Ignore:
Timestamp:
Jan 14, 2007, 12:00:21 PM (15 years ago)
Author:
titer
Message:

Merge io branch into trunk

File:
1 edited

Legend:

Unmodified
Added
Removed
  • trunk/libtransmission/inout.c

    r1074 r1356  
    4747 * Local prototypes
    4848 **********************************************************************/
    49 static int  createFiles( tr_io_t * );
    5049static int  checkFiles( tr_io_t * );
    5150static void closeFiles( tr_io_t * );
     
    9695    io->tor = tor;
    9796
    98     if( createFiles( io ) || checkFiles( io ) )
     97    if( checkFiles( io ) )
    9998    {
    10099        free( io );
     
    107106/***********************************************************************
    108107 * tr_ioRead
    109  ***********************************************************************
    110  *
    111108 **********************************************************************/
    112109int tr_ioRead( tr_io_t * io, int index, int begin, int length,
    113110               uint8_t * buf )
    114111{
     112    tr_info_t * inf = &io->tor->info;
    115113    uint64_t    offset;
    116     tr_info_t * inf = &io->tor->info;
    117114
    118115    offset = (uint64_t) io->pieceSlot[index] *
     
    124121/***********************************************************************
    125122 * tr_ioWrite
    126  ***********************************************************************
    127  *
    128123 **********************************************************************/
    129124int tr_ioWrite( tr_io_t * io, int index, int begin, int length,
    130125                uint8_t * buf )
    131126{
    132     tr_torrent_t * tor = io->tor;
    133127    tr_info_t    * inf = &io->tor->info;
    134128    uint64_t       offset;
    135     int            i, hashFailed;
    136     uint8_t        hash[SHA_DIGEST_LENGTH];
    137     uint8_t      * pieceBuf;
    138     int            pieceSize;
    139     int            startBlock, endBlock;
    140129
    141130    if( io->pieceSlot[index] < 0 )
     
    149138        (uint64_t) inf->pieceSize + (uint64_t) begin;
    150139
    151     if( writeBytes( io, offset, length, buf ) )
    152     {
    153         return 1;
    154     }
    155 
    156     startBlock = tr_pieceStartBlock( index );
    157     endBlock   = startBlock + tr_pieceCountBlocks( index );
    158     for( i = startBlock; i < endBlock; i++ )
    159     {
    160         if( !tr_cpBlockIsComplete( tor->completion, i ) )
    161         {
    162             /* The piece is not complete */
    163             return 0;
    164         }
    165     }
    166 
    167     /* The piece is complete, check the hash */
     140    return writeBytes( io, offset, length, buf );
     141}
     142
     143/***********************************************************************
     144 * tr_ioHash
     145 **********************************************************************/
     146int tr_ioHash( tr_io_t * io, int index )
     147{
     148    tr_torrent_t * tor = io->tor;
     149    tr_info_t    * inf = &io->tor->info;
     150    int            pieceSize;
     151    uint8_t      * pieceBuf;
     152    uint8_t        hash[SHA_DIGEST_LENGTH];
     153    int            hashFailed;
     154    int            ret;
     155    int            i;
     156
     157    if( !tr_cpPieceIsComplete( tor->completion, index ) )
     158    {
     159        return TR_ERROR_ASSERT;
     160    }
     161
    168162    pieceSize = tr_pieceSize( index );
    169163    pieceBuf  = malloc( pieceSize );
    170     readBytes( io, (uint64_t) io->pieceSlot[index] *
    171                (uint64_t) inf->pieceSize, pieceSize, pieceBuf );
     164    if( ( ret = readBytes( io, (uint64_t) io->pieceSlot[index] *
     165                    (uint64_t) inf->pieceSize, pieceSize, pieceBuf ) ) )
     166    {
     167        free( pieceBuf );
     168        return ret;
     169    }
    172170    SHA1( pieceBuf, pieceSize, hash );
    173171    free( pieceBuf );
     
    178176        tr_inf( "Piece %d (slot %d): hash FAILED", index,
    179177                io->pieceSlot[index] );
    180 
    181         /* We will need to reload the whole piece */
    182         for( i = startBlock; i < endBlock; i++ )
    183         {
    184             tr_cpBlockRem( tor->completion, i );
    185         }
     178        tr_cpPieceRem( tor->completion, index );
    186179    }
    187180    else
     
    201194}
    202195
     196/***********************************************************************
     197 * tr_ioSync
     198 **********************************************************************/
     199void tr_ioSync( tr_io_t * io )
     200{
     201    closeFiles( io );
     202    fastResumeSave( io );
     203}
     204
     205/***********************************************************************
     206 * tr_ioClose
     207 **********************************************************************/
    203208void tr_ioClose( tr_io_t * io )
    204209{
    205     closeFiles( io );
    206 
    207     fastResumeSave( io );
     210    tr_ioSync( io );
    208211
    209212    free( io->pieceSlot );
    210213    free( io->slotPiece );
    211214    free( io );
    212 }
    213 
    214 void tr_ioSaveResume( tr_io_t * io )
    215 {
    216     fastResumeSave( io );
    217 }
    218 
    219 /***********************************************************************
    220  * createFiles
    221  ***********************************************************************
    222  * Make sure the existing folders/files have correct types and
    223  * permissions, and create missing folders and files
    224  **********************************************************************/
    225 static int createFiles( tr_io_t * io )
    226 {
    227     tr_torrent_t * tor = io->tor;
    228     tr_info_t    * inf = &tor->info;
    229 
    230     int           i;
    231     char        * path, * p;
    232     struct stat   sb;
    233     int           file;
    234 
    235     tr_dbg( "Creating files..." );
    236 
    237     for( i = 0; i < inf->fileCount; i++ )
    238     {
    239         asprintf( &path, "%s/%s", tor->destination, inf->files[i].name );
    240 
    241         /* Create folders */
    242         if( NULL != ( p = strrchr( path, '/' ) ) )
    243         {
    244             *p = '\0';
    245             if( tr_mkdir( path ) )
    246             {
    247                 free( path );
    248                 return 1;
    249             }
    250             *p = '/';
    251         }
    252 
    253         /* Empty folders use a dummy "" file, skip those */
    254         if( p == &path[strlen( path ) - 1] )
    255         {
    256             free( path );
    257             continue;
    258         }
    259 
    260         if( stat( path, &sb ) )
    261         {
    262             /* File doesn't exist yet */
    263             if( ( file = open( path, O_WRONLY|O_CREAT|O_TRUNC, 0666 ) ) < 0 )
    264             {
    265                 tr_err( "Could not create `%s' (%s)", path,
    266                         strerror( errno ) );
    267                 free( path );
    268                 return 1;
    269             }
    270             close( file );
    271         }
    272         else if( ( sb.st_mode & S_IFMT ) != S_IFREG )
    273         {
    274             /* Node exists but isn't a file */
    275             /* XXX this should be reported to the frontend somehow */
    276             tr_err( "Remove %s, it's in the way.", path );
    277             free( path );
    278             return 1;
    279         }
    280 
    281         free( path );
    282     }
    283 
    284     return 0;
    285215}
    286216
     
    370300
    371301    int i;
    372     char * path;
    373302
    374303    for( i = 0; i < inf->fileCount; i++ )
    375304    {
    376         asprintf( &path, "%s/%s", tor->destination, inf->files[i].name );
    377         tr_fdFileClose( tor->fdlimit, path );
    378         free( path );
     305        tr_fdFileClose( tor->fdlimit, tor->destination,
     306                        inf->files[i].name );
    379307    }
    380308}
     
    396324    int    i;
    397325    size_t cur;
    398     char * path;
    399326    int    file;
    400327    iofunc readOrWrite = isWrite ? (iofunc) write : (iofunc) read;
     328    int    ret = 0;
    401329
    402330    /* Release the torrent lock so the UI can still update itself if
     
    408336    {
    409337        tr_err( "readOrWriteBytes: trying to write more than a piece" );
    410         goto fail;
     338        ret = TR_ERROR_ASSERT;
     339        goto cleanup;
    411340    }
    412341
     
    426355        tr_err( "readOrWriteBytes: offset out of range (%"PRIu64", %d, %d)",
    427356                offset, size, isWrite );
    428         goto fail;
     357        ret = TR_ERROR_ASSERT;
     358        goto cleanup;
    429359    }
    430360
     
    443373        if( cur > 0 )
    444374        {
    445             /* Now let's get a stream on the file... */
    446             asprintf( &path, "%s/%s", tor->destination, inf->files[i].name );
    447             file = tr_fdFileOpen( tor->fdlimit, path );
     375            /* Now let's get a descriptor on the file... */
     376            file = tr_fdFileOpen( tor->fdlimit, tor->destination,
     377                                  inf->files[i].name, isWrite );
    448378            if( file < 0 )
    449379            {
    450                 tr_err( "readOrWriteBytes: could not open file '%s'", path );
    451                 free( path );
    452                 goto fail;
    453             }
    454             free( path );
     380                ret = file;
     381                goto cleanup;
     382            }
    455383
    456384            /* seek to the right offset... */
    457385            if( lseek( file, offset, SEEK_SET ) < 0 )
    458386            {
    459                 goto fail;
     387                tr_fdFileRelease( tor->fdlimit, file );
     388                ret = TR_ERROR_IO_OTHER;
     389                goto cleanup;
    460390            }
    461391
     
    463393            if( readOrWrite( file, buf, cur ) != cur )
    464394            {
    465                 goto fail;
    466             }
    467 
    468             /* and close the stream. */
     395                tr_fdFileRelease( tor->fdlimit, file );
     396                ret = TR_ERROR_IO_OTHER;
     397                goto cleanup;
     398            }
     399
     400            /* and release the descriptor. */
    469401            tr_fdFileRelease( tor->fdlimit, file );
    470402        }
     
    477409    }
    478410
     411cleanup:
    479412    tr_lockLock( &tor->lock );
    480     return 0;
    481 
    482 fail:
    483     tr_lockLock( &tor->lock );
    484     return 1;
     413    return ret;
    485414}
    486415
Note: See TracChangeset for help on using the changeset viewer.