Changeset 4734
- Timestamp:
- Jan 18, 2008, 7:13:32 PM (13 years ago)
- Location:
- trunk/libtransmission
- Files:
-
- 13 edited
Legend:
- Unmodified
- Added
- Removed
-
trunk/libtransmission/fdlimit.c
r4598 r4734 128 128 ***/ 129 129 130 static int 131 TrOpenFile( int i, const char * filename, int write ) 130 static tr_errno 131 TrOpenFile( int i, 132 const char * folder, 133 const char * torrentFile, 134 int write ) 132 135 { 133 136 struct tr_openfile * file = &gFd->open[i]; 134 137 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; 135 144 136 145 /* create subfolders, if any */ 146 tr_buildPath ( filename, sizeof(filename), folder, torrentFile, NULL ); 137 147 if( write ) { 138 148 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; 140 150 tr_free( tmp ); 141 if( val)142 return tr_ioErrorFromErrno( );151 if( err ) 152 return tr_ioErrorFromErrno( err ); 143 153 } 144 154 … … 151 161 flags |= O_BINARY; 152 162 #endif 153 errno = 0;154 163 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; 166 171 } 167 172 … … 193 198 194 199 int 195 tr_fdFileCheckout( const char * filename, int write ) 200 tr_fdFileCheckout( const char * folder, 201 const char * torrentFile, 202 int write ) 196 203 { 197 204 int i, winner = -1; 198 205 struct tr_openfile * o; 199 200 assert( filename && *filename ); 206 char filename[MAX_PATH_LENGTH]; 207 208 assert( folder && *folder ); 209 assert( torrentFile && *torrentFile ); 201 210 assert( write==0 || write==1 ); 202 211 212 tr_buildPath ( filename, sizeof(filename), folder, torrentFile, NULL ); 203 213 dbgmsg( "looking for file '%s', writable %c", filename, write?'y':'n' ); 204 214 … … 275 285 if( !fileIsOpen( o ) ) 276 286 { 277 const int ret = TrOpenFile( winner, filename, write );278 if( ret) {287 const tr_errno err = TrOpenFile( winner, folder, torrentFile, write ); 288 if( err ) { 279 289 tr_lockUnlock( gFd->lock ); 280 return ret;290 return err; 281 291 } 282 292 -
trunk/libtransmission/fdlimit.h
r4404 r4734 37 37 * Returns an fd to the specified filename. 38 38 * 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. 43 44 * 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. 47 51 * 48 52 * @see tr_fdFileReturn 49 53 * @see tr_fdFileClose 54 * @see tr_errno 50 55 */ 51 int tr_fdFileCheckout( const char * filename, int write ); 56 int tr_fdFileCheckout( const char * folder, 57 const char * torrentFile, 58 int doWrite ); 52 59 53 60 /** -
trunk/libtransmission/inout.c
r4561 r4734 42 42 enum { TR_IO_READ, TR_IO_WRITE }; 43 43 44 static int44 static tr_errno 45 45 readOrWriteBytes( const tr_torrent * tor, 46 46 int ioMode, … … 57 57 struct stat sb; 58 58 int fd = -1; 59 int ret;59 int err; 60 60 int fileExists; 61 61 … … 69 69 if( !file->length ) 70 70 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; 75 76 else if( lseek( fd, (off_t)fileOffset, SEEK_SET ) == ((off_t)-1) ) 76 ret = TR_ERROR_IO_OTHER;77 err = tr_ioErrorFromErrno( errno ); 77 78 else if( func( fd, buf, buflen ) != buflen ) 78 ret = tr_ioErrorFromErrno();79 err = tr_ioErrorFromErrno( errno ); 79 80 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) ) 83 84 tr_statsFileCreated( tor->handle ); 84 85 … … 86 87 tr_fdFileReturn( fd ); 87 88 88 return ret;89 } 90 91 static void89 return err; 90 } 91 92 static tr_errno 92 93 findFileLocation( const tr_torrent * tor, 93 94 int pieceIndex, … … 101 102 uint64_t piecePos = ((uint64_t)pieceIndex * info->pieceSize) + pieceOffset; 102 103 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; 107 110 108 111 for( i=0; info->files[i].length<=piecePos; ++i ) … … 114 117 assert( 0<=*fileIndex && *fileIndex<info->fileCount ); 115 118 assert( *fileOffset < info->files[i].length ); 119 return 0; 116 120 } 117 121 118 122 #ifdef WIN32 119 static int123 static tr_errno 120 124 ensureMinimumFileSize( const tr_torrent * tor, 121 125 int fileIndex, … … 123 127 { 124 128 int fd; 125 int ret;129 tr_errno err; 126 130 struct stat sb; 127 131 const tr_file * file = &tor->info.files[fileIndex]; 128 char path[MAX_PATH_LENGTH];129 132 130 133 assert( 0<=fileIndex && fileIndex<tor->info.fileCount ); 131 134 assert( minBytes <= file->length ); 132 135 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; 138 138 else if (fstat (fd, &sb) ) /* how big is the file? */ 139 ret = tr_ioErrorFromErrno ();139 err = tr_ioErrorFromErrno( errno ); 140 140 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; 144 144 else /* couldn't grow it */ 145 ret = tr_ioErrorFromErrno ();145 err = tr_ioErrorFromErrno( errno ); 146 146 147 147 if( fd >= 0 ) 148 148 tr_fdFileReturn( fd ); 149 149 150 return ret;150 return err; 151 151 } 152 152 #endif 153 153 154 static int154 static tr_errno 155 155 readOrWritePiece( tr_torrent * tor, 156 156 int ioMode, … … 160 160 size_t buflen ) 161 161 { 162 int ret= 0;162 tr_errno err = 0; 163 163 int fileIndex; 164 164 uint64_t fileOffset; 165 165 const tr_info * info = &tor->info; 166 166 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 ) 173 176 { 174 177 const tr_file * file = &info->files[fileIndex]; … … 177 180 #ifdef WIN32 178 181 if( ioMode == TR_IO_WRITE ) 179 ret= ensureMinimumFileSize( tor, fileIndex,182 err = ensureMinimumFileSize( tor, fileIndex, 180 183 fileOffset + bytesThisPass ); 181 if( ! ret)184 if( !err ) 182 185 #endif 183 ret= readOrWriteBytes( tor, ioMode,186 err = readOrWriteBytes( tor, ioMode, 184 187 fileIndex, fileOffset, buf, bytesThisPass ); 185 188 buf += bytesThisPass; … … 189 192 } 190 193 191 return ret;192 } 193 194 int 194 return err; 195 } 196 197 tr_errno 195 198 tr_ioRead( tr_torrent * tor, 196 199 int pieceIndex, … … 202 205 } 203 206 204 int 207 tr_errno 205 208 tr_ioWrite( tr_torrent * tor, 206 209 int pieceIndex, -
trunk/libtransmission/inout.h
r4404 r4734 28 28 struct tr_torrent; 29 29 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 */ 35 int tr_ioRead ( struct tr_torrent*, int index, int begin, int len, uint8_t * ); 31 36 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 */ 42 tr_errno tr_ioWrite ( struct tr_torrent *, int index, int begin, int len, const uint8_t * ); 42 43 43 44 /* hashes the specified piece and updates the completion accordingly. */ -
trunk/libtransmission/ipcparse.c
r4537 r4734 713 713 benc_val_t * dict, * item; 714 714 int ii, used; 715 unsigned interror;715 tr_errno error; 716 716 717 717 /* always send torrent id */ … … 764 764 tr_bencInitStr( item, "", -1, 1 ); 765 765 } 766 else if( TR_ERROR_ISSET( TR_ERROR_ASSERT, error ))766 else if( error == TR_ERROR_ASSERT ) 767 767 { 768 768 tr_bencInitStr( item, "assert", -1, 1 ); 769 769 } 770 else if( TR_ERROR_ISSET( TR_ERROR_IO_PERMISSIONS, error ))770 else if( error == TR_ERROR_IO_PERMISSIONS ) 771 771 { 772 772 tr_bencInitStr( item, "io-permissions", -1, 1 ); 773 773 } 774 else if( TR_ERROR_ISSET( TR_ERROR_IO_SPACE, error ))774 else if( error == TR_ERROR_IO_SPACE ) 775 775 { 776 776 tr_bencInitStr( item, "io-space", -1, 1 ); 777 777 } 778 else if( TR_ERROR_ISSET( TR_ERROR_IO_FILE_TOO_BIG, error ))778 else if( error == TR_ERROR_IO_FILE_TOO_BIG ) 779 779 { 780 780 tr_bencInitStr( item, "io-file-too-big", -1, 1 ); 781 781 } 782 else if( TR_ERROR_ISSET( TR_ERROR_IO_OPEN_FILES, error ))782 else if( error == TR_ERROR_IO_OPEN_FILES ) 783 783 { 784 784 tr_bencInitStr( item, "io-open-files", -1, 1 ); 785 785 } 786 else if( TR_ERROR_IS SET( TR_ERROR_IO_MASK,error ) )786 else if( TR_ERROR_IS_IO( error ) ) 787 787 { 788 788 tr_bencInitStr( item, "io-other", -1, 1 ); 789 789 } 790 else if( TR_ERROR_ISSET( TR_ERROR_TC_ERROR, error ))790 else if( error == TR_ERROR_TC_ERROR ) 791 791 { 792 792 tr_bencInitStr( item, "tracker-error", -1, 1 ); 793 793 } 794 else if( TR_ERROR_ISSET( TR_ERROR_TC_WARNING, error ))794 else if( error == TR_ERROR_TC_WARNING ) 795 795 { 796 796 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 ); 797 801 } 798 802 else -
trunk/libtransmission/peer-mgr.c
r4720 r4734 920 920 break; 921 921 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 } 928 930 peer->doPurge = 1; 929 931 break; -
trunk/libtransmission/peer-msgs.c
r4648 r4734 263 263 **/ 264 264 265 static const tr_peermsgs_event blankEvent = { 0, 0, 0, 0, 0.0f };265 static const tr_peermsgs_event blankEvent = { 0, 0, 0, 0, 0.0f, 0 }; 266 266 267 267 static void … … 272 272 273 273 static void 274 fire GotAssertError( tr_peermsgs * msgs)274 fireError( tr_peermsgs * msgs, tr_errno err ) 275 275 { 276 276 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; 286 279 publish( msgs, &e ); 287 280 } … … 593 586 const time_t now = time( NULL ); 594 587 595 / /find queued requests that are too old596 // "time_requested" here is when the request was queued588 /* find queued requests that are too old 589 "time_requested" here is when the request was queued */ 597 590 for( l=msgs->clientWillAskFor; l!=NULL; l=l->next ) { 598 591 struct peer_request * req = l->data; … … 601 594 } 602 595 603 / /find sent requests that are too old604 // "time_requested" here is when the request was sent596 /* find sent requests that are too old 597 "time_requested" here is when the request was sent */ 605 598 for( l=msgs->clientAskedFor; l!=NULL; l=l->next ) { 606 599 struct peer_request * req = l->data; … … 609 602 } 610 603 611 / / expire the old requests604 /* expire the old requests */ 612 605 for( l=prune; l!=NULL; l=l->next ) { 613 606 struct peer_request * req = l->data; … … 615 608 } 616 609 617 / / cleanup610 /* cleanup */ 618 611 tr_list_free( &prune, NULL ); 619 612 } … … 1151 1144 return READ_AGAIN; 1152 1145 else { 1153 fire GotAssertError( msgs);1146 fireError( msgs, err ); 1154 1147 return READ_DONE; 1155 1148 } … … 1165 1158 const size_t startBufLen = EVBUFFER_LENGTH( inbuf ); 1166 1159 1167 --msglen; / / id length1160 --msglen; /* id length */ 1168 1161 1169 1162 if( inlen < msglen ) … … 1175 1168 { 1176 1169 dbgmsg( msgs, "bad packet - BT message #%d with a length of %d", (int)id, (int)msglen ); 1177 fire GotError( msgs);1170 fireError( msgs, TR_ERROR ); 1178 1171 return READ_DONE; 1179 1172 } … … 1387 1380 } 1388 1381 1389 static int1382 static tr_errno 1390 1383 clientGotBlock( tr_peermsgs * msgs, 1391 1384 const uint8_t * data, 1392 1385 const struct peer_request * req ) 1393 1386 { 1394 int i;1387 int err; 1395 1388 tr_torrent * tor = msgs->torrent; 1396 1389 const int block = _tr_block( tor, req->index, req->offset ); … … 1404 1397 dbgmsg( msgs, "wrong block size -- expected %u, got %d", 1405 1398 tr_torBlockCountBytes( msgs->torrent, block ), req->length ); 1406 return TR_ERROR _ASSERT;1399 return TR_ERROR; 1407 1400 } 1408 1401 … … 1445 1438 1446 1439 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; 1450 1442 1451 1443 tr_cpBlockAdd( tor->completion, block ); … … 1657 1649 dbgmsg( vmsgs, "libevent got an error! what=%hd, errno=%d (%s)", 1658 1650 what, errno, strerror(errno) ); 1659 fire GotError( vmsgs);1651 fireError( vmsgs, TR_ERROR ); 1660 1652 } 1661 1653 } -
trunk/libtransmission/peer-msgs.h
r4496 r4734 66 66 TR_PEERMSG_PIECE_DATA, 67 67 TR_PEERMSG_PEER_PROGRESS, 68 TR_PEERMSG_GOT_ERROR, 69 TR_PEERMSG_GOT_ASSERT_ERROR, 68 TR_PEERMSG_ERROR, 70 69 TR_PEERMSG_CANCEL, 71 70 TR_PEERMSG_NEED_REQ … … 80 79 uint32_t length; /* for TR_PEERMSG_GOT_BLOCK */ 81 80 float progress; /* for TR_PEERMSG_PEER_PROGRESS */ 81 tr_errno err; /* for TR_PEERMSG_GOT_ERROR */ 82 82 } 83 83 tr_peermsgs_event; -
trunk/libtransmission/torrent.c
r4710 r4734 881 881 } 882 882 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 887 static void 888 fireActiveChange( 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 896 void 897 tr_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 906 void 907 tr_torrentClearActiveCallback( tr_torrent * torrent ) 908 { 909 tr_torrentSetActiveCallback( torrent, NULL, NULL ); 910 } 911 890 912 891 913 static void … … 897 919 898 920 tor->isRunning = 1; 921 fireActiveChange( tor, tor->isRunning ); 899 922 *tor->errorString = '\0'; 900 923 tr_torrentResetTransferStats( tor ); … … 960 983 tr_peerMgrStopTorrent( tor->handle->peerMgr, tor->info.hash ); 961 984 tr_trackerStop( tor->tracker ); 985 fireActiveChange( tor, 0 ); 962 986 963 987 for( i=0; i<tor->info.fileCount; ++i ) -
trunk/libtransmission/torrent.h
r4539 r4734 148 148 void * status_func_user_data; 149 149 150 tr_torrent_active_func * active_func; 151 void * active_func_user_data; 152 150 153 unsigned int statCur : 1; 151 154 unsigned int isRunning : 1; -
trunk/libtransmission/transmission.h
r4683 r4734 67 67 TR_PEER_FROM__MAX 68 68 }; 69 70 /***********************************************************************71 * Error codes72 **********************************************************************/73 /* General errors */74 #define TR_OK 0x0000000075 #define TR_ERROR 0x8100000076 #define TR_ERROR_ASSERT 0x8200000077 /* I/O errors */78 #define TR_ERROR_IO_MASK 0x000000FF79 #define TR_ERROR_IO_PERMISSIONS 0x8000000280 #define TR_ERROR_IO_SPACE 0x8000000481 #define TR_ERROR_IO_FILE_TOO_BIG 0x8000000882 #define TR_ERROR_IO_OPEN_FILES 0x8000001083 #define TR_ERROR_IO_DUP_DOWNLOAD 0x8000002084 #define TR_ERROR_IO_OTHER 0x8000004085 /* Misc */86 #define TR_ERROR_TC_MASK 0x00000F0087 #define TR_ERROR_TC_ERROR 0x8000010088 #define TR_ERROR_TC_WARNING 0x8000020089 90 #define TR_ERROR_ISSET( num, code ) ( (code) == ( (code) & (num) ) )91 69 92 70 /*********************************************************************** … … 497 475 498 476 /** 499 *** Register to be notified whenever a torrent's state changes.477 *** 500 478 **/ 501 479 … … 512 490 void * user_data ); 513 491 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 */ 514 500 void tr_torrentSetStatusCallback( tr_torrent * torrent, 515 501 tr_torrent_status_func func, … … 517 503 518 504 void tr_torrentClearStatusCallback( tr_torrent * torrent ); 505 506 507 508 /** 509 *** 510 **/ 511 512 typedef 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 */ 524 void tr_torrentSetActiveCallback( tr_torrent * torrent, 525 tr_torrent_active_func func, 526 void * user_data ); 527 528 void tr_torrentClearActiveCallback( tr_torrent * torrent ); 529 519 530 520 531 /** … … 676 687 #define TR_STATUS_IS_ACTIVE(s) ((s) != TR_STATUS_STOPPED) 677 688 678 /*********************************************************************** 679 * tr_stat 680 **********************************************************************/ 689 /** 690 * Transmission error codes 691 * errors are always negative, and 0 refers to no error. 692 */ 693 typedef 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 } 714 tr_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 681 719 struct tr_stat 682 720 { 683 721 tr_torrent_status status; 684 722 685 interror;723 tr_errno error; 686 724 char errorString[128]; 687 725 -
trunk/libtransmission/utils.c
r4733 r4734 490 490 491 491 int 492 tr_ioErrorFromErrno( void ) 493 { 494 switch( errno ) 495 { 492 tr_ioErrorFromErrno( int err ) 493 { 494 switch( err ) 495 { 496 case 0: 497 return TR_OK; 496 498 case EACCES: 497 499 case EROFS: … … 516 518 case TR_OK: 517 519 return "No error"; 520 518 521 case TR_ERROR: 519 522 return "Generic error"; 520 523 case TR_ERROR_ASSERT: 521 524 return "Assert error"; 525 526 case TR_ERROR_IO_PARENT: 527 return "Download folder does not exist"; 522 528 case TR_ERROR_IO_PERMISSIONS: 523 529 return "Insufficient permissions"; 524 530 case TR_ERROR_IO_SPACE: 525 531 return "Insufficient free space"; 526 case TR_ERROR_IO_DUP_DOWNLOAD:527 return "Already active transfer with same name and download folder";528 532 case TR_ERROR_IO_FILE_TOO_BIG: 529 533 return "File too large"; 530 534 case TR_ERROR_IO_OPEN_FILES: 531 535 return "Too many open files"; 536 case TR_ERROR_IO_DUP_DOWNLOAD: 537 return "Already active transfer with same name and download folder"; 532 538 case TR_ERROR_IO_OTHER: 533 539 return "Generic I/O error"; 534 } 535 return "Unknown error"; 540 541 default: 542 return "Unknown error"; 543 } 536 544 } 537 545 -
trunk/libtransmission/utils.h
r4733 r4734 77 77 78 78 79 int tr_ioErrorFromErrno( void);79 int tr_ioErrorFromErrno( int err ); 80 80 81 81 const char * tr_errorString( int code );
Note: See TracChangeset
for help on using the changeset viewer.