X-Git-Url: http://git.efficios.com/?a=blobdiff_plain;f=include%2Fbabeltrace%2Fcompat%2Ffcntl-internal.h;fp=include%2Fbabeltrace%2Fcompat%2Ffcntl-internal.h;h=33c2a09f710f5cd96bfc0be50ed50e84473f0fce;hb=26fdbcef74212634bb50e8e8c6b58ce0752dfb8f;hp=47e5effc047619944599755eecabc22973527698;hpb=3d2f08e7a34d78b0fff4da7a374a81c7d4141ac6;p=babeltrace.git diff --git a/include/babeltrace/compat/fcntl-internal.h b/include/babeltrace/compat/fcntl-internal.h index 47e5effc..33c2a09f 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