diff --git a/libtransmission/fdlimit.c b/libtransmission/fdlimit.c index c56d75a7e..f3f3a3fa5 100644 --- a/libtransmission/fdlimit.c +++ b/libtransmission/fdlimit.c @@ -95,33 +95,65 @@ static struct tr_fd_s * gFd = NULL; **** ***/ +#ifndef O_LARGEFILE +#define O_LARGEFILE 0 +#endif + static int -preallocateFile( int fd UNUSED, uint64_t length UNUSED ) +preallocateFile( const char * filename, uint64_t length ) { -#ifdef HAVE_FALLOCATE + int success = 0; - return fallocate( fd, FALLOC_FL_KEEP_SIZE, 0, length ); +#ifdef WIN32 -#elif defined(HAVE_POSIX_FALLOCATE) - - return posix_fallocate( fd, 0, length ); - -#elif defined(SYS_DARWIN) - - fstore_t fst; - fst.fst_flags = F_ALLOCATECONTIG; - fst.fst_posmode = F_PEOFPOSMODE; - fst.fst_offset = 0; - fst.fst_length = length; - fst.fst_bytesalloc = 0; - return fcntl( fd, F_PREALLOCATE, &fst ); + HANDLE hFile = CreateFile( filename, GENERIC_WRITE, 0, 0, CREATE_NEW, 0, 0 ); + if( hFile != INVALID_HANDLE_VALUE ) + { + LARGE_INTEGER li; + li.QuadPart = desiredFileSize; + success = SetFilePointerEx( hFile, desiredFileSize, NULL, FILE_BEGIN ) + && SetEndOfFile( hFile ); + CloseHandle( hFile ); + } #else - #warning no known method to preallocate files on this platform - return -1; + int flags = O_RDWR | O_CREAT | O_LARGEFILE; + int fd = open( filename, flags, 0666 ); + if( fd >= 0 ) + { + +# ifdef HAVE_FALLOCATE + + success = !fallocate( fd, FALLOC_FL_KEEP_SIZE, 0, length ); + +# elif defined(HAVE_POSIX_FALLOCATE) + + success = !posix_fallocate( fd, 0, length ); + +# elif defined(SYS_DARWIN) + + fstore_t fst; + fst.fst_flags = F_ALLOCATECONTIG; + fst.fst_posmode = F_PEOFPOSMODE; + fst.fst_offset = 0; + fst.fst_length = length; + fst.fst_bytesalloc = 0; + success = !fcntl( fd, F_PREALLOCATE, &fst ); + +# else + + #warning no known method to preallocate files on this platform + success = 0; + +# endif + + close( fd ); + } #endif + + return success; } /** @@ -161,6 +193,10 @@ TrOpenFile( int i, } alreadyExisted = !stat( filename, &sb ) && S_ISREG( sb.st_mode ); + + if( doWrite && !alreadyExisted && doPreallocate ) + if( preallocateFile( filename, desiredFileSize ) ) + tr_inf( _( "Preallocated file \"%s\"" ), filename ); /* open the file */ flags = doWrite ? ( O_RDWR | O_CREAT ) : O_RDONLY; @@ -180,10 +216,6 @@ TrOpenFile( int i, return err; } - if( ( file->fd >= 0 ) && !alreadyExisted && doPreallocate ) - if( !preallocateFile( file->fd, desiredFileSize ) ) - tr_inf( _( "Preallocated file \"%s\"" ), filename ); - tr_free( filename ); return 0; }