Changeset 3665
- Timestamp:
- Oct 31, 2007, 6:10:54 PM (15 years ago)
- Location:
- branches/0.9x
- Files:
-
- 6 edited
Legend:
- Unmodified
- Added
- Removed
-
branches/0.9x/configure.ac
r3637 r3665 30 30 AC_HEADER_TIME 31 31 AC_CHECK_FUNCS([lrintf strlcpy strlcat daemon dirname basename]) 32 AC_CHECK_SIZEOF([void*]) 32 33 AC_PROG_INSTALL 33 34 AC_PROG_MAKE_SET -
branches/0.9x/libtransmission/fdlimit.c
r3649 r3665 25 25 #include <assert.h> 26 26 #include <errno.h> 27 #include <inttypes.h> 27 28 #include <stdio.h> 28 29 #include <stdlib.h> … … 43 44 #include "transmission.h" 44 45 #include "trcompat.h" 46 #include "list.h" 45 47 #include "net.h" 46 48 #include "platform.h" 47 49 #include "utils.h" 50 51 #if SIZEOF_VOIDP==8 52 #define TR_UINT_TO_PTR(i) (void*)((uint64_t)i) 53 #else 54 #define TR_UINT_TO_PTR(i) ((void*)((uint32_t)i)) 55 #endif 48 56 49 57 /** … … 82 90 enum 83 91 { 84 TR_MAX_OPEN_FILES = 16, /* That is,real files, not sockets */92 TR_MAX_OPEN_FILES = 16, /* real files, not sockets */ 85 93 86 94 TR_RESERVED_FDS = 16 /* sockets reserved for tracker connections */ … … 92 100 unsigned int isWritable : 1; 93 101 char filename[MAX_PATH_LENGTH]; 94 int f ile;102 int fd; 95 103 uint64_t date; 96 104 }; … … 118 126 { 119 127 struct tr_openfile * file = &gFd->open[i]; 120 struct stat sb;121 128 char * dir; 122 129 int flags; … … 131 138 } 132 139 133 /* Make sure the parent folder exists */ 134 if( stat( dir, &sb ) || !S_ISDIR( sb.st_mode ) ) { 135 free( dir ); 136 return TR_ERROR_IO_PARENT; 137 } 138 139 errno = 0; 140 flags = 0; 140 /* open the file */ 141 flags = write ? (O_RDWR | O_CREAT) : O_RDONLY; 141 142 #ifdef WIN32 142 143 flags |= O_BINARY; 143 144 #endif 144 flags |= write ? (O_RDWR | O_CREAT) : O_RDONLY;145 file->f ile = open( filename, flags, 0666);145 errno = 0; 146 file->fd = open( filename, flags, 0600 ); 146 147 free( dir ); 147 if( write && ( file->file < 0 ) ) 148 { 149 const int ret = tr_ioErrorFromErrno(); 150 if( errno ) 148 if( file->fd < 0 ) { 149 if( errno ) { 151 150 tr_err( "Couldn't open '%s': %s", filename, strerror(errno) ); 152 else 151 return tr_ioErrorFromErrno(); 152 } else { 153 153 tr_err( "Couldn't open '%s'", filename ); 154 return ret; 154 return TR_ERROR_IO_OTHER; 155 } 155 156 } 156 157 … … 161 162 fileIsOpen( const struct tr_openfile * o ) 162 163 { 163 return o->f ile>= 0;164 return o->fd >= 0; 164 165 } 165 166 … … 167 168 TrCloseFile( int i ) 168 169 { 169 struct tr_openfile * file= &gFd->open[i];170 struct tr_openfile * o = &gFd->open[i]; 170 171 171 172 assert( i >= 0 ); 172 173 assert( i < TR_MAX_OPEN_FILES ); 173 assert( fileIsOpen( file ) ); 174 175 dbgmsg( "closing %s in slot %d writable %c", 176 file->filename, i, file->isWritable?'y':'n' ); 177 close( file->file ); 178 file->file = -1; 179 file->isCheckedOut = 0; 174 assert( fileIsOpen( o ) ); 175 176 dbgmsg( "closing slot #%d, %s", i, o->filename ); 177 close( o->fd ); 178 o->fd = -1; 179 o->isCheckedOut = 0; 180 180 tr_condSignal( gFd->cond ); 181 181 } … … 192 192 int i, winner; 193 193 struct tr_openfile * o; 194 195 assert( filename && *filename ); 196 assert( write==0 || write==1 ); 194 197 195 198 dbgmsg( "looking for file '%s', writable %c", filename, write?'y':'n' ); … … 211 214 dbgmsg( "found it! it's open, but checked out. waiting..." ); 212 215 tr_condWait( gFd->cond, gFd->lock ); 213 i = -1; 216 i = -1; /* reloop */ 214 217 continue; 215 218 } … … 218 221 dbgmsg( "found it! it's open and available, but isn't writable. closing..." ); 219 222 TrCloseFile( i ); 220 continue;223 break; 221 224 } 222 225 … … 243 246 } 244 247 245 if( o->date < date ) { 248 if( date > o->date ) { 249 date = o->date; 246 250 winner = i; 247 date = o->date;248 251 } 249 252 } … … 272 275 273 276 dbgmsg( "opened '%s' in slot %d, write %c", filename, winner, write?'y':'n' ); 274 strlcpy( gFd->open[winner].filename, filename, MAX_PATH_LENGTH);275 gFd->open[winner].isWritable = write;277 strlcpy( o->filename, filename, sizeof( o->filename ) ); 278 o->isWritable = write; 276 279 } 277 280 278 281 dbgmsg( "checking out '%s' in slot %d", filename, winner ); 279 gFd->open[winner].isCheckedOut = 1;280 gFd->open[winner].date = tr_date();282 o->isCheckedOut = 1; 283 o->date = tr_date(); 281 284 tr_lockUnlock( gFd->lock ); 282 return gFd->open[winner].file;285 return o->fd; 283 286 } 284 287 … … 291 294 for( i=0; i<TR_MAX_OPEN_FILES; ++i ) { 292 295 struct tr_openfile * o = &gFd->open[i]; 293 if( o->f ile== file ) {296 if( o->fd == file ) { 294 297 dbgmsg( "releasing file '%s' in slot #%d", o->filename, i ); 295 298 if( o->isWritable ) 296 fsync( o->f ile); /* fflush */299 fsync( o->fd ); /* fflush */ 297 300 o->isCheckedOut = 0; 298 301 break; … … 310 313 ***/ 311 314 312 struct tr_socket 313 { 314 int socket; 315 int priority; 316 }; 317 318 /* Remember the priority of every socket we open, so that we can keep 319 * track of how many reserved file descriptors we are using */ 320 static struct tr_socket * gSockets = NULL; 321 static int gSocketsSize = 0; 322 static int gSocketsCount = 0; 315 static tr_list * reservedSockets = NULL; 323 316 324 317 static void 325 SocketSetPriority( int s, int priority ) 326 { 327 if( gSocketsSize <= gSocketsCount ) { 328 gSocketsSize += 64; 329 gSockets = tr_renew( struct tr_socket, gSockets, gSocketsSize ); 330 } 331 332 gSockets[gSocketsCount].socket = s; 333 gSockets[gSocketsCount].priority = priority; 334 ++gSocketsCount; 318 setSocketPriority( int fd, int isReserved ) 319 { 320 if( isReserved ) 321 tr_list_append( &reservedSockets, TR_UINT_TO_PTR(fd) ); 335 322 } 336 323 337 324 static int 338 SocketGetPriority( int s ) 339 { 340 int i, ret; 341 342 for( i=0; i<gSocketsCount; ++i ) 343 if( gSockets[i].socket == s ) 344 break; 345 346 if( i >= gSocketsCount ) { 347 tr_err( "could not find that socket (%d)!", s ); 348 return -1; 349 } 350 351 ret = gSockets[i].priority; 352 gSocketsCount--; 353 memmove( &gSockets[i], &gSockets[i+1], 354 ( gSocketsCount - i ) * sizeof( struct tr_socket ) ); 355 return ret; 325 socketWasReserved( int fd ) 326 { 327 return tr_list_remove_data( &reservedSockets, TR_UINT_TO_PTR(fd) ) != NULL; 356 328 } 357 329 … … 360 332 { 361 333 int s = -1; 362 363 334 tr_lockLock( gFd->lock ); 364 335 … … 367 338 368 339 if( priority || ( gFd->normal < gFd->normalMax ) ) 369 if( ( s = socket( AF_INET, type, 0 ) ) < 0 )370 tr_err( "Couldn't create socket (%s)", strerror( sockerrno ) );340 if( ( s = socket( AF_INET, type, 0 ) ) < 0 ) 341 tr_err( "Couldn't create socket (%s)", strerror( sockerrno ) ); 371 342 372 343 if( s > -1 ) 373 344 { 374 SocketSetPriority( s, priority ); 345 setSocketPriority( s, priority ); 346 375 347 if( priority ) 376 gFd->reserved++;348 ++gFd->reserved; 377 349 else 378 gFd->normal++; 379 } 350 ++gFd->normal; 351 } 352 353 assert( gFd->reserved >= 0 ); 354 assert( gFd->normal >= 0 ); 355 380 356 tr_lockUnlock( gFd->lock ); 381 382 357 return s; 383 358 } … … 387 362 { 388 363 int s = -1; 389 unsigned len;364 unsigned int len; 390 365 struct sockaddr_in sock; 391 366 … … 401 376 if( s > -1 ) 402 377 { 403 SocketSetPriority( s, 0 );378 setSocketPriority( s, 0 ); 404 379 *addr = sock.sin_addr; 405 380 *port = sock.sin_port; … … 424 399 tr_fdSocketClose( int s ) 425 400 { 426 if( s >= 0 )427 { 428 tr_lockLock( gFd->lock );401 tr_lockLock( gFd->lock ); 402 403 if( s >= 0 ) { 429 404 socketClose( s ); 430 if( SocketGetPriority( s ) )431 gFd->reserved--;405 if( socketWasReserved( s ) ) 406 --gFd->reserved; 432 407 else 433 gFd->normal--; 434 tr_lockUnlock( gFd->lock ); 435 } 408 --gFd->normal; 409 } 410 411 assert( gFd->reserved >= 0 ); 412 assert( gFd->normal >= 0 ); 413 414 tr_lockUnlock( gFd->lock ); 436 415 } 437 416 … … 465 444 466 445 for( i=0; i<TR_MAX_OPEN_FILES; ++i ) 467 gFd->open[i].f ile= -1;446 gFd->open[i].fd = -1; 468 447 469 448 } … … 481 460 tr_condFree( gFd->cond ); 482 461 483 tr_ free( gSockets);462 tr_list_free( &reservedSockets, NULL ); 484 463 tr_free( gFd ); 485 464 } -
branches/0.9x/libtransmission/inout.c
r3662 r3665 47 47 48 48 static int 49 readOrWriteBytes ( const tr_torrent* tor,50 intioMode,51 intfileIndex,52 uint64_tfileOffset,53 void* buf,54 size_tbuflen )49 readOrWriteBytes( const tr_torrent * tor, 50 int ioMode, 51 int fileIndex, 52 uint64_t fileOffset, 53 void * buf, 54 size_t buflen ) 55 55 { 56 56 const tr_info * info = &tor->info; … … 71 71 if( !file->length ) 72 72 return 0; 73 else if ((ioMode==TR_IO_READ) && stat( path, &sb ) ) /* fast check to make sure file exists*/73 else if ((ioMode==TR_IO_READ) && stat( path, &sb ) ) /* does file exist? */ 74 74 ret = tr_ioErrorFromErrno (); 75 75 else if ((fd = tr_fdFileOpen ( path, ioMode==TR_IO_WRITE )) < 0) … … 89 89 90 90 static void 91 findFileLocation 92 93 94 95 91 findFileLocation( const tr_torrent * tor, 92 int pieceIndex, 93 int pieceOffset, 94 int * fileIndex, 95 uint64_t * fileOffset ) 96 96 { 97 97 const tr_info * info = &tor->info; … … 117 117 #ifdef WIN32 118 118 static int 119 ensureMinimumFileSize 120 121 uint64_t minSize ) /* in bytes */119 ensureMinimumFileSize( const tr_torrent * tor, 120 int fileIndex, 121 uint64_t minBytes ) 122 122 { 123 123 int fd; … … 128 128 129 129 assert ( 0<=fileIndex && fileIndex<tor->info.fileCount ); 130 assert ( min Size<= file->length );130 assert ( minBytes <= file->length ); 131 131 132 132 tr_buildPath ( path, sizeof(path), tor->destination, file->name, NULL ); … … 137 137 else if (fstat (fd, &sb) ) /* how big is the file? */ 138 138 ret = tr_ioErrorFromErrno (); 139 else if (sb.st_size >= (off_t)min Size) /* already big enough */139 else if (sb.st_size >= (off_t)minBytes) /* already big enough */ 140 140 ret = TR_OK; 141 else if (!ftruncate( fd, min Size)) /* grow it */141 else if (!ftruncate( fd, minBytes )) /* grow it */ 142 142 ret = TR_OK; 143 143 else /* couldn't grow it */ … … 152 152 153 153 static int 154 readOrWritePiece ( tr_torrent* tor,155 intioMode,156 intpieceIndex,157 intpieceOffset,158 uint8_t* buf,159 size_tbuflen )154 readOrWritePiece( tr_torrent * tor, 155 int ioMode, 156 int pieceIndex, 157 int pieceOffset, 158 uint8_t * buf, 159 size_t buflen ) 160 160 { 161 161 int ret = 0; … … 194 194 tr_ioRead( tr_torrent * tor, int pieceIndex, int begin, int len, uint8_t * buf ) 195 195 { 196 return readOrWritePiece 196 return readOrWritePiece( tor, TR_IO_READ, pieceIndex, begin, buf, len ); 197 197 } 198 198 … … 200 200 tr_ioWrite( tr_torrent * tor, int pieceIndex, int begin, int len, uint8_t * buf ) 201 201 { 202 return readOrWritePiece 202 return readOrWritePiece( tor, TR_IO_WRITE, pieceIndex, begin, buf, len ); 203 203 } 204 204 … … 208 208 209 209 static int 210 tr_ioRecalculateHash( tr_torrent 211 int 212 uint8_t 210 tr_ioRecalculateHash( tr_torrent * tor, 211 int pieceIndex, 212 uint8_t * setme ) 213 213 { 214 214 int n; … … 237 237 { 238 238 uint8_t hash[SHA_DIGEST_LENGTH]; 239 int ret = tr_ioRecalculateHash( tor, pieceIndex, hash )240 239 const int ret = tr_ioRecalculateHash( tor, pieceIndex, hash ) 240 || memcmp( hash, tor->info.pieces[pieceIndex].hash, SHA_DIGEST_LENGTH ); 241 241 tr_dbg ("torrent [%s] piece %d hash check: %s", 242 242 tor->info.name, pieceIndex, (ret?"FAILED":"OK")); … … 267 267 } 268 268 269 tr_peerMgrSetBlame( tor->handle->peerMgr, tor->info.hash, pieceIndex, success ); 269 tr_peerMgrSetBlame( tor->handle->peerMgr, tor->info.hash, 270 pieceIndex, success ); 270 271 271 272 return ret; … … 290 291 } 291 292 292 st ruct recheck_node currentNode;293 static struct recheck_node currentNode; 293 294 294 295 static tr_list * recheckList = NULL; … … 397 398 compareRecheckByTorrent( const void * va, const void * vb ) 398 399 { 399 const struct recheck_node * a = ( const struct recheck_node * )va;400 const struct recheck_node * b = ( const struct recheck_node * )vb;401 return a->torrent - b ->torrent;400 const struct recheck_node * a = va; 401 const tr_torrent * b = vb; 402 return a->torrent - b; 402 403 } 403 404 … … 420 421 else 421 422 { 422 struct recheck_node tmp; 423 struct recheck_node * node; 424 tmp.torrent = tor; 425 node = tr_list_remove( &recheckList, 426 &tmp, 427 compareRecheckByTorrent ); 428 tr_free( node ); 423 tr_free( tr_list_remove( &recheckList, tor, compareRecheckByTorrent ) ); 429 424 tor->recheckState = TR_RECHECK_NONE; 430 425 } -
branches/0.9x/libtransmission/ipcparse.c
r3486 r3665 781 781 tr_bencInitStr( item, "assert", -1, 1 ); 782 782 } 783 else if( TR_ERROR_ISSET( TR_ERROR_IO_PARENT, error ) )784 {785 tr_bencInitStr( item, "io-parent", -1, 1 );786 }787 783 else if( TR_ERROR_ISSET( TR_ERROR_IO_PERMISSIONS, error ) ) 788 784 { -
branches/0.9x/libtransmission/transmission.h
r3573 r3665 81 81 /* I/O errors */ 82 82 #define TR_ERROR_IO_MASK 0x000000FF 83 #define TR_ERROR_IO_PARENT 0x8000000184 83 #define TR_ERROR_IO_PERMISSIONS 0x80000002 85 84 #define TR_ERROR_IO_SPACE 0x80000004 -
branches/0.9x/libtransmission/utils.c
r3662 r3665 648 648 case TR_ERROR_ASSERT: 649 649 return "Assert error"; 650 case TR_ERROR_IO_PARENT:651 return "Download folder does not exist";652 650 case TR_ERROR_IO_PERMISSIONS: 653 651 return "Insufficient permissions";
Note: See TracChangeset
for help on using the changeset viewer.