From: Michael Jeanson Date: Tue, 13 Sep 2016 21:34:57 +0000 (+0000) Subject: Port: Add posix_fallocate compat for mingw X-Git-Url: http://drtracing.org/?a=commitdiff_plain;h=26fdbcef74212634bb50e8e8c6b58ce0752dfb8f;p=deliverable%2Fbabeltrace.git Port: Add posix_fallocate compat for mingw Signed-off-by: Michael Jeanson Signed-off-by: Jérémie Galarneau --- diff --git a/include/babeltrace/compat/fcntl-internal.h b/include/babeltrace/compat/fcntl-internal.h index 47e5effc0..33c2a09f7 100644 --- a/include/babeltrace/compat/fcntl-internal.h +++ b/include/babeltrace/compat/fcntl-internal.h @@ -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 +#include +#include + +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 #include