Port: Add posix_fallocate compat for mingw
authorMichael Jeanson <mjeanson@efficios.com>
Tue, 13 Sep 2016 21:34:57 +0000 (21:34 +0000)
committerJérémie Galarneau <jeremie.galarneau@efficios.com>
Fri, 9 Jun 2017 20:58:15 +0000 (16:58 -0400)
Signed-off-by: Michael Jeanson <mjeanson@efficios.com>
Signed-off-by: Jérémie Galarneau <jeremie.galarneau@efficios.com>
include/babeltrace/compat/fcntl-internal.h

index 47e5effc047619944599755eecabc22973527698..33c2a09f710f5cd96bfc0be50ed50e84473f0fce 100644 (file)
@@ -37,7 +37,101 @@ int bt_posix_fallocate(int fd, off_t offset, off_t len)
        return posix_fallocate(fd, offset, len);
 }
 
-#else /* #ifdef BABELTRACE_HAVE_POSIX_FALLOCATE */
+#elif defined(__MINGW32__) /* #ifdef BABELTRACE_HAVE_POSIX_FALLOCATE */
+
+#include <assert.h>
+#include <windows.h>
+#include <fcntl.h>
+
+static inline
+int bt_posix_fallocate(int fd, off_t offset, off_t len)
+{
+       HANDLE handle;
+       LARGE_INTEGER pos, file_pos, orig_end_offset, range_end;
+       int ret = 0;
+       char zero = 0;
+       DWORD byteswritten;
+
+       if (offset < 0 || len <= 0) {
+               ret = EINVAL;
+               goto end;
+       }
+
+       range_end.QuadPart = (__int64) offset + (__int64) len;
+
+       /* Get a handle from the fd */
+       handle = (HANDLE) _get_osfhandle(fd);
+       if (handle == INVALID_HANDLE_VALUE) {
+               ret = EBADF;
+               goto end;
+       }
+
+       /* Get the file original end offset */
+       ret = GetFileSizeEx(handle, &orig_end_offset);
+       if (ret == 0) {
+               ret = EBADF;
+               goto end;
+       }
+
+       /* Make sure we don't truncate the file */
+       if (orig_end_offset.QuadPart >= range_end.QuadPart) {
+               ret = 0;
+               goto end;
+       }
+
+       /* Get the current file pointer position */
+       pos.QuadPart = 0;
+       ret = SetFilePointerEx(handle, pos, &file_pos, FILE_CURRENT);
+       if (ret == 0) {
+               ret = EBADF;
+               goto end;
+       }
+
+       /* Move the file pointer to the new end offset */
+       ret = SetFilePointerEx(handle, range_end, NULL, FILE_BEGIN);
+       if (ret == 0) {
+               ret = EBADF;
+               goto end;
+       }
+
+       /* Sets the physical file size to the current position */
+       ret = SetEndOfFile(handle);
+       if (ret == 0) {
+               ret = EINVAL;
+               goto restore;
+       }
+
+       /*
+        * Move the file pointer back 1 byte, and write a single 0 at the
+        * last byte of the new end offset, the operating system will zero
+        * fill the file.
+        */
+       pos.QuadPart = -1;
+       ret = SetFilePointerEx(handle, pos, NULL, FILE_END);
+       if (ret == 0) {
+               ret = EBADF;
+               goto end;
+       }
+
+       ret = WriteFile(handle, &zero, 1, &byteswritten, NULL);
+       if (ret == 0 || byteswritten != 1) {
+               ret = ENOSPC;
+       } else {
+               ret = 0;
+       }
+
+restore:
+       /* Restore the original file pointer position */
+       if (!SetFilePointerEx(handle, file_pos, NULL, FILE_BEGIN)) {
+               /* We moved the file pointer but failed to restore it. */
+               assert(0);
+       }
+
+end:
+       return ret;
+}
+
+#else
 
 #include <sys/types.h>
 #include <unistd.h>
This page took 0.025606 seconds and 4 git commands to generate.