diff options
Diffstat (limited to 'src')
| -rw-r--r-- | src/posix.c | 23 |
1 files changed, 22 insertions, 1 deletions
diff --git a/src/posix.c b/src/posix.c index 242fda8c6..b5dfac56d 100644 --- a/src/posix.c +++ b/src/posix.c @@ -159,6 +159,20 @@ int p_fallocate(int fd, off_t offset, off_t len) { #ifdef __APPLE__ fstore_t prealloc; + struct stat st; + size_t newsize; + int error; + + if ((error = p_fstat(fd, &st)) < 0) + return error; + + if (git__add_sizet_overflow(&newsize, offset, len)) { + errno = EINVAL; + return -1; + } + + if (newsize < (unsigned long long)st.st_size) + return 0; memset(&prealloc, 0, sizeof(prealloc)); prealloc.fst_flags = F_ALLOCATEALL; @@ -166,7 +180,14 @@ int p_fallocate(int fd, off_t offset, off_t len) prealloc.fst_offset = offset; prealloc.fst_length = len; - return fcntl(fd, F_PREALLOCATE, &prealloc); + /* + * fcntl will often error when the file already exists; ignore + * this error since ftruncate will also resize the file (although + * likely slower). + */ + fcntl(fd, F_PREALLOCATE, &prealloc); + + return ftruncate(fd, (offset + len)); #else return posix_fallocate(fd, offset, len); #endif |
