existing_dir: An ancestor of filename which must already exist and won't be created by tr_fdFileCheckout(). In implementation this is the download directory and prevents directories from being created in error, such as a mount point for an external drive when the drive is unplugged.
*/
static int
cached_file_open( struct tr_cached_file * o,
+ const char * existing_dir,
const char * filename,
tr_bool writable,
tr_preallocation_mode allocation,
struct stat sb;
tr_bool alreadyExisted;
+ /* confirm that existing_dir, if specified, exists on the disk */
+ if( existing_dir && *existing_dir && stat( existing_dir, &sb ) )
+ {
+ const int err = errno;
+ tr_err( _( "Couldn't open \"%1$s\": %2$s" ), existing_dir, tr_strerror( err ) );
+ return err;
+ }
+
/* create subfolders, if any */
if( writable )
{
tr_fdFileCheckout( tr_session * session,
int torrent_id,
tr_file_index_t i,
+ const char * existing_dir,
const char * filename,
tr_bool writable,
tr_preallocation_mode allocation,
if( !cached_file_is_open( o ) )
{
- const int err = cached_file_open( o, filename, writable, allocation, file_size );
+ const int err = cached_file_open( o, existing_dir, filename, writable, allocation, file_size );
if( err ) {
errno = err;
return -1;
* continually opening and closing the same files when downloading
* piece data.
*
- * - if doWrite is true, subfolders in torrentFile are created if necessary.
- * - if doWrite is true, the target file is created if necessary.
+ * - if do_write is true, subfolders in torrentFile are created if necessary.
+ * - if do_write is true, the target file is created if necessary.
+ *
+ * @param existing_dir An ancestor of filename which must already exist and
+ * won't be created by tr_fdFileCheckout(). This prevents
+ * directories from being created in error, such as a mount
+ * point for an external drive when the drive is unplugged.
*
* on success, a file descriptor >= 0 is returned.
* on failure, a -1 is returned and errno is set.
* @see tr_fdFileClose
*/
int tr_fdFileCheckout( tr_session * session,
- int torrentId,
- tr_file_index_t fileNum,
- const char * fileName,
- tr_bool doWrite,
- tr_preallocation_mode preallocationMode,
- uint64_t desiredFileSize );
+ int torrent_id,
+ tr_file_index_t file_num,
+ const char * existing_dir,
+ const char * filename,
+ tr_bool do_write,
+ tr_preallocation_mode preallocation_mode,
+ uint64_t preallocation_file_size );
int tr_fdFileGetCached( tr_session * session,
- int torrentId,
- tr_file_index_t fileNum,
+ int torrent_id,
+ tr_file_index_t file_num,
tr_bool doWrite );
/**
*/
void tr_fdFileClose( tr_session * session,
const tr_torrent * tor,
- tr_file_index_t fileNo );
+ tr_file_index_t file_num );
/**
{
char * filename = tr_buildPath( base, subpath, NULL );
- if( ( fd = tr_fdFileCheckout( session, tor->uniqueId, fileIndex, filename,
+ if( ( fd = tr_fdFileCheckout( session, tor->uniqueId, fileIndex,
+ base, filename,
doWrite, preallocationMode, file->length ) ) < 0 )
{
err = errno;
/**
* Converts a piece index + offset into a file index + offset.
*/
-void tr_ioFindFileLocation( const tr_torrent * tor,
- tr_piece_index_t pieceIndex,
- uint32_t pieceOffset,
- tr_file_index_t * fileIndex,
- uint64_t * fileOffset );
+void tr_ioFindFileLocation( const tr_torrent * tor,
+ tr_piece_index_t pieceIndex,
+ uint32_t pieceOffset,
+ tr_file_index_t * fileIndex,
+ uint64_t * fileOffset );
/* @} */