Changeset 4734


Ignore:
Timestamp:
Jan 18, 2008, 7:13:32 PM (13 years ago)
Author:
charles
Message:

if the torrent's download path doesn't exist, don't create it -- it's might be a removeable disk that got unplugged.

Location:
trunk/libtransmission
Files:
13 edited

Legend:

Unmodified
Added
Removed
  • trunk/libtransmission/fdlimit.c

    r4598 r4734  
    128128***/
    129129
    130 static int
    131 TrOpenFile( int i, const char * filename, int write )
     130static tr_errno
     131TrOpenFile( int           i,
     132            const char  * folder,
     133            const char  * torrentFile,
     134            int           write )
    132135{
    133136    struct tr_openfile * file = &gFd->open[i];
    134137    int flags;
     138    char filename[MAX_PATH_LENGTH];
     139    struct stat sb;
     140
     141    /* confirm the parent folder exists */
     142    if( stat( folder, &sb ) || !S_ISDIR( sb.st_mode ) )
     143        return TR_ERROR_IO_PARENT;
    135144
    136145    /* create subfolders, if any */
     146    tr_buildPath ( filename, sizeof(filename), folder, torrentFile, NULL );
    137147    if( write ) {
    138148        char * tmp = tr_strdup( filename );
    139         const int val = tr_mkdirp( dirname(tmp), 0777 );
     149        const int err = tr_mkdirp( dirname(tmp), 0777 ) ? errno : 0;
    140150        tr_free( tmp );
    141         if( val )
    142             return tr_ioErrorFromErrno( );
     151        if( err )
     152            return tr_ioErrorFromErrno( err );
    143153    }
    144154
     
    151161    flags |= O_BINARY;
    152162#endif
    153     errno = 0;
    154163    file->fd = open( filename, flags, 0666 );
    155     if( file->fd < 0 ) {
    156         if( errno ) {
    157             tr_err( "Couldn't open '%s': %s", filename, strerror(errno) );
    158             return tr_ioErrorFromErrno();
    159         } else {
    160             tr_err( "Couldn't open '%s'", filename );
    161             return TR_ERROR_IO_OTHER;
    162         }
    163     }
    164 
    165     return TR_OK;
     164    if( file->fd == -1 ) {
     165        const int err = errno;
     166        tr_err( "Couldn't open '%s': %s", filename, strerror(err) );
     167        return tr_ioErrorFromErrno( err );
     168    }
     169
     170    return 0;
    166171}
    167172
     
    193198
    194199int
    195 tr_fdFileCheckout( const char * filename, int write )
     200tr_fdFileCheckout( const char * folder,
     201                   const char * torrentFile,
     202                   int          write )
    196203{
    197204    int i, winner = -1;
    198205    struct tr_openfile * o;
    199 
    200     assert( filename && *filename );
     206    char filename[MAX_PATH_LENGTH];
     207
     208    assert( folder && *folder );
     209    assert( torrentFile && *torrentFile );
    201210    assert( write==0 || write==1 );
    202211
     212    tr_buildPath ( filename, sizeof(filename), folder, torrentFile, NULL );
    203213    dbgmsg( "looking for file '%s', writable %c", filename, write?'y':'n' );
    204214
     
    275285    if( !fileIsOpen( o ) )
    276286    {
    277         const int ret = TrOpenFile( winner, filename, write );
    278         if( ret ) {
     287        const tr_errno err = TrOpenFile( winner, folder, torrentFile, write );
     288        if( err ) {
    279289            tr_lockUnlock( gFd->lock );
    280             return ret;
     290            return err;
    281291        }
    282292
  • trunk/libtransmission/fdlimit.h

    r4404 r4734  
    3737 * Returns an fd to the specified filename.
    3838 *
    39  * A small repository of open files is kept to avoid the overhead of continually
    40  * opening and closing the same files when writing piece data during download.
    41  * It's also used to ensure that only one client uses the file at a time.
    42  * Clients must check out a file to use it, then return it, like a library, when done.
     39 * A small pool of open files is kept to avoid the overhead of
     40 * continually opening and closing the same files when downloading
     41 * piece data.    It's also used to ensure only one caller can
     42 * write to the file at a time.  Callers check out a file, use it,
     43 * and then check it back in via tr_fdFileReturn() when done.
    4344 *
    44  * if write is nonzero and dirname(filename) doesn't exist, dirname is created.
    45  * if write is nonzero and filename doesn't exist, filename is created.
    46  * returns the fd if successful; otherwise, one of TR_ERROR_IO_*
     45 * - if `folder' doesn't exist, TR_ERROR_IO_PARENT is returned.
     46 * - if doWrite is true, subfolders in torrentFile are created if necessary.
     47 * - if doWrite is true, the target file is created if necessary.
     48 *
     49 * on success, a file descriptor >= 0 is returned.
     50 * on failure, a negative number corresponding to tr_errno is returned.
    4751 *
    4852 * @see tr_fdFileReturn
    4953 * @see tr_fdFileClose
     54 * @see tr_errno
    5055 */
    51 int tr_fdFileCheckout( const char * filename, int write );
     56int tr_fdFileCheckout( const char * folder,
     57                       const char * torrentFile,
     58                       int          doWrite );
    5259
    5360/**
  • trunk/libtransmission/inout.c

    r4561 r4734  
    4242enum { TR_IO_READ, TR_IO_WRITE };
    4343
    44 static int
     44static tr_errno
    4545readOrWriteBytes( const tr_torrent  * tor,
    4646                  int                 ioMode,
     
    5757    struct stat sb;
    5858    int fd = -1;
    59     int ret;
     59    int err;
    6060    int fileExists;
    6161
     
    6969    if( !file->length )
    7070        return 0;
    71     else if ((ioMode==TR_IO_READ) && !fileExists ) /* does file exist? */
    72         ret = tr_ioErrorFromErrno ();
    73     else if ((fd = tr_fdFileCheckout ( path, ioMode==TR_IO_WRITE )) < 0)
    74         ret = fd;
     71
     72    if ((ioMode==TR_IO_READ) && !fileExists ) /* does file exist? */
     73        err = tr_ioErrorFromErrno( errno );
     74    else if ((fd = tr_fdFileCheckout ( tor->destination, file->name, ioMode==TR_IO_WRITE )) < 0)
     75        err = fd;
    7576    else if( lseek( fd, (off_t)fileOffset, SEEK_SET ) == ((off_t)-1) )
    76         ret = TR_ERROR_IO_OTHER;
     77        err = tr_ioErrorFromErrno( errno );
    7778    else if( func( fd, buf, buflen ) != buflen )
    78         ret = tr_ioErrorFromErrno( );
     79        err = tr_ioErrorFromErrno( errno );
    7980    else
    80         ret = TR_OK;
    81 
    82     if((ret==TR_OK) && (ioMode==TR_IO_WRITE) && !fileExists )
     81        err = 0;
     82
     83    if( !err && !fileExists && (ioMode==TR_IO_WRITE) )
    8384        tr_statsFileCreated( tor->handle );
    8485 
     
    8687        tr_fdFileReturn( fd );
    8788
    88     return ret;
    89 }
    90 
    91 static void
     89    return err;
     90}
     91
     92static tr_errno
    9293findFileLocation( const tr_torrent * tor,
    9394                  int                pieceIndex,
     
    101102    uint64_t piecePos = ((uint64_t)pieceIndex * info->pieceSize) + pieceOffset;
    102103
    103     assert( 0<=pieceIndex && pieceIndex < info->pieceCount );
    104     assert( 0<=tor->info.pieceSize );
    105     assert( pieceOffset < tr_torPieceCountBytes( tor, pieceIndex ) );
    106     assert( piecePos < info->totalSize );
     104    if( pieceIndex < 0 || pieceIndex >= info->pieceCount )
     105        return TR_ERROR_ASSERT;
     106    if( pieceOffset >= tr_torPieceCountBytes( tor, pieceIndex ) )
     107        return TR_ERROR_ASSERT;
     108    if( piecePos >= info->totalSize )
     109        return TR_ERROR_ASSERT;
    107110
    108111    for( i=0; info->files[i].length<=piecePos; ++i )
     
    114117    assert( 0<=*fileIndex && *fileIndex<info->fileCount );
    115118    assert( *fileOffset < info->files[i].length );
     119    return 0;
    116120}
    117121
    118122#ifdef WIN32
    119 static int
     123static tr_errno
    120124ensureMinimumFileSize( const tr_torrent  * tor,
    121125                       int                 fileIndex,
     
    123127{
    124128    int fd;
    125     int ret;
     129    tr_errno err;
    126130    struct stat sb;
    127131    const tr_file * file = &tor->info.files[fileIndex];
    128     char path[MAX_PATH_LENGTH];
    129132
    130133    assert( 0<=fileIndex && fileIndex<tor->info.fileCount );
    131134    assert( minBytes <= file->length );
    132135
    133     tr_buildPath( path, sizeof(path), tor->destination, file->name, NULL );
    134 
    135     fd = tr_fdFileCheckout( path, TRUE );
    136     if( fd < 0 ) /* bad fd */
    137         ret = fd;
     136    if(( fd = tr_fdFileCheckout( tor->destination, file->name, TRUE )) < 0 )
     137        err = fd;
    138138    else if (fstat (fd, &sb) ) /* how big is the file? */
    139         ret = tr_ioErrorFromErrno ();
     139        err = tr_ioErrorFromErrno( errno );
    140140    else if (sb.st_size >= (off_t)minBytes) /* already big enough */
    141         ret = TR_OK;
    142     else if (!ftruncate( fd, minBytes )) /* grow it */
    143         ret = TR_OK;
     141        err = 0;
     142    else if ( !ftruncate( fd, minBytes ) ) /* grow it */
     143        err = 0;
    144144    else /* couldn't grow it */
    145         ret = tr_ioErrorFromErrno ();
     145        err = tr_ioErrorFromErrno( errno );
    146146
    147147    if( fd >= 0 )
    148148        tr_fdFileReturn( fd );
    149149
    150     return ret;
     150    return err;
    151151}
    152152#endif
    153153
    154 static int
     154static tr_errno
    155155readOrWritePiece( tr_torrent  * tor,
    156156                  int           ioMode,
     
    160160                  size_t        buflen )
    161161{
    162     int ret = 0;
     162    tr_errno err = 0;
    163163    int fileIndex;
    164164    uint64_t fileOffset;
    165165    const tr_info * info = &tor->info;
    166166
    167     assert( 0<=pieceIndex && pieceIndex<tor->info.pieceCount );
    168     assert( buflen <= (size_t) tr_torPieceCountBytes( tor, pieceIndex ) );
    169 
    170     findFileLocation ( tor, pieceIndex, pieceOffset, &fileIndex, &fileOffset );
    171 
    172     while( buflen && !ret )
     167    if( pieceIndex < 0 || pieceIndex >= tor->info.pieceCount )
     168        err = TR_ERROR_ASSERT;
     169    else if( buflen > ( size_t ) tr_torPieceCountBytes( tor, pieceIndex ) )
     170        err = TR_ERROR_ASSERT;
     171
     172    if( !err )
     173        err = findFileLocation ( tor, pieceIndex, pieceOffset, &fileIndex, &fileOffset );
     174
     175    while( buflen && !err )
    173176    {
    174177        const tr_file * file = &info->files[fileIndex];
     
    177180#ifdef WIN32
    178181        if( ioMode == TR_IO_WRITE )
    179             ret = ensureMinimumFileSize( tor, fileIndex,
     182            err = ensureMinimumFileSize( tor, fileIndex,
    180183                                         fileOffset + bytesThisPass );
    181         if( !ret )
     184        if( !err )
    182185#endif
    183             ret = readOrWriteBytes( tor, ioMode,
     186            err = readOrWriteBytes( tor, ioMode,
    184187                                    fileIndex, fileOffset, buf, bytesThisPass );
    185188        buf += bytesThisPass;
     
    189192    }
    190193
    191     return ret;
    192 }
    193 
    194 int
     194    return err;
     195}
     196
     197tr_errno
    195198tr_ioRead( tr_torrent  * tor,
    196199           int           pieceIndex,
     
    202205}
    203206
    204 int
     207tr_errno
    205208tr_ioWrite( tr_torrent     * tor,
    206209            int              pieceIndex,
  • trunk/libtransmission/inout.h

    r4404 r4734  
    2828struct tr_torrent;
    2929
    30 typedef struct tr_io tr_io;
     30/**
     31 * Reads the block specified by the piece index, offset, and length.
     32 * @return 0 on success, TR_ERROR_ASSERT if the arguments are incorrect,
     33 * or TR_ERROR_IO_* otherwise.
     34 */
     35int tr_ioRead  ( struct tr_torrent*, int index, int begin, int len, uint8_t * );
    3136
    32 /***********************************************************************
    33  * tr_ioRead, tr_ioWrite
    34  ***********************************************************************
    35  * Reads or writes the block specified by the piece index, the offset in
    36  * that piece and the size of the block. Returns 0 if successful,
    37  * TR_ERROR_ASSERT if the parameters are incorrect, one of the
    38  * TR_ERROR_IO_* otherwise.
    39  **********************************************************************/
    40 int tr_ioRead  ( struct tr_torrent*, int index, int begin, int len, uint8_t * );
    41 int tr_ioWrite ( struct tr_torrent *, int index, int begin, int len, const uint8_t * );
     37/**
     38 * Writes the block specified by the piece index, offset, and length.
     39 * @return 0 on success, TR_ERROR_ASSERT if the arguments are incorrect,
     40 * or TR_ERROR_IO_* otherwise.
     41 */
     42tr_errno tr_ioWrite ( struct tr_torrent *, int index, int begin, int len, const uint8_t * );
    4243
    4344/* hashes the specified piece and updates the completion accordingly. */
  • trunk/libtransmission/ipcparse.c

    r4537 r4734  
    713713    benc_val_t  * dict, * item;
    714714    int           ii, used;
    715     unsigned int  error;
     715    tr_errno      error;
    716716
    717717    /* always send torrent id */
     
    764764                    tr_bencInitStr( item, "", -1, 1 );
    765765                }
    766                 else if( TR_ERROR_ISSET( TR_ERROR_ASSERT, error ) )
     766                else if( error == TR_ERROR_ASSERT )
    767767                {
    768768                    tr_bencInitStr( item, "assert", -1, 1 );
    769769                }
    770                 else if( TR_ERROR_ISSET( TR_ERROR_IO_PERMISSIONS, error ) )
     770                else if( error == TR_ERROR_IO_PERMISSIONS )
    771771                {
    772772                    tr_bencInitStr( item, "io-permissions", -1, 1 );
    773773                }
    774                 else if( TR_ERROR_ISSET( TR_ERROR_IO_SPACE, error ) )
     774                else if( error == TR_ERROR_IO_SPACE )
    775775                {
    776776                    tr_bencInitStr( item, "io-space", -1, 1 );
    777777                }
    778                 else if( TR_ERROR_ISSET( TR_ERROR_IO_FILE_TOO_BIG, error ) )
     778                else if( error == TR_ERROR_IO_FILE_TOO_BIG )
    779779                {
    780780                    tr_bencInitStr( item, "io-file-too-big", -1, 1 );
    781781                }
    782                 else if( TR_ERROR_ISSET( TR_ERROR_IO_OPEN_FILES, error ) )
     782                else if( error == TR_ERROR_IO_OPEN_FILES )
    783783                {
    784784                    tr_bencInitStr( item, "io-open-files", -1, 1 );
    785785                }
    786                 else if( TR_ERROR_ISSET( TR_ERROR_IO_MASK, error ) )
     786                else if( TR_ERROR_IS_IO( error ) )
    787787                {
    788788                    tr_bencInitStr( item, "io-other", -1, 1 );
    789789                }
    790                 else if( TR_ERROR_ISSET( TR_ERROR_TC_ERROR, error ) )
     790                else if( error == TR_ERROR_TC_ERROR )
    791791                {
    792792                    tr_bencInitStr( item, "tracker-error", -1, 1 );
    793793                }
    794                 else if( TR_ERROR_ISSET( TR_ERROR_TC_WARNING, error ) )
     794                else if( error == TR_ERROR_TC_WARNING )
    795795                {
    796796                    tr_bencInitStr( item, "tracker-warning", -1, 1 );
     797                }
     798                else if( TR_ERROR_IS_TC( error ) )
     799                {
     800                    tr_bencInitStr( item, "tracker-other", -1, 1 );
    797801                }
    798802                else
  • trunk/libtransmission/peer-mgr.c

    r4720 r4734  
    920920            break;
    921921
    922         case TR_PEERMSG_GOT_ASSERT_ERROR:
    923             addStrike( t, peer );
    924             peer->doPurge = 1;
    925             break;
    926 
    927         case TR_PEERMSG_GOT_ERROR:
     922        case TR_PEERMSG_ERROR:
     923            if( TR_ERROR_IS_IO( e->err ) ) {
     924                t->tor->error = e->err;
     925                strlcpy( t->tor->errorString, tr_errorString( e->err ), sizeof(t->tor->errorString) );
     926                tr_torrentStop( t->tor );
     927            } else if( e->err == TR_ERROR_ASSERT ) {
     928                addStrike( t, peer );
     929            }
    928930            peer->doPurge = 1;
    929931            break;
  • trunk/libtransmission/peer-msgs.c

    r4648 r4734  
    263263**/
    264264
    265 static const tr_peermsgs_event blankEvent = { 0, 0, 0, 0, 0.0f };
     265static const tr_peermsgs_event blankEvent = { 0, 0, 0, 0, 0.0f, 0 };
    266266
    267267static void
     
    272272
    273273static void
    274 fireGotAssertError( tr_peermsgs * msgs )
     274fireError( tr_peermsgs * msgs, tr_errno err )
    275275{
    276276    tr_peermsgs_event e = blankEvent;
    277     e.eventType = TR_PEERMSG_GOT_ASSERT_ERROR;
    278     publish( msgs, &e );
    279 }
    280 
    281 static void
    282 fireGotError( tr_peermsgs * msgs )
    283 {
    284     tr_peermsgs_event e = blankEvent;
    285     e.eventType = TR_PEERMSG_GOT_ERROR;
     277    e.eventType = TR_PEERMSG_ERROR;
     278    e.err = err;
    286279    publish( msgs, &e );
    287280}
     
    593586    const time_t now = time( NULL );
    594587
    595     // find queued requests that are too old
    596     // "time_requested" here is when the request was queued
     588    /* find queued requests that are too old
     589       "time_requested" here is when the request was queued */
    597590    for( l=msgs->clientWillAskFor; l!=NULL; l=l->next ) {
    598591        struct peer_request * req = l->data;
     
    601594    }
    602595
    603     // find sent requests that are too old
    604     // "time_requested" here is when the request was sent
     596    /* find sent requests that are too old
     597       "time_requested" here is when the request was sent */
    605598    for( l=msgs->clientAskedFor; l!=NULL; l=l->next ) {
    606599        struct peer_request * req = l->data;
     
    609602    }
    610603
    611     // expire the old requests
     604    /* expire the old requests */
    612605    for( l=prune; l!=NULL; l=l->next ) {
    613606        struct peer_request * req = l->data;
     
    615608    }
    616609
    617     // cleanup
     610    /* cleanup */
    618611    tr_list_free( &prune, NULL );
    619612}
     
    11511144            return READ_AGAIN;
    11521145        else {
    1153             fireGotAssertError( msgs );
     1146            fireError( msgs, err );
    11541147            return READ_DONE;
    11551148        }
     
    11651158    const size_t startBufLen = EVBUFFER_LENGTH( inbuf );
    11661159
    1167     --msglen; // id length
     1160    --msglen; /* id length */
    11681161
    11691162    if( inlen < msglen )
     
    11751168    {
    11761169        dbgmsg( msgs, "bad packet - BT message #%d with a length of %d", (int)id, (int)msglen );
    1177         fireGotError( msgs );
     1170        fireError( msgs, TR_ERROR );
    11781171        return READ_DONE;
    11791172    }
     
    13871380}
    13881381
    1389 static int
     1382static tr_errno
    13901383clientGotBlock( tr_peermsgs                * msgs,
    13911384                const uint8_t              * data,
    13921385                const struct peer_request  * req )
    13931386{
    1394     int i;
     1387    int err;
    13951388    tr_torrent * tor = msgs->torrent;
    13961389    const int block = _tr_block( tor, req->index, req->offset );
     
    14041397        dbgmsg( msgs, "wrong block size -- expected %u, got %d",
    14051398                tr_torBlockCountBytes( msgs->torrent, block ), req->length );
    1406         return TR_ERROR_ASSERT;
     1399        return TR_ERROR;
    14071400    }
    14081401
     
    14451438
    14461439    msgs->info->peerSentPieceDataAt = time( NULL );
    1447     i = tr_ioWrite( tor, req->index, req->offset, req->length, data );
    1448     if( i )
    1449         return 0;
     1440    if(( err = tr_ioWrite( tor, req->index, req->offset, req->length, data )))
     1441        return err;
    14501442
    14511443    tr_cpBlockAdd( tor->completion, block );
     
    16571649        dbgmsg( vmsgs, "libevent got an error! what=%hd, errno=%d (%s)",
    16581650                what, errno, strerror(errno) );
    1659         fireGotError( vmsgs );
     1651        fireError( vmsgs, TR_ERROR );
    16601652    }
    16611653}
  • trunk/libtransmission/peer-msgs.h

    r4496 r4734  
    6666    TR_PEERMSG_PIECE_DATA,
    6767    TR_PEERMSG_PEER_PROGRESS,
    68     TR_PEERMSG_GOT_ERROR,
    69     TR_PEERMSG_GOT_ASSERT_ERROR,
     68    TR_PEERMSG_ERROR,
    7069    TR_PEERMSG_CANCEL,
    7170    TR_PEERMSG_NEED_REQ
     
    8079    uint32_t length;     /* for TR_PEERMSG_GOT_BLOCK */
    8180    float progress;      /* for TR_PEERMSG_PEER_PROGRESS */
     81    tr_errno err;        /* for TR_PEERMSG_GOT_ERROR */
    8282}
    8383tr_peermsgs_event;
  • trunk/libtransmission/torrent.c

    r4710 r4734  
    881881}
    882882
    883 enum
    884 {
    885     AFTER_RECHECK_NONE,
    886     AFTER_RECHECK_START,
    887     AFTER_RECHECK_STOP,
    888     AFTER_RECHECK_CLOSE
    889 };
     883/**
     884***  Start/Stop Callback
     885**/
     886
     887static void
     888fireActiveChange( tr_torrent * tor, int isRunning )
     889{
     890    assert( tor != NULL );
     891
     892    if( tor->active_func != NULL )
     893        (tor->active_func)( tor, isRunning, tor->active_func_user_data );
     894}
     895
     896void
     897tr_torrentSetActiveCallback( tr_torrent             * tor,
     898                             tr_torrent_active_func   func,
     899                             void                   * user_data )
     900{
     901    assert( tor != NULL );
     902    tor->active_func = func;
     903    tor->active_func_user_data = user_data;
     904}
     905
     906void
     907tr_torrentClearActiveCallback( tr_torrent * torrent )
     908{
     909    tr_torrentSetActiveCallback( torrent, NULL, NULL );
     910}
     911
    890912
    891913static void
     
    897919
    898920    tor->isRunning  = 1;
     921    fireActiveChange( tor, tor->isRunning );
    899922    *tor->errorString = '\0';
    900923    tr_torrentResetTransferStats( tor );
     
    960983    tr_peerMgrStopTorrent( tor->handle->peerMgr, tor->info.hash );
    961984    tr_trackerStop( tor->tracker );
     985    fireActiveChange( tor, 0 );
    962986
    963987    for( i=0; i<tor->info.fileCount; ++i )
  • trunk/libtransmission/torrent.h

    r4539 r4734  
    148148    void                     * status_func_user_data;
    149149
     150    tr_torrent_active_func   * active_func;
     151    void                     * active_func_user_data;
     152
    150153    unsigned int               statCur : 1;
    151154    unsigned int               isRunning : 1;
  • trunk/libtransmission/transmission.h

    r4683 r4734  
    6767    TR_PEER_FROM__MAX
    6868};
    69 
    70 /***********************************************************************
    71  * Error codes
    72  **********************************************************************/
    73 /* General errors */
    74 #define TR_OK                       0x00000000
    75 #define TR_ERROR                    0x81000000
    76 #define TR_ERROR_ASSERT             0x82000000
    77 /* I/O errors */
    78 #define TR_ERROR_IO_MASK            0x000000FF
    79 #define TR_ERROR_IO_PERMISSIONS     0x80000002
    80 #define TR_ERROR_IO_SPACE           0x80000004
    81 #define TR_ERROR_IO_FILE_TOO_BIG    0x80000008
    82 #define TR_ERROR_IO_OPEN_FILES      0x80000010
    83 #define TR_ERROR_IO_DUP_DOWNLOAD    0x80000020
    84 #define TR_ERROR_IO_OTHER           0x80000040
    85 /* Misc */
    86 #define TR_ERROR_TC_MASK            0x00000F00
    87 #define TR_ERROR_TC_ERROR           0x80000100
    88 #define TR_ERROR_TC_WARNING         0x80000200
    89 
    90 #define TR_ERROR_ISSET( num, code ) ( (code) == ( (code) & (num) ) )
    9169
    9270/***********************************************************************
     
    497475
    498476/**
    499 ***  Register to be notified whenever a torrent's state changes.
     477***
    500478**/
    501479
     
    512490                                      void         * user_data );
    513491
     492/**
     493 * Register to be notified whenever a torrent's state changes.
     494 *
     495 * func is invoked FROM LIBTRANSMISSION'S THREAD!
     496 * This means func must be fast (to avoid blocking peers),
     497 * shouldn't call libtransmission functions (to avoid deadlock),
     498 * and shouldn't modify client-level memory without using a mutex!
     499 */
    514500void tr_torrentSetStatusCallback( tr_torrent             * torrent,
    515501                                  tr_torrent_status_func   func,
     
    517503
    518504void tr_torrentClearStatusCallback( tr_torrent * torrent );
     505
     506
     507
     508/**
     509***
     510**/
     511
     512typedef void (tr_torrent_active_func)(tr_torrent   * torrent,
     513                                      int            isRunning,
     514                                      void         * user_data );
     515
     516/**
     517 * Register to be notified whenever a torrent starts or stops.
     518 *
     519 * func is invoked FROM LIBTRANSMISSION'S THREAD!
     520 * This means func must be fast (to avoid blocking peers),
     521 * shouldn't call libtransmission functions (to avoid deadlock),
     522 * and shouldn't modify client-level memory without using a mutex!
     523 */
     524void tr_torrentSetActiveCallback( tr_torrent             * torrent,
     525                                  tr_torrent_active_func   func,
     526                                  void                   * user_data );
     527
     528void tr_torrentClearActiveCallback( tr_torrent * torrent );
     529
    519530
    520531/**
     
    676687#define TR_STATUS_IS_ACTIVE(s) ((s) != TR_STATUS_STOPPED)
    677688
    678 /***********************************************************************
    679  * tr_stat
    680  **********************************************************************/
     689/**
     690 * Transmission error codes
     691 * errors are always negative, and 0 refers to no error.
     692 */
     693typedef enum tr_errno
     694{
     695    TR_OK = 0,
     696
     697    /* general errors */
     698    TR_ERROR = -100,
     699    TR_ERROR_ASSERT,
     700
     701    /* io errors */
     702    TR_ERROR_IO_PARENT = -200,
     703    TR_ERROR_IO_PERMISSIONS,
     704    TR_ERROR_IO_SPACE,
     705    TR_ERROR_IO_FILE_TOO_BIG,
     706    TR_ERROR_IO_OPEN_FILES,
     707    TR_ERROR_IO_DUP_DOWNLOAD,
     708    TR_ERROR_IO_OTHER,
     709
     710    /* tracker errors */
     711    TR_ERROR_TC_ERROR = -300,
     712    TR_ERROR_TC_WARNING
     713}
     714tr_errno;
     715
     716#define TR_ERROR_IS_IO(e) (TR_ERROR_IO_PARENT<=(e) && (e)<=TR_ERROR_IO_OTHER)
     717#define TR_ERROR_IS_TC(e) (TR_ERROR_TC_ERROR<=(e) && (e)<=TR_ERROR_TC_WARNING)
     718
    681719struct tr_stat
    682720{
    683721    tr_torrent_status   status;
    684722
    685     int                 error;
     723    tr_errno            error;
    686724    char                errorString[128];
    687725
  • trunk/libtransmission/utils.c

    r4733 r4734  
    490490
    491491int
    492 tr_ioErrorFromErrno( void )
    493 {
    494     switch( errno )
    495     {
     492tr_ioErrorFromErrno( int err )
     493{
     494    switch( err )
     495    {
     496        case 0:
     497            return TR_OK;
    496498        case EACCES:
    497499        case EROFS:
     
    516518        case TR_OK:
    517519            return "No error";
     520
    518521        case TR_ERROR:
    519522            return "Generic error";
    520523        case TR_ERROR_ASSERT:
    521524            return "Assert error";
     525
     526        case TR_ERROR_IO_PARENT:
     527            return "Download folder does not exist";
    522528        case TR_ERROR_IO_PERMISSIONS:
    523529            return "Insufficient permissions";
    524530        case TR_ERROR_IO_SPACE:
    525531            return "Insufficient free space";
    526         case TR_ERROR_IO_DUP_DOWNLOAD:
    527             return "Already active transfer with same name and download folder";
    528532        case TR_ERROR_IO_FILE_TOO_BIG:
    529533            return "File too large";
    530534        case TR_ERROR_IO_OPEN_FILES:
    531535            return "Too many open files";
     536        case TR_ERROR_IO_DUP_DOWNLOAD:
     537            return "Already active transfer with same name and download folder";
    532538        case TR_ERROR_IO_OTHER:
    533539            return "Generic I/O error";
    534     }
    535     return "Unknown error";
     540   
     541        default:
     542            return "Unknown error";
     543    }
    536544}
    537545
  • trunk/libtransmission/utils.h

    r4733 r4734  
    7777
    7878
    79 int    tr_ioErrorFromErrno( void );
     79int tr_ioErrorFromErrno( int err );
    8080
    8181const char * tr_errorString( int code );
Note: See TracChangeset for help on using the changeset viewer.