Ticket #1486: inout.c-win32-large-file-support.patch

File inout.c-win32-large-file-support.patch, 2.9 KB (added by lubomir.marinov, 12 years ago)

Unbreaks large file support on Windows in inout.c

  • inout.c

     
    8585        err = errno;
    8686    else if( ( fd = tr_fdFileCheckout ( tor->downloadDir, file->name, ioMode == TR_IO_WRITE, !file->dnd, file->length ) ) < 0 )
    8787        err = errno;
     88#ifdef WIN32
     89    /*
     90     * As lseek is redefined above to _lseeki64, casting to off_t (1) cannot be
     91     * performed on MinGW because large file support is not supported and (2) is
     92     * not necessary on MSVC because the function accepts __int64 anyway.
     93     */
     94    else if( lseek( fd, fileOffset, SEEK_SET ) == ( -1 ) )
     95#else
    8896    else if( lseek( fd, (off_t)fileOffset, SEEK_SET ) == ( (off_t)-1 ) )
     97#endif
    8998        err = errno;
    9099    else if( func( fd, buf, buflen ) != buflen )
    91100        err = errno;
     
    137146}
    138147
    139148#ifdef WIN32
     149static int
     150convertLastErrorCodeToErrno( DWORD lastErrorCode )
     151{
     152    switch( lastErrorCode )
     153    {
     154    /* Mappings taken from PostgreSQL. */
     155    case ERROR_ACCESS_DENIED:     return EACCES;
     156    case ERROR_DISK_FULL:         return ENOSPC;
     157    case ERROR_INVALID_HANDLE:    return EBADF ;
     158    case ERROR_INVALID_PARAMETER: return EINVAL;
     159    case ERROR_NEGATIVE_SEEK:     return EINVAL;
     160    case ERROR_SEEK_ON_DEVICE:    return EACCES;
     161    default:                      return EINVAL;
     162    }
     163}
     164
    140165/* return 0 on success, or an errno on failure */
    141166static int
    142167ensureMinimumFileSize( const tr_torrent * tor,
     
    156181
    157182    if( fd < 0 ) /* bad fd */
    158183        err = errno;
    159     else if( fstat ( fd, &sb ) ) /* how big is the file? */
    160         err = errno;
    161     else if( sb.st_size >= (off_t)minBytes ) /* already big enough */
    162         err = 0;
    163     else if( !ftruncate( fd, minBytes ) )  /* grow it */
    164         err = 0;
    165     else /* couldn't grow it */
    166         err = errno;
     184    else
     185    {
     186        HANDLE fhandle = (HANDLE) _get_osfhandle( fd );
    167187
     188        if( INVALID_HANDLE_VALUE == fhandle )
     189            err = errno;
     190        else
     191        {
     192            LARGE_INTEGER fileSize;
     193
     194            if( GetFileSizeEx( fhandle, &fileSize ) ) /* how big is the file? */
     195            {
     196                if( fileSize.QuadPart >= minBytes ) /* already big enough */
     197                    err = 0;
     198                else /* grow it */
     199                {
     200                    fileSize.QuadPart = minBytes;
     201                    if( SetFilePointerEx( fhandle, fileSize, NULL, FILE_BEGIN )
     202                            && SetEndOfFile( fhandle ) )
     203                        err = 0;
     204                    else /* couldn't grow it */
     205                        err = convertLastErrorCodeToErrno( GetLastError() );
     206                }
     207            }
     208            else
     209                err = convertLastErrorCodeToErrno( GetLastError() );
     210        }
     211    }
     212
    168213    if( fd >= 0 )
    169214        tr_fdFileReturn( fd );
    170215
    171216    return err;
    172217}
    173 
    174218#endif
    175219
    176220/* returns 0 on success, or an errno on failure */