diff --git a/libtransmission/blocklist-test.c b/libtransmission/blocklist-test.c index a9e628108..2bb65ce62 100644 --- a/libtransmission/blocklist-test.c +++ b/libtransmission/blocklist-test.c @@ -9,6 +9,7 @@ #include #include +#include /* strlen () */ #include /* sync() */ #include "transmission.h" @@ -36,17 +37,16 @@ static const char * contents2 = static void create_text_file (const char * path, const char * contents) { - FILE * fp; + tr_sys_file_t fd; char * dir; dir = tr_sys_path_dirname (path, NULL); tr_mkdirp (dir, 0700); tr_free (dir); - tr_sys_path_remove (path, NULL); - fp = fopen (path, "w+"); - fprintf (fp, "%s", contents); - fclose (fp); + fd = tr_sys_file_open (path, TR_SYS_FILE_WRITE | TR_SYS_FILE_CREATE | TR_SYS_FILE_TRUNCATE, 0600, NULL); + tr_sys_file_write (fd, contents, strlen (contents), NULL, NULL); + tr_sys_file_close (fd, NULL); sync (); } diff --git a/libtransmission/blocklist.c b/libtransmission/blocklist.c index c52e034f9..a00b38c37 100644 --- a/libtransmission/blocklist.c +++ b/libtransmission/blocklist.c @@ -13,32 +13,14 @@ #include /* bsearch (), qsort () */ #include -#include /* close () */ - -#ifdef _WIN32 - #include - #define WINVER WindowsXP - #include - #define PROT_READ PAGE_READONLY - #define MAP_PRIVATE FILE_MAP_COPY -#endif - -#ifndef _WIN32 - #include -#endif -#include - #include "transmission.h" #include "blocklist.h" +#include "error.h" #include "file.h" #include "log.h" #include "net.h" #include "utils.h" -#ifndef O_BINARY - #define O_BINARY 0 -#endif - /*** **** PRIVATE @@ -53,9 +35,9 @@ struct tr_ipv4_range struct tr_blocklistFile { bool isEnabled; - int fd; + tr_sys_file_t fd; size_t ruleCount; - size_t byteCount; + uint64_t byteCount; char * filename; struct tr_ipv4_range * rules; }; @@ -65,22 +47,23 @@ blocklistClose (tr_blocklistFile * b) { if (b->rules != NULL) { - munmap (b->rules, b->byteCount); - close (b->fd); + tr_sys_file_unmap (b->rules, b->byteCount, NULL); + tr_sys_file_close (b->fd, NULL); b->rules = NULL; b->ruleCount = 0; b->byteCount = 0; - b->fd = -1; + b->fd = TR_BAD_SYS_FILE; } } static void blocklistLoad (tr_blocklistFile * b) { - int fd; - size_t byteCount; + tr_sys_file_t fd; + uint64_t byteCount; tr_sys_path_info info; char * base; + tr_error * error = NULL; const char * err_fmt = _("Couldn't read \"%1$s\": %2$s"); blocklistClose (b); @@ -88,22 +71,24 @@ blocklistLoad (tr_blocklistFile * b) if (!tr_sys_path_get_info (b->filename, 0, &info, NULL)) return; - byteCount = (size_t) info.size; + byteCount = info.size; if (byteCount == 0) return; - fd = open (b->filename, O_RDONLY | O_BINARY); - if (fd == -1) + fd = tr_sys_file_open (b->filename, TR_SYS_FILE_READ, 0, &error); + if (fd == TR_BAD_SYS_FILE) { - tr_logAddError (err_fmt, b->filename, tr_strerror (errno)); + tr_logAddError (err_fmt, b->filename, error->message); + tr_error_free (error); return; } - b->rules = mmap (NULL, byteCount, PROT_READ, MAP_PRIVATE, fd, 0); + b->rules = tr_sys_file_map_for_reading (fd, 0, byteCount, &error); if (!b->rules) { - tr_logAddError (err_fmt, b->filename, tr_strerror (errno)); - close (fd); + tr_logAddError (err_fmt, b->filename, error->message); + tr_sys_file_close (fd, NULL); + tr_error_free (error); return; } @@ -151,7 +136,7 @@ tr_blocklistFileNew (const char * filename, bool isEnabled) tr_blocklistFile * b; b = tr_new0 (tr_blocklistFile, 1); - b->fd = -1; + b->fd = TR_BAD_SYS_FILE; b->filename = tr_strdup (filename); b->isEnabled = isEnabled; diff --git a/libtransmission/fdlimit.c b/libtransmission/fdlimit.c index aaa670ec1..ffb7a6065 100644 --- a/libtransmission/fdlimit.c +++ b/libtransmission/fdlimit.c @@ -7,38 +7,16 @@ * $Id$ */ -#ifdef HAVE_POSIX_FADVISE - #ifdef _XOPEN_SOURCE - #undef _XOPEN_SOURCE - #endif - #define _XOPEN_SOURCE 600 -#endif - #include #include #include #include -#ifdef __APPLE__ - #include -#endif -#ifdef HAVE_FALLOCATE64 - /* FIXME can't find the right #include voodoo to pick up the declaration.. */ - extern int fallocate64 (int fd, int mode, uint64_t offset, uint64_t len); -#endif - -#ifdef HAVE_XFS_XFS_H - #include -#endif - -#include -#include #include /* getrlimit */ #include /* getrlimit */ -#include /* O_LARGEFILE posix_fadvise */ -#include /* lseek (), write (), ftruncate (), pread (), pwrite (), etc */ #include "transmission.h" +#include "error.h" #include "fdlimit.h" #include "file.h" #include "log.h" @@ -59,21 +37,8 @@ **** ***/ -#ifndef O_LARGEFILE - #define O_LARGEFILE 0 -#endif - -#ifndef O_BINARY - #define O_BINARY 0 -#endif - -#ifndef O_SEQUENTIAL - #define O_SEQUENTIAL 0 -#endif - - static bool -preallocate_file_sparse (int fd, uint64_t length) +preallocate_file_sparse (tr_sys_file_t fd, uint64_t length) { const char zero = '\0'; bool success = 0; @@ -81,15 +46,18 @@ preallocate_file_sparse (int fd, uint64_t length) if (!length) success = true; -#ifdef HAVE_FALLOCATE64 - if (!success) /* fallocate64 is always preferred, so try it first */ - success = !fallocate64 (fd, 0, 0, length); -#endif + if (!success) + success = tr_sys_file_preallocate (fd, length, TR_SYS_FILE_PREALLOC_SPARSE, NULL); if (!success) /* fallback: the old-style seek-and-write */ - success = (lseek (fd, length-1, SEEK_SET) != -1) - && (write (fd, &zero, 1) != -1) - && (ftruncate (fd, length) != -1); + { + /* seek requires signed offset, so length should be in mod range */ + assert (length < 0x7FFFFFFFFFFFFFFFULL); + + success = tr_sys_file_seek (fd, length - 1, TR_SEEK_SET, NULL, NULL) && + tr_sys_file_write (fd, &zero, 1, NULL, NULL) && + tr_sys_file_truncate (fd, length, NULL); + } return success; } @@ -99,53 +67,10 @@ preallocate_file_full (const char * filename, uint64_t length) { bool success = 0; -#ifdef _WIN32 - - HANDLE hFile = CreateFile (filename, GENERIC_WRITE, 0, 0, CREATE_NEW, FILE_FLAG_RANDOM_ACCESS, 0); - if (hFile != INVALID_HANDLE_VALUE) + tr_sys_file_t fd = tr_sys_file_open (filename, TR_SYS_FILE_WRITE | TR_SYS_FILE_CREATE, 0666, NULL); + if (fd != TR_BAD_SYS_FILE) { - LARGE_INTEGER li; - li.QuadPart = length; - success = SetFilePointerEx (hFile, li, NULL, FILE_BEGIN) && SetEndOfFile (hFile); - CloseHandle (hFile); - } - -#else - - int flags = O_RDWR | O_CREAT | O_LARGEFILE; - int fd = open (filename, flags, 0666); - if (fd >= 0) - { -# ifdef HAVE_FALLOCATE64 - if (!success) - success = !fallocate64 (fd, 0, 0, length); -# endif -# ifdef HAVE_XFS_XFS_H - if (!success && platform_test_xfs_fd (fd)) - { - xfs_flock64_t fl; - fl.l_whence = 0; - fl.l_start = 0; - fl.l_len = length; - success = !xfsctl (NULL, fd, XFS_IOC_RESVSP64, &fl); - } -# endif -# ifdef __APPLE__ - if (!success) - { - fstore_t fst; - fst.fst_flags = F_ALLOCATECONTIG; - fst.fst_posmode = F_PEOFPOSMODE; - fst.fst_offset = 0; - fst.fst_length = length; - fst.fst_bytesalloc = 0; - success = !fcntl (fd, F_PREALLOCATE, &fst); - } -# endif -# ifdef HAVE_POSIX_FALLOCATE - if (!success) - success = !posix_fallocate (fd, 0, length); -# endif + success = tr_sys_file_preallocate (fd, length, 0, NULL); if (!success) /* if nothing else works, do it the old-fashioned way */ { @@ -154,139 +79,19 @@ preallocate_file_full (const char * filename, uint64_t length) success = true; while (success && (length > 0)) { - const int thisPass = MIN (length, sizeof (buf)); - success = write (fd, buf, thisPass) == thisPass; + const uint64_t thisPass = MIN (length, sizeof (buf)); + uint64_t bytes_written; + success = tr_sys_file_write (fd, buf, thisPass, &bytes_written, NULL) && bytes_written == thisPass; length -= thisPass; } } - close (fd); + tr_sys_file_close (fd, NULL); } -#endif - return success; } - -/* portability wrapper for fsync (). */ -int -tr_fsync (int fd) -{ -#ifdef _WIN32 - return _commit (fd); -#else - return fsync (fd); -#endif -} - - -/* Like pread and pwrite, except that the position is undefined afterwards. - And of course they are not thread-safe. */ - -/* don't use pread/pwrite on old versions of uClibc because they're buggy. - * https://trac.transmissionbt.com/ticket/3826 */ -#ifdef __UCLIBC__ -#define TR_UCLIBC_CHECK_VERSION(major,minor,micro) \ - (__UCLIBC_MAJOR__ > (major) || \ - (__UCLIBC_MAJOR__ == (major) && __UCLIBC_MINOR__ > (minor)) || \ - (__UCLIBC_MAJOR__ == (major) && __UCLIBC_MINOR__ == (minor) && \ - __UCLIBC_SUBLEVEL__ >= (micro))) -#if !TR_UCLIBC_CHECK_VERSION (0,9,28) - #undef HAVE_PREAD - #undef HAVE_PWRITE -#endif -#endif - -#ifdef __APPLE__ - #define HAVE_PREAD - #define HAVE_PWRITE -#endif - -ssize_t -tr_pread (int fd, void *buf, size_t count, off_t offset) -{ -#ifdef HAVE_PREAD - return pread (fd, buf, count, offset); -#else - const off_t lrc = lseek (fd, offset, SEEK_SET); - if (lrc < 0) - return -1; - return read (fd, buf, count); -#endif -} - -ssize_t -tr_pwrite (int fd, const void *buf, size_t count, off_t offset) -{ -#ifdef HAVE_PWRITE - return pwrite (fd, buf, count, offset); -#else - const off_t lrc = lseek (fd, offset, SEEK_SET); - if (lrc < 0) - return -1; - return write (fd, buf, count); -#endif -} - -int -tr_prefetch (int fd UNUSED, off_t offset UNUSED, size_t count UNUSED) -{ -#ifdef HAVE_POSIX_FADVISE - return posix_fadvise (fd, offset, count, POSIX_FADV_WILLNEED); -#elif defined (__APPLE__) - struct radvisory radv; - radv.ra_offset = offset; - radv.ra_count = count; - return fcntl (fd, F_RDADVISE, &radv); -#else - return 0; -#endif -} - -void -tr_set_file_for_single_pass (int fd) -{ - if (fd >= 0) - { - /* Set hints about the lookahead buffer and caching. It's okay - for these to fail silently, so don't let them affect errno */ - const int err = errno; -#ifdef HAVE_POSIX_FADVISE - posix_fadvise (fd, 0, 0, POSIX_FADV_SEQUENTIAL); -#endif -#ifdef __APPLE__ - fcntl (fd, F_RDAHEAD, 1); - fcntl (fd, F_NOCACHE, 1); -#endif - errno = err; - } -} - -static int -open_local_file (const char * filename, int flags) -{ - const int fd = open (filename, flags, 0666); - tr_set_file_for_single_pass (fd); - return fd; -} -int -tr_open_file_for_writing (const char * filename) -{ - return open_local_file (filename, O_LARGEFILE|O_BINARY|O_CREAT|O_WRONLY); -} -int -tr_open_file_for_scanning (const char * filename) -{ - return open_local_file (filename, O_LARGEFILE|O_BINARY|O_SEQUENTIAL|O_RDONLY); -} - -void -tr_close_file (int fd) -{ - close (fd); -} - /***** ****** ****** @@ -296,7 +101,7 @@ tr_close_file (int fd) struct tr_cached_file { bool is_writable; - int fd; + tr_sys_file_t fd; int torrent_id; tr_file_index_t file_index; time_t used_at; @@ -307,7 +112,7 @@ cached_file_is_open (const struct tr_cached_file * o) { assert (o != NULL); - return o->fd >= 0; + return o->fd != TR_BAD_SYS_FILE; } static void @@ -315,14 +120,14 @@ cached_file_close (struct tr_cached_file * o) { assert (cached_file_is_open (o)); - tr_close_file (o->fd); - o->fd = -1; + tr_sys_file_close (o->fd, NULL); + o->fd = TR_BAD_SYS_FILE; } /** * returns 0 on success, or an errno value on failure. * errno values include ENOENT if the parent folder doesn't exist, - * plus the errno values set by tr_mkdirp () and open (). + * plus the errno values set by tr_mkdirp () and tr_sys_file_open (). */ static int cached_file_open (struct tr_cached_file * o, @@ -335,6 +140,7 @@ cached_file_open (struct tr_cached_file * o, tr_sys_path_info info; bool already_existed; bool resize_needed; + tr_error * error = NULL; /* create subfolders, if any */ if (writable) @@ -361,14 +167,15 @@ cached_file_open (struct tr_cached_file * o, writable |= resize_needed; /* open the file */ - flags = writable ? (O_RDWR | O_CREAT) : O_RDONLY; - flags |= O_LARGEFILE | O_BINARY | O_SEQUENTIAL; - o->fd = open (filename, flags, 0666); + flags = writable ? (TR_SYS_FILE_WRITE | TR_SYS_FILE_CREATE) : 0; + flags |= TR_SYS_FILE_READ | TR_SYS_FILE_SEQUENTIAL; + o->fd = tr_sys_file_open (filename, flags, 0666, &error); - if (o->fd == -1) + if (o->fd == TR_BAD_SYS_FILE) { - const int err = errno; - tr_logAddError (_("Couldn't open \"%1$s\": %2$s"), filename, tr_strerror (err)); + const int err = error->code; + tr_logAddError (_("Couldn't open \"%1$s\": %2$s"), filename, error->message); + tr_error_free (error); return err; } @@ -378,21 +185,17 @@ cached_file_open (struct tr_cached_file * o, * http://trac.transmissionbt.com/ticket/2228 * https://bugs.launchpad.net/ubuntu/+source/transmission/+bug/318249 */ - if (resize_needed && (ftruncate (o->fd, file_size) == -1)) + if (resize_needed && !tr_sys_file_truncate (o->fd, file_size, &error)) { - const int err = errno; - tr_logAddError (_("Couldn't truncate \"%1$s\": %2$s"), filename, tr_strerror (err)); + const int err = error->code; + tr_logAddError (_("Couldn't truncate \"%1$s\": %2$s"), filename, error->message); + tr_error_free (error); return err; } if (writable && !already_existed && (allocation == TR_PREALLOCATE_SPARSE)) preallocate_file_sparse (o->fd, file_size); - /* Many (most?) clients request blocks in ascending order, - * so increase the readahead buffer. - * Also, disable OS-level caching because "inactive memory" angers users. */ - tr_set_file_for_single_pass (o->fd); - return 0; } @@ -410,7 +213,7 @@ static void fileset_construct (struct tr_fileset * set, int n) { struct tr_cached_file * o; - const struct tr_cached_file TR_CACHED_FILE_INIT = { 0, -1, 0, 0, 0 }; + const struct tr_cached_file TR_CACHED_FILE_INIT = { false, TR_BAD_SYS_FILE, 0, 0, 0 }; set->begin = tr_new (struct tr_cached_file, n); set->end = set->begin + n; @@ -567,39 +370,33 @@ tr_fdFileClose (tr_session * s, const tr_torrent * tor, tr_file_index_t i) /* flush writable files so that their mtimes will be * up-to-date when this function returns to the caller... */ if (o->is_writable) - tr_fsync (o->fd); + tr_sys_file_flush (o->fd, NULL); cached_file_close (o); } } -int +tr_sys_file_t tr_fdFileGetCached (tr_session * s, int torrent_id, tr_file_index_t i, bool writable) { struct tr_cached_file * o = fileset_lookup (get_fileset (s), torrent_id, i); if (!o || (writable && !o->is_writable)) - return -1; + return TR_BAD_SYS_FILE; o->used_at = tr_time (); return o->fd; } -#ifdef __APPLE__ - #define TR_STAT_MTIME(sb)((sb).st_mtimespec.tv_sec) -#else - #define TR_STAT_MTIME(sb)((sb).st_mtime) -#endif - bool tr_fdFileGetCachedMTime (tr_session * s, int torrent_id, tr_file_index_t i, time_t * mtime) { bool success; - struct stat sb; + tr_sys_path_info info; struct tr_cached_file * o = fileset_lookup (get_fileset (s), torrent_id, i); - if ((success = (o != NULL) && !fstat (o->fd, &sb))) - *mtime = TR_STAT_MTIME (sb); + if ((success = (o != NULL) && tr_sys_file_get_info (o->fd, &info, NULL))) + *mtime = info.last_modified_at; return success; } @@ -612,8 +409,8 @@ tr_fdTorrentClose (tr_session * session, int torrent_id) fileset_close_torrent (get_fileset (session), torrent_id); } -/* returns an fd on success, or a -1 on failure and sets errno */ -int +/* returns an fd on success, or a TR_BAD_SYS_FILE on failure and sets errno */ +tr_sys_file_t tr_fdFileCheckout (tr_session * session, int torrent_id, tr_file_index_t i, @@ -636,7 +433,7 @@ tr_fdFileCheckout (tr_session * session, if (err) { errno = err; - return -1; + return TR_BAD_SYS_FILE; } dbgmsg ("opened '%s' writable %c", filename, writable?'y':'n'); diff --git a/libtransmission/fdlimit.h b/libtransmission/fdlimit.h index f1cb9bd5f..6f3545098 100644 --- a/libtransmission/fdlimit.h +++ b/libtransmission/fdlimit.h @@ -12,6 +12,7 @@ #endif #include "transmission.h" +#include "file.h" #include "net.h" /** @@ -23,21 +24,6 @@ **** ***/ -void tr_set_file_for_single_pass (int fd); - -int tr_open_file_for_scanning (const char * filename); - -int tr_open_file_for_writing (const char * filename); - -void tr_close_file (int fd); - -int tr_fsync (int fd); - -ssize_t tr_pread (int fd, void *buf, size_t count, off_t offset); -ssize_t tr_pwrite (int fd, const void *buf, size_t count, off_t offset); -int tr_prefetch (int fd, off_t offset, size_t count); - - /** * Returns an fd to the specified filename. * @@ -49,22 +35,22 @@ int tr_prefetch (int fd, off_t offset, size_t count); * - if do_write is true, the target file is created if necessary. * * on success, a file descriptor >= 0 is returned. - * on failure, a -1 is returned and errno is set. + * on failure, a TR_BAD_SYS_FILE is returned and errno is set. * * @see tr_fdFileClose */ -int tr_fdFileCheckout (tr_session * session, - int torrent_id, - tr_file_index_t file_num, - const char * filename, - bool do_write, - tr_preallocation_mode preallocation_mode, - uint64_t preallocation_file_size); +tr_sys_file_t tr_fdFileCheckout (tr_session * session, + int torrent_id, + tr_file_index_t file_num, + const char * filename, + bool do_write, + tr_preallocation_mode preallocation_mode, + uint64_t preallocation_file_size); -int tr_fdFileGetCached (tr_session * session, - int torrent_id, - tr_file_index_t file_num, - bool doWrite); +tr_sys_file_t tr_fdFileGetCached (tr_session * session, + int torrent_id, + tr_file_index_t file_num, + bool doWrite); bool tr_fdFileGetCachedMTime (tr_session * session, int torrent_id, diff --git a/libtransmission/inout.c b/libtransmission/inout.c index 50b017f63..63bd1874a 100644 --- a/libtransmission/inout.c +++ b/libtransmission/inout.c @@ -16,7 +16,9 @@ #include "transmission.h" #include "cache.h" /* tr_cacheReadBlock () */ +#include "error.h" #include "fdlimit.h" +#include "file.h" #include "inout.h" #include "log.h" #include "peer-common.h" /* MAX_BLOCK_SIZE */ @@ -46,7 +48,7 @@ readOrWriteBytes (tr_session * session, void * buf, size_t buflen) { - int fd; + tr_sys_file_t fd; int err = 0; const bool doWrite = ioMode >= TR_IO_WRITE; const tr_info * const info = &tor->info; @@ -64,7 +66,7 @@ readOrWriteBytes (tr_session * session, ***/ fd = tr_fdFileGetCached (session, tr_torrentId (tor), fileIndex, doWrite); - if (fd < 0) + if (fd == TR_BAD_SYS_FILE) { /* it's not cached, so open/create it now */ char * subpath; @@ -94,7 +96,7 @@ readOrWriteBytes (tr_session * session, : tor->session->preallocationMode; if (((fd = tr_fdFileCheckout (session, tor->uniqueId, fileIndex, filename, doWrite, - prealloc, file->length))) < 0) + prealloc, file->length))) == TR_BAD_SYS_FILE) { err = errno; tr_logAddTorErr (tor, "tr_fdFileCheckout failed for \"%s\": %s", @@ -118,27 +120,29 @@ readOrWriteBytes (tr_session * session, if (!err) { + tr_error * error = NULL; + if (ioMode == TR_IO_READ) { - const int rc = tr_pread (fd, buf, buflen, fileOffset); - if (rc < 0) + if (!tr_sys_file_read_at (fd, buf, buflen, fileOffset, NULL, &error)) { - err = errno; - tr_logAddTorErr (tor, "read failed for \"%s\": %s", file->name, tr_strerror (err)); + err = error->code; + tr_logAddTorErr (tor, "read failed for \"%s\": %s", file->name, error->message); + tr_error_free (error); } } else if (ioMode == TR_IO_WRITE) { - const int rc = tr_pwrite (fd, buf, buflen, fileOffset); - if (rc < 0) + if (!tr_sys_file_write_at (fd, buf, buflen, fileOffset, NULL, &error)) { - err = errno; - tr_logAddTorErr (tor, "write failed for \"%s\": %s", file->name, tr_strerror (err)); + err = error->code; + tr_logAddTorErr (tor, "write failed for \"%s\": %s", file->name, error->message); + tr_error_free (error); } } else if (ioMode == TR_IO_PREFETCH) { - tr_prefetch (fd, fileOffset, buflen); + tr_sys_file_prefetch (fd, fileOffset, buflen, NULL); } else { diff --git a/libtransmission/libtransmission-test.c b/libtransmission/libtransmission-test.c index 5d0a04e75..480e36baf 100644 --- a/libtransmission/libtransmission-test.c +++ b/libtransmission/libtransmission-test.c @@ -14,6 +14,7 @@ #include #include "transmission.h" +#include "error.h" #include "file.h" #include "platform.h" /* TR_PATH_DELIMETER */ #include "torrent.h" @@ -373,7 +374,7 @@ libttest_zero_torrent_populate (tr_torrent * tor, bool complete) { int err; uint64_t j; - FILE * fp; + tr_sys_file_t fd; char * path; char * dirname; const tr_file * file = &tor->info.files[i]; @@ -384,10 +385,10 @@ libttest_zero_torrent_populate (tr_torrent * tor, bool complete) path = tr_strdup_printf ("%s%c%s", tor->currentDir, TR_PATH_DELIMITER, file->name); dirname = tr_sys_path_dirname (path, NULL); tr_mkdirp (dirname, 0700); - fp = fopen (path, "wb+"); + fd = tr_sys_file_open (path, TR_SYS_FILE_WRITE | TR_SYS_FILE_CREATE | TR_SYS_FILE_TRUNCATE, 0600, NULL); for (j=0; jlength; ++j) - fputc (((!complete) && (i==0) && (jinfo.pieceSize)) ? '\1' : '\0', fp); - fclose (fp); + tr_sys_file_write (fd, ((!complete) && (i==0) && (jinfo.pieceSize)) ? "\1" : "\0", 1, NULL, NULL); + tr_sys_file_close (fd, NULL); tr_free (dirname); tr_free (path); @@ -450,15 +451,14 @@ build_parent_dir (const char* path) void libtest_create_file_with_contents (const char* path, const void* payload, size_t n) { - FILE * fp; + tr_sys_file_t fd; const int tmperr = errno; build_parent_dir (path); - tr_sys_path_remove (path, NULL); - fp = fopen (path, "wb"); - fwrite (payload, 1, n, fp); - fclose (fp); + fd = tr_sys_file_open (path, TR_SYS_FILE_WRITE | TR_SYS_FILE_CREATE | TR_SYS_FILE_TRUNCATE, 0600, NULL); + tr_sys_file_write (fd, payload, n, NULL, NULL); + tr_sys_file_close (fd, NULL); sync (); @@ -474,24 +474,26 @@ libtest_create_file_with_string_contents (const char * path, const char* str) void libtest_create_tmpfile_with_contents (char* tmpl, const void* payload, size_t n) { - int fd; + tr_sys_file_t fd; const int tmperr = errno; - size_t n_left = n; + uint64_t n_left = n; + tr_error * error = NULL; build_parent_dir (tmpl); - fd = mkstemp (tmpl); + fd = tr_sys_file_open_temp (tmpl, NULL); while (n_left > 0) { - const ssize_t n = write (fd, payload, n_left); - if (n == -1) + uint64_t n; + if (!tr_sys_file_write (fd, payload, n_left, &n, &error)) { - fprintf (stderr, "Error writing '%s': %s\n", tmpl, tr_strerror(errno)); + fprintf (stderr, "Error writing '%s': %s\n", tmpl, error->message); + tr_error_free (error); break; } n_left -= n; } - close (fd); + tr_sys_file_close (fd, NULL); sync (); diff --git a/libtransmission/makemeta.c b/libtransmission/makemeta.c index fca91f12c..17bdbab42 100644 --- a/libtransmission/makemeta.c +++ b/libtransmission/makemeta.c @@ -9,11 +9,9 @@ #include #include -#include /* FILE, stderr */ #include /* qsort */ #include /* strcmp, strlen */ -#include /* read () */ #include #include /* evutil_ascii_strcasecmp () */ @@ -21,7 +19,6 @@ #include "transmission.h" #include "crypto.h" /* tr_sha1 */ #include "error.h" -#include "fdlimit.h" /* tr_open_file_for_scanning () */ #include "file.h" #include "log.h" #include "session.h" @@ -228,7 +225,8 @@ getHashInfo (tr_metainfo_builder * b) uint8_t *buf; uint64_t totalRemain; uint64_t off = 0; - int fd; + tr_sys_file_t fd; + tr_error * error = NULL; if (!b->totalSize) return ret; @@ -236,16 +234,18 @@ getHashInfo (tr_metainfo_builder * b) buf = tr_valloc (b->pieceSize); b->pieceIndex = 0; totalRemain = b->totalSize; - fd = tr_open_file_for_scanning (b->files[fileIndex].filename); - if (fd < 0) + fd = tr_sys_file_open (b->files[fileIndex].filename, TR_SYS_FILE_READ | + TR_SYS_FILE_SEQUENTIAL, 0, &error); + if (fd == TR_BAD_SYS_FILE) { - b->my_errno = errno; + b->my_errno = error->code; tr_strlcpy (b->errfile, b->files[fileIndex].filename, sizeof (b->errfile)); b->result = TR_MAKEMETA_IO_READ; tr_free (buf); tr_free (ret); + tr_error_free (error); return NULL; } @@ -253,34 +253,37 @@ getHashInfo (tr_metainfo_builder * b) { uint8_t * bufptr = buf; const uint32_t thisPieceSize = (uint32_t) MIN (b->pieceSize, totalRemain); - uint32_t leftInPiece = thisPieceSize; + uint64_t leftInPiece = thisPieceSize; assert (b->pieceIndex < b->pieceCount); while (leftInPiece) { - const size_t n_this_pass = (size_t) MIN ((b->files[fileIndex].size - off), leftInPiece); - const ssize_t n_read = read (fd, bufptr, n_this_pass); + const uint64_t n_this_pass = MIN (b->files[fileIndex].size - off, leftInPiece); + uint64_t n_read = 0; + tr_sys_file_read (fd, bufptr, n_this_pass, &n_read, NULL); bufptr += n_read; off += n_read; leftInPiece -= n_read; if (off == b->files[fileIndex].size) { off = 0; - tr_close_file (fd); - fd = -1; + tr_sys_file_close (fd, NULL); + fd = TR_BAD_SYS_FILE; if (++fileIndex < b->fileCount) { - fd = tr_open_file_for_scanning (b->files[fileIndex].filename); - if (fd < 0) + fd = tr_sys_file_open (b->files[fileIndex].filename, TR_SYS_FILE_READ | + TR_SYS_FILE_SEQUENTIAL, 0, &error); + if (fd == TR_BAD_SYS_FILE) { - b->my_errno = errno; + b->my_errno = error->code; tr_strlcpy (b->errfile, b->files[fileIndex].filename, sizeof (b->errfile)); b->result = TR_MAKEMETA_IO_READ; tr_free (buf); tr_free (ret); + tr_error_free (error); return NULL; } } @@ -306,8 +309,8 @@ getHashInfo (tr_metainfo_builder * b) || (walk - ret == (int)(SHA_DIGEST_LENGTH * b->pieceCount))); assert (b->abortFlag || !totalRemain); - if (fd >= 0) - tr_close_file (fd); + if (fd != TR_BAD_SYS_FILE) + tr_sys_file_close (fd, NULL); tr_free (buf); return ret; diff --git a/libtransmission/platform.c b/libtransmission/platform.c index a03e61cf8..c2f9582bf 100644 --- a/libtransmission/platform.c +++ b/libtransmission/platform.c @@ -565,123 +565,3 @@ tr_getWebClientDir (const tr_session * session UNUSED) return s; } - - -#ifdef _WIN32 - -/* The following mmap functions are by Joerg Walter, and were taken from - * his paper at: http://www.genesys-e.de/jwalter/mix4win.htm */ - -#if defined (_MSC_VER) -__declspec (align (4)) static LONG volatile g_sl; -#else -static LONG volatile g_sl __attribute__((aligned (4))); -#endif - -/* Wait for spin lock */ -static int -slwait (LONG volatile *sl) -{ - while (InterlockedCompareExchange (sl, 1, 0) != 0) - Sleep (0); - - return 0; -} - -/* Release spin lock */ -static int -slrelease (LONG volatile *sl) -{ - InterlockedExchange (sl, 0); - return 0; -} - -/* getpagesize for windows */ -static long -getpagesize (void) -{ - static long g_pagesize = 0; - - if (!g_pagesize) - { - SYSTEM_INFO system_info; - GetSystemInfo (&system_info); - g_pagesize = system_info.dwPageSize; - } - - return g_pagesize; -} - -static long -getregionsize (void) -{ - static long g_regionsize = 0; - - if (!g_regionsize) - { - SYSTEM_INFO system_info; - GetSystemInfo (&system_info); - g_regionsize = system_info.dwAllocationGranularity; - } - - return g_regionsize; -} - -void * -mmap (void *ptr, long size, long prot, long type, long handle, long arg) -{ - static long g_pagesize; - static long g_regionsize; - - /* Wait for spin lock */ - slwait (&g_sl); - - /* First time initialization */ - if (!g_pagesize) - g_pagesize = getpagesize (); - if (!g_regionsize) - g_regionsize = getregionsize (); - - /* Allocate this */ - ptr = VirtualAlloc (ptr, size, MEM_RESERVE | MEM_COMMIT | MEM_TOP_DOWN, PAGE_READWRITE); - if (!ptr) - { - ptr = (void *) -1; - goto mmap_exit; - } - -mmap_exit: - /* Release spin lock */ - slrelease (&g_sl); - return ptr; -} - -long -munmap (void *ptr, long size) -{ - static long g_pagesize; - static long g_regionsize; - int rc = -1; - - /* Wait for spin lock */ - slwait (&g_sl); - - /* First time initialization */ - if (!g_pagesize) - g_pagesize = getpagesize (); - if (!g_regionsize) - g_regionsize = getregionsize (); - - /* Free this */ - if (!VirtualFree (ptr, 0, MEM_RELEASE)) - goto munmap_exit; - - rc = 0; - -munmap_exit: - /* Release spin lock */ - slrelease (&g_sl); - return rc; -} - -#endif diff --git a/libtransmission/platform.h b/libtransmission/platform.h index 90fe58899..f1f112ebc 100644 --- a/libtransmission/platform.h +++ b/libtransmission/platform.h @@ -77,12 +77,6 @@ void tr_lockUnlock (tr_lock *); /** @brief return nonzero if the specified lock is locked */ int tr_lockHave (const tr_lock *); -#ifdef _WIN32 -void * mmap (void *ptr, long size, long prot, long type, long handle, long arg); - -long munmap (void *ptr, long size); -#endif - /* @} */ #endif diff --git a/libtransmission/rpc-server.c b/libtransmission/rpc-server.c index 20da6943b..de7516fd2 100644 --- a/libtransmission/rpc-server.c +++ b/libtransmission/rpc-server.c @@ -11,8 +11,6 @@ #include #include /* memcpy */ -#include /* close */ - #include #include diff --git a/libtransmission/rpcimpl.c b/libtransmission/rpcimpl.c index 4fdf45cef..fab0a207f 100644 --- a/libtransmission/rpcimpl.c +++ b/libtransmission/rpcimpl.c @@ -19,6 +19,7 @@ #include "transmission.h" #include "completion.h" +#include "error.h" #include "fdlimit.h" #include "file.h" #include "log.h" @@ -1487,13 +1488,14 @@ gotNewBlocklist (tr_session * session, } else /* successfully fetched the blocklist... */ { - int fd; + tr_sys_file_t fd; int err; char * filename; z_stream stream; const char * configDir = tr_sessionGetConfigDir (session); const size_t buflen = 1024 * 128; /* 128 KiB buffer */ uint8_t * buf = tr_valloc (buflen); + tr_error * error = NULL; /* this is an odd Magic Number required by zlib to enable gz support. See zlib's inflateInit2 () documentation for a full description */ @@ -1506,10 +1508,13 @@ gotNewBlocklist (tr_session * session, stream.avail_in = response_byte_count; inflateInit2 (&stream, windowBits); - filename = tr_buildPath (configDir, "blocklist.tmp", NULL); - fd = tr_open_file_for_writing (filename); - if (fd < 0) - tr_snprintf (result, sizeof (result), _("Couldn't save file \"%1$s\": %2$s"), filename, tr_strerror (errno)); + filename = tr_buildPath (configDir, "blocklist.tmp.XXXXXX", NULL); + fd = tr_sys_file_open_temp (filename, &error); + if (fd == TR_BAD_SYS_FILE) + { + tr_snprintf (result, sizeof (result), _("Couldn't save file \"%1$s\": %2$s"), filename, error->message); + tr_error_clear (&error); + } for (;;) { @@ -1519,10 +1524,10 @@ gotNewBlocklist (tr_session * session, if (stream.avail_out < buflen) { - const int e = write (fd, buf, buflen - stream.avail_out); - if (e < 0) + if (!tr_sys_file_write (fd, buf, buflen - stream.avail_out, NULL, &error)) { - tr_snprintf (result, sizeof (result), _("Couldn't save file \"%1$s\": %2$s"), filename, tr_strerror (errno)); + tr_snprintf (result, sizeof (result), _("Couldn't save file \"%1$s\": %2$s"), filename, error->message); + tr_error_clear (&error); break; } } @@ -1538,10 +1543,13 @@ gotNewBlocklist (tr_session * session, inflateEnd (&stream); if (err == Z_DATA_ERROR) /* couldn't inflate it... it's probably already uncompressed */ - if (write (fd, response, response_byte_count) < 0) - tr_snprintf (result, sizeof (result), _("Couldn't save file \"%1$s\": %2$s"), filename, tr_strerror (errno)); + if (!tr_sys_file_write (fd, response, response_byte_count, NULL, &error)) + { + tr_snprintf (result, sizeof (result), _("Couldn't save file \"%1$s\": %2$s"), filename, error->message); + tr_error_clear (&error); + } - tr_close_file(fd); + tr_sys_file_close (fd, NULL); if (*result) { diff --git a/libtransmission/torrent-magnet.c b/libtransmission/torrent-magnet.c index e7730b832..cad15ead4 100644 --- a/libtransmission/torrent-magnet.c +++ b/libtransmission/torrent-magnet.c @@ -155,19 +155,19 @@ tr_torrentGetMetadataPiece (tr_torrent * tor, int piece, int * len) if (tr_torrentHasMetadata (tor)) { - FILE * fp; + tr_sys_file_t fd; ensureInfoDictOffsetIsCached (tor); assert (tor->infoDictLength > 0); assert (tor->infoDictOffset >= 0); - fp = fopen (tor->info.torrent, "rb"); - if (fp != NULL) + fd = tr_sys_file_open (tor->info.torrent, TR_SYS_FILE_READ, 0, NULL); + if (fd != TR_BAD_SYS_FILE) { const int o = piece * METADATA_PIECE_SIZE; - if (!fseek (fp, tor->infoDictOffset + o, SEEK_SET)) + if (tr_sys_file_seek (fd, tor->infoDictOffset + o, TR_SEEK_SET, NULL, NULL)) { const int l = o + METADATA_PIECE_SIZE <= tor->infoDictLength ? METADATA_PIECE_SIZE @@ -176,8 +176,8 @@ tr_torrentGetMetadataPiece (tr_torrent * tor, int piece, int * len) if (0 #include /* strerror (), memset (), memmem () */ #include /* nanosleep () */ +#include +#include #ifdef HAVE_ICONV_OPEN #include #endif #include -#include -#include -#include /* stat (), getpagesize () */ +#include /* getpagesize () */ #include #include @@ -48,7 +48,6 @@ #include "transmission.h" #include "error.h" -#include "fdlimit.h" #include "file.h" #include "ConvertUTF.h" #include "list.h" @@ -221,8 +220,7 @@ tr_loadFile (const char * path, { uint8_t * buf; tr_sys_path_info info; - int fd; - ssize_t n; + tr_sys_file_t fd; tr_error * error = NULL; const char * const err_fmt = _("Couldn't read \"%1$s\": %2$s"); @@ -248,11 +246,12 @@ tr_loadFile (const char * path, assert (info.size <= SIZE_MAX); /* Load the torrent file into our buffer */ - fd = tr_open_file_for_scanning (path); - if (fd < 0) + fd = tr_sys_file_open (path, TR_SYS_FILE_READ | TR_SYS_FILE_SEQUENTIAL, 0, &error); + if (fd == TR_BAD_SYS_FILE) { - const int err = errno; - tr_logAddError (err_fmt, path, tr_strerror (errno)); + const int err = error->code; + tr_logAddError (err_fmt, path, error->message); + tr_error_free (error); errno = err; return NULL; } @@ -261,22 +260,22 @@ tr_loadFile (const char * path, { const int err = errno; tr_logAddError (err_fmt, path, _("Memory allocation failed")); - tr_close_file (fd); + tr_sys_file_close (fd, NULL); errno = err; return NULL; } - n = read (fd, buf, (size_t)info.size); - if (n == -1) + if (!tr_sys_file_read (fd, buf, info.size, NULL, &error)) { - const int err = errno; - tr_logAddError (err_fmt, path, tr_strerror (errno)); - tr_close_file (fd); + const int err = error->code; + tr_logAddError (err_fmt, path, error->message); + tr_sys_file_close (fd, NULL); free (buf); + tr_error_free (error); errno = err; return NULL; } - tr_close_file (fd); + tr_sys_file_close (fd, NULL); buf[info.size] = '\0'; *size = info.size; return buf; @@ -1544,11 +1543,11 @@ tr_strratio (char * buf, size_t buflen, double ratio, const char * infinity) int tr_moveFile (const char * oldpath, const char * newpath, bool * renamed) { - int in; - int out; + tr_sys_file_t in; + tr_sys_file_t out; char * buf; tr_sys_path_info info; - off_t bytesLeft; + uint64_t bytesLeft; const size_t buflen = 1024 * 128; /* 128 KiB buffer */ tr_error * error = NULL; @@ -1586,26 +1585,24 @@ tr_moveFile (const char * oldpath, const char * newpath, bool * renamed) } /* copy the file */ - in = tr_open_file_for_scanning (oldpath); - out = tr_open_file_for_writing (newpath); + in = tr_sys_file_open (oldpath, TR_SYS_FILE_READ | TR_SYS_FILE_SEQUENTIAL, 0, NULL); + out = tr_sys_file_open (newpath, TR_SYS_FILE_WRITE | TR_SYS_FILE_CREATE | TR_SYS_FILE_TRUNCATE, 0666, NULL); buf = tr_valloc (buflen); while (bytesLeft > 0) { - ssize_t bytesWritten; - const off_t bytesThisPass = MIN (bytesLeft, (off_t)buflen); - const int numRead = read (in, buf, bytesThisPass); - if (numRead < 0) + const uint64_t bytesThisPass = MIN (bytesLeft, buflen); + uint64_t numRead, bytesWritten; + if (!tr_sys_file_read (in, buf, bytesThisPass, &numRead, NULL)) break; - bytesWritten = write (out, buf, numRead); - if (bytesWritten < 0) + if (!tr_sys_file_write (out, buf, numRead, &bytesWritten, NULL)) break; bytesLeft -= bytesWritten; } /* cleanup */ tr_free (buf); - tr_close_file (out); - tr_close_file (in); + tr_sys_file_close (out, NULL); + tr_sys_file_close (in, NULL); if (bytesLeft != 0) return -1; diff --git a/libtransmission/variant.c b/libtransmission/variant.c index 45e33490d..3f17ab719 100644 --- a/libtransmission/variant.c +++ b/libtransmission/variant.c @@ -9,24 +9,20 @@ #include #include -#include /* strtod(), realloc(), qsort(), mkstemp() */ +#include /* strtod(), realloc(), qsort() */ #include -#ifdef _WIN32 /* tr_mkstemp() */ - #include +#ifdef _WIN32 #include - #include #endif #include /* setlocale() */ -#include /* write() */ #include #define __LIBTRANSMISSION_VARIANT_MODULE___ #include "transmission.h" #include "ConvertUTF.h" -#include "fdlimit.h" /* tr_close_file() */ #include "error.h" #include "file.h" #include "log.h" @@ -1125,55 +1121,28 @@ tr_variantToStr (const tr_variant * v, tr_variant_fmt fmt, int * len) return ret; } -/* portability wrapper for mkstemp(). */ -static int -tr_mkstemp (char * template) -{ -#ifdef _WIN32 - - const int n = strlen (template) + 1; - const int flags = O_RDWR | O_BINARY | O_CREAT | O_EXCL | _O_SHORT_LIVED; - const mode_t mode = _S_IREAD | _S_IWRITE; - wchar_t templateUTF16[n]; - - if (MultiByteToWideChar(CP_UTF8, 0, template, -1, templateUTF16, n)) - { - _wmktemp(templateUTF16); - WideCharToMultiByte(CP_UTF8, 0, templateUTF16, -1, template, n, NULL, NULL); - return _wopen(chkFilename(templateUTF16), flags, mode); - } - errno = EINVAL; - return -1; - -#else - - return mkstemp (template); - -#endif -} - int tr_variantToFile (const tr_variant * v, tr_variant_fmt fmt, const char * filename) { char * tmp; - int fd; + tr_sys_file_t fd; int err = 0; char * real_filename; + tr_error * error = NULL; /* follow symlinks to find the "real" file, to make sure the temporary - * we build with tr_mkstemp() is created on the right partition */ + * we build with tr_sys_file_open_temp() is created on the right partition */ if ((real_filename = tr_sys_path_resolve (filename, NULL)) != NULL) filename = real_filename; /* if the file already exists, try to move it out of the way & keep it as a backup */ tmp = tr_strdup_printf ("%s.tmp.XXXXXX", filename); - fd = tr_mkstemp (tmp); - tr_set_file_for_single_pass (fd); - if (fd >= 0) + fd = tr_sys_file_open_temp (tmp, &error); + if (fd != TR_BAD_SYS_FILE) { - int nleft; + uint64_t nleft; /* save the variant to a temporary file */ { @@ -1183,34 +1152,31 @@ tr_variantToFile (const tr_variant * v, while (nleft > 0) { - const int n = write (fd, walk, nleft); - if (n >= 0) + uint64_t n; + if (!tr_sys_file_write (fd, walk, nleft, &n, &error)) { - nleft -= n; - walk += n; - } - else if (errno != EAGAIN) - { - err = errno; + err = error->code; break; } + + nleft -= n; + walk += n; } evbuffer_free (buf); } + tr_sys_file_close (fd, NULL); + if (nleft > 0) { - tr_logAddError (_("Couldn't save temporary file \"%1$s\": %2$s"), tmp, tr_strerror (err)); - tr_close_file (fd); + tr_logAddError (_("Couldn't save temporary file \"%1$s\": %2$s"), tmp, error->message); tr_sys_path_remove (tmp, NULL); + tr_error_free (error); } else { - tr_error * error = NULL; - - tr_close_file (fd); - + tr_error_clear (&error); if (tr_sys_path_rename (tmp, filename, &error)) { tr_logAddInfo (_("Saved \"%s\""), filename); @@ -1226,8 +1192,9 @@ tr_variantToFile (const tr_variant * v, } else { - err = errno; - tr_logAddError (_("Couldn't save temporary file \"%1$s\": %2$s"), tmp, tr_strerror (err)); + err = error->code; + tr_logAddError (_("Couldn't save temporary file \"%1$s\": %2$s"), tmp, error->message); + tr_error_free (error); } tr_free (tmp); diff --git a/libtransmission/verify.c b/libtransmission/verify.c index 6185fe246..fcab02306 100644 --- a/libtransmission/verify.c +++ b/libtransmission/verify.c @@ -19,7 +19,7 @@ #include "transmission.h" #include "completion.h" -#include "fdlimit.h" +#include "file.h" #include "list.h" #include "log.h" #include "platform.h" /* tr_lock () */ @@ -41,8 +41,8 @@ verifyTorrent (tr_torrent * tor, bool * stopFlag) { time_t end; SHA_CTX sha; - int fd = -1; - int64_t filePos = 0; + tr_sys_file_t fd = TR_BAD_SYS_FILE; + uint64_t filePos = 0; bool changed = 0; bool hadPiece = 0; time_t lastSleptAt = 0; @@ -60,8 +60,8 @@ verifyTorrent (tr_torrent * tor, bool * stopFlag) tr_torrentSetChecked (tor, 0); while (!*stopFlag && (pieceIndex < tor->info.pieceCount)) { - uint32_t leftInPiece; - uint32_t bytesThisPass; + uint64_t leftInPiece; + uint64_t bytesThisPass; uint64_t leftInFile; const tr_file * file = &tor->info.files[fileIndex]; @@ -70,10 +70,11 @@ verifyTorrent (tr_torrent * tor, bool * stopFlag) hadPiece = tr_torrentPieceIsComplete (tor, pieceIndex); /* if we're starting a new file... */ - if (!filePos && (fd<0) && (fileIndex!=prevFileIndex)) + if (filePos == 0 && fd == TR_BAD_SYS_FILE && fileIndex != prevFileIndex) { char * filename = tr_torrentFindFile (tor, fileIndex); - fd = filename == NULL ? -1 : tr_open_file_for_scanning (filename); + fd = filename == NULL ? TR_BAD_SYS_FILE : tr_sys_file_open (filename, + TR_SYS_FILE_READ | TR_SYS_FILE_SEQUENTIAL, 0, NULL); tr_free (filename); prevFileIndex = fileIndex; } @@ -85,12 +86,12 @@ verifyTorrent (tr_torrent * tor, bool * stopFlag) bytesThisPass = MIN (bytesThisPass, buflen); /* read a bit */ - if (fd >= 0) + if (fd != TR_BAD_SYS_FILE) { - const ssize_t numRead = tr_pread (fd, buffer, bytesThisPass, filePos); - if (numRead > 0) + uint64_t numRead; + if (tr_sys_file_read_at (fd, buffer, bytesThisPass, filePos, &numRead, NULL) && numRead > 0) { - bytesThisPass = (uint32_t)numRead; + bytesThisPass = numRead; SHA1_Update (&sha, buffer, bytesThisPass); #if defined HAVE_POSIX_FADVISE && defined POSIX_FADV_DONTNEED posix_fadvise (fd, filePos, bytesThisPass, POSIX_FADV_DONTNEED); @@ -140,10 +141,10 @@ verifyTorrent (tr_torrent * tor, bool * stopFlag) /* if we're finishing a file... */ if (leftInFile == 0) { - if (fd >= 0) + if (fd != TR_BAD_SYS_FILE) { - tr_close_file (fd); - fd = -1; + tr_sys_file_close (fd, NULL); + fd = TR_BAD_SYS_FILE; } fileIndex++; filePos = 0; @@ -151,8 +152,8 @@ verifyTorrent (tr_torrent * tor, bool * stopFlag) } /* cleanup */ - if (fd >= 0) - tr_close_file (fd); + if (fd != TR_BAD_SYS_FILE) + tr_sys_file_close (fd, NULL); free (buffer); /* stopwatch */