diff --git a/libtransmission/blocklist.cc b/libtransmission/blocklist.cc index 6208137b2..69ccd4eae 100644 --- a/libtransmission/blocklist.cc +++ b/libtransmission/blocklist.cc @@ -42,14 +42,14 @@ void BlocklistFile::load() { close(); - auto info = tr_sys_path_info{}; - if (!tr_sys_path_get_info(getFilename(), 0, &info)) + auto const info = tr_sys_path_get_info(getFilename()); + if (!info) { return; } - auto const byteCount = info.size; - if (byteCount == 0) + auto const byte_count = info->size; + if (byte_count == 0) { return; } @@ -67,7 +67,7 @@ void BlocklistFile::load() return; } - rules_ = static_cast(tr_sys_file_map_for_reading(fd, 0, byteCount, &error)); + rules_ = static_cast(tr_sys_file_map_for_reading(fd, 0, byte_count, &error)); if (rules_ == nullptr) { tr_logAddWarn(fmt::format( @@ -81,8 +81,8 @@ void BlocklistFile::load() } fd_ = fd; - byte_count_ = byteCount; - rule_count_ = byteCount / sizeof(IPv4Range); + byte_count_ = byte_count; + rule_count_ = byte_count / sizeof(IPv4Range); tr_logAddInfo(fmt::format( ngettext("Blocklist '{path}' has {count} entry", "Blocklist '{path}' has {count} entries", rule_count_), diff --git a/libtransmission/crypto-utils-openssl.cc b/libtransmission/crypto-utils-openssl.cc index 3df748439..3c2ed28fd 100644 --- a/libtransmission/crypto-utils-openssl.cc +++ b/libtransmission/crypto-utils-openssl.cc @@ -123,7 +123,7 @@ public: unsigned int hash_length = 0; auto digest = DigestType{}; auto* const digest_as_uchar = reinterpret_cast(std::data(digest)); - bool const ok = check_result(EVP_DigestFinal_ex(handle_.get(), digest_as_uchar, &hash_length)); + [[maybe_unused]] bool const ok = check_result(EVP_DigestFinal_ex(handle_.get(), digest_as_uchar, &hash_length)); TR_ASSERT(!ok || hash_length == std::size(digest)); clear(); diff --git a/libtransmission/file-posix.cc b/libtransmission/file-posix.cc index e2abe1f5b..902975028 100644 --- a/libtransmission/file-posix.cc +++ b/libtransmission/file-posix.cc @@ -117,23 +117,27 @@ static void set_system_error_if_file_found(tr_error** error, int code) } } -static void stat_to_sys_path_info(struct stat const* sb, tr_sys_path_info* info) +static constexpr auto stat_to_sys_path_info(struct stat const& sb) { - if (S_ISREG(sb->st_mode)) + auto info = tr_sys_path_info{}; + + if (S_ISREG(sb.st_mode)) { - info->type = TR_SYS_PATH_IS_FILE; + info.type = TR_SYS_PATH_IS_FILE; } - else if (S_ISDIR(sb->st_mode)) + else if (S_ISDIR(sb.st_mode)) { - info->type = TR_SYS_PATH_IS_DIRECTORY; + info.type = TR_SYS_PATH_IS_DIRECTORY; } else { - info->type = TR_SYS_PATH_IS_OTHER; + info.type = TR_SYS_PATH_IS_OTHER; } - info->size = (uint64_t)sb->st_size; - info->last_modified_at = sb->st_mtime; + info.size = static_cast(sb.st_size); + info.last_modified_at = sb.st_mtime; + + return info; } static void set_file_for_single_pass(tr_sys_file_t handle) @@ -299,33 +303,29 @@ bool tr_sys_path_exists(char const* path, tr_error** error) return ret; } -bool tr_sys_path_get_info(char const* path, int flags, tr_sys_path_info* info, tr_error** error) +std::optional tr_sys_path_get_info(std::string_view path, int flags, tr_error** error) { - TR_ASSERT(path != nullptr); - TR_ASSERT(info != nullptr); + struct stat sb = {}; - bool ret = false; - struct stat sb; + bool ok = false; + auto const szpath = tr_pathbuf{ path }; if ((flags & TR_SYS_PATH_NO_FOLLOW) == 0) { - ret = stat(path, &sb) != -1; + ok = stat(szpath, &sb) != -1; } else { - ret = lstat(path, &sb) != -1; + ok = lstat(szpath, &sb) != -1; } - if (ret) + if (ok) { - stat_to_sys_path_info(&sb, info); - } - else - { - set_system_error(error, errno); + return stat_to_sys_path_info(sb); } - return ret; + set_system_error(error, errno); + return {}; } bool tr_sys_path_is_relative(std::string_view path) @@ -486,8 +486,8 @@ bool tr_sys_path_copy(char const* src_path, char const* dst_path, tr_error** err return false; } - tr_sys_path_info info; - if (!tr_sys_file_get_info(in, &info, error)) + auto const info = tr_sys_file_get_info(in, error); + if (!info) { tr_error_prefix(error, "Unable to get information on source file: "); tr_sys_file_close(in); @@ -506,11 +506,11 @@ bool tr_sys_path_copy(char const* src_path, char const* dst_path, tr_error** err return false; } - uint64_t file_size = info.size; + uint64_t file_size = info->size; #if defined(USE_COPY_FILE_RANGE) || defined(USE_SENDFILE64) - while (file_size > 0) + while (file_size > 0U) { size_t const chunk_size = std::min(file_size, uint64_t{ SSIZE_MAX }); ssize_t const copied = @@ -538,12 +538,12 @@ bool tr_sys_path_copy(char const* src_path, char const* dst_path, tr_error** err /* Fallback to user-space copy. */ - size_t const buflen = 1024 * 1024; /* 1024 KiB buffer */ - auto* buf = static_cast(tr_malloc(buflen)); + static auto constexpr Buflen = size_t{ 1024U * 1024U }; /* 1024 KiB buffer */ + auto* buf = static_cast(tr_malloc(Buflen)); - while (file_size > 0) + while (file_size > 0U) { - uint64_t const chunk_size = std::min(file_size, uint64_t{ buflen }); + uint64_t const chunk_size = std::min(file_size, uint64_t{ Buflen }); uint64_t bytes_read; uint64_t bytes_written; @@ -707,24 +707,19 @@ bool tr_sys_file_close(tr_sys_file_t handle, tr_error** error) return ret; } -bool tr_sys_file_get_info(tr_sys_file_t handle, tr_sys_path_info* info, tr_error** error) +std::optional tr_sys_file_get_info(tr_sys_file_t handle, tr_error** error) { TR_ASSERT(handle != TR_BAD_SYS_FILE); - TR_ASSERT(info != nullptr); struct stat sb; - bool const ret = fstat(handle, &sb) != -1; - if (ret) + if (fstat(handle, &sb) != -1) { - stat_to_sys_path_info(&sb, info); - } - else - { - set_system_error(error, errno); + return stat_to_sys_path_info(sb); } - return ret; + set_system_error(error, errno); + return {}; } bool tr_sys_file_seek(tr_sys_file_t handle, int64_t offset, tr_seek_origin_t origin, uint64_t* new_offset, tr_error** error) diff --git a/libtransmission/file-win32.cc b/libtransmission/file-win32.cc index ba310ca79..2c2728550 100644 --- a/libtransmission/file-win32.cc +++ b/libtransmission/file-win32.cc @@ -72,48 +72,42 @@ static void set_system_error_if_file_found(tr_error** error, DWORD code) } } -static time_t filetime_to_unix_time(FILETIME const* t) +static constexpr time_t filetime_to_unix_time(FILETIME const& t) { - TR_ASSERT(t != nullptr); - uint64_t tmp = 0; - tmp |= t->dwHighDateTime; + tmp |= t.dwHighDateTime; tmp <<= 32; - tmp |= t->dwLowDateTime; + tmp |= t.dwLowDateTime; tmp /= 10; /* to microseconds */ tmp -= DELTA_EPOCH_IN_MICROSECS; return tmp / 1000000UL; } -static void stat_to_sys_path_info( - DWORD attributes, - DWORD size_low, - DWORD size_high, - FILETIME const* mtime, - tr_sys_path_info* info) +static constexpr auto stat_to_sys_path_info(DWORD attributes, DWORD size_low, DWORD size_high, FILETIME const& mtime) { - TR_ASSERT(mtime != nullptr); - TR_ASSERT(info != nullptr); + auto info = tr_sys_path_info{}; if ((attributes & FILE_ATTRIBUTE_DIRECTORY) != 0) { - info->type = TR_SYS_PATH_IS_DIRECTORY; + info.type = TR_SYS_PATH_IS_DIRECTORY; } else if ((attributes & (FILE_ATTRIBUTE_DEVICE | FILE_ATTRIBUTE_REPARSE_POINT | FILE_ATTRIBUTE_VIRTUAL)) == 0) { - info->type = TR_SYS_PATH_IS_FILE; + info.type = TR_SYS_PATH_IS_FILE; } else { - info->type = TR_SYS_PATH_IS_OTHER; + info.type = TR_SYS_PATH_IS_OTHER; } - info->size = size_high; - info->size <<= 32; - info->size |= size_low; + info.size = size_high; + info.size <<= 32; + info.size |= size_low; - info->last_modified_at = filetime_to_unix_time(mtime); + info.last_modified_at = filetime_to_unix_time(mtime); + + return info; } static constexpr bool is_slash(char c) @@ -235,6 +229,18 @@ static wchar_t* path_to_native_path(char const* path) return path_to_native_path_ex(path, 0, nullptr); } +static std::wstring path_to_native_path_wstr(std::string_view path) +{ + if (auto* const rawptr = path_to_native_path(tr_pathbuf{ path }); rawptr != nullptr) + { + auto ret = std::wstring{ rawptr }; + tr_free(rawptr); + return ret; + } + + return {}; +} + static char* native_path_to_path(wchar_t const* wide_path) { if (wide_path == nullptr) @@ -423,67 +429,35 @@ bool tr_sys_path_exists(char const* path, tr_error** error) return ret; } -bool tr_sys_path_get_info(char const* path, int flags, tr_sys_path_info* info, tr_error** error) +std::optional tr_sys_path_get_info(std::string_view path, int flags, tr_error** error) { - TR_ASSERT(path != nullptr); - TR_ASSERT(info != nullptr); - - bool ret = false; - wchar_t* wide_path = path_to_native_path(path); - - if ((flags & TR_SYS_PATH_NO_FOLLOW) == 0) + if (auto const wide_path = path_to_native_path_wstr(path); std::empty(wide_path)) { - HANDLE handle = INVALID_HANDLE_VALUE; - - if (wide_path != nullptr) - { - handle = CreateFileW(wide_path, 0, 0, nullptr, OPEN_EXISTING, FILE_FLAG_BACKUP_SEMANTICS, nullptr); - } - - if (handle != INVALID_HANDLE_VALUE) - { - tr_error* my_error = nullptr; - ret = tr_sys_file_get_info(handle, info, &my_error); - - if (!ret) - { - tr_error_propagate(error, &my_error); - } - - CloseHandle(handle); - } - else - { - set_system_error(error, GetLastError()); - } + // do nothing } - else + else if ((flags & TR_SYS_PATH_NO_FOLLOW) != 0) { - WIN32_FILE_ATTRIBUTE_DATA attributes; - - if (wide_path != nullptr) + auto attributes = WIN32_FILE_ATTRIBUTE_DATA{}; + if (GetFileAttributesExW(wide_path.c_str(), GetFileExInfoStandard, &attributes)) { - ret = GetFileAttributesExW(wide_path, GetFileExInfoStandard, &attributes); - } - - if (ret) - { - stat_to_sys_path_info( + return stat_to_sys_path_info( attributes.dwFileAttributes, attributes.nFileSizeLow, attributes.nFileSizeHigh, - &attributes.ftLastWriteTime, - info); - } - else - { - set_system_error(error, GetLastError()); + attributes.ftLastWriteTime); } } + else if (auto const + handle = CreateFileW(wide_path.c_str(), 0, 0, nullptr, OPEN_EXISTING, FILE_FLAG_BACKUP_SEMANTICS, nullptr); + handle != INVALID_HANDLE_VALUE) + { + auto ret = tr_sys_file_get_info(handle, error); + CloseHandle(handle); + return ret; + } - tr_free(wide_path); - - return ret; + set_system_error(error, GetLastError()); + return {}; } bool tr_sys_path_is_relative(std::string_view path) @@ -1071,29 +1045,22 @@ bool tr_sys_file_close(tr_sys_file_t handle, tr_error** error) return ret; } -bool tr_sys_file_get_info(tr_sys_file_t handle, tr_sys_path_info* info, tr_error** error) +std::optional tr_sys_file_get_info(tr_sys_file_t handle, tr_error** error) { TR_ASSERT(handle != TR_BAD_SYS_FILE); - TR_ASSERT(info != nullptr); - BY_HANDLE_FILE_INFORMATION attributes; - bool ret = GetFileInformationByHandle(handle, &attributes); - - if (ret) + auto attributes = BY_HANDLE_FILE_INFORMATION{}; + if (GetFileInformationByHandle(handle, &attributes)) { - stat_to_sys_path_info( + return stat_to_sys_path_info( attributes.dwFileAttributes, attributes.nFileSizeLow, attributes.nFileSizeHigh, - &attributes.ftLastWriteTime, - info); - } - else - { - set_system_error(error, GetLastError()); + attributes.ftLastWriteTime); } - return ret; + set_system_error(error, GetLastError()); + return {}; } bool tr_sys_file_seek(tr_sys_file_t handle, int64_t offset, tr_seek_origin_t origin, uint64_t* new_offset, tr_error** error) diff --git a/libtransmission/file.h b/libtransmission/file.h index faea6b442..83d619fda 100644 --- a/libtransmission/file.h +++ b/libtransmission/file.h @@ -8,9 +8,9 @@ #include // size_t #include // uint64_t #include // time_t +#include #include #include -#include #ifdef _WIN32 #include @@ -117,8 +117,18 @@ enum tr_sys_path_type_t struct tr_sys_path_info { tr_sys_path_type_t type = {}; - uint64_t size = 0; - time_t last_modified_at = 0; + uint64_t size = {}; + time_t last_modified_at = {}; + + [[nodiscard]] constexpr auto isFile() const noexcept + { + return type == TR_SYS_PATH_IS_FILE; + } + + [[nodiscard]] constexpr auto isFolder() const noexcept + { + return type == TR_SYS_PATH_IS_DIRECTORY; + } }; /** @@ -153,13 +163,15 @@ bool tr_sys_path_copy(char const* src_path, char const* dst_path, struct tr_erro * * @param[in] path Path to file or directory. * @param[in] flags Combination of @ref tr_sys_path_get_info_flags_t values. - * @param[out] info Result buffer. * @param[out] error Pointer to error object. Optional, pass `nullptr` if you * are not interested in error details. * - * @return `True` on success, `false` otherwise (with `error` set accordingly). + * @return info on success, or nullopt with `error` set accordingly. */ -bool tr_sys_path_get_info(char const* path, int flags, tr_sys_path_info* info, struct tr_error** error = nullptr); +[[nodiscard]] std::optional tr_sys_path_get_info( + std::string_view path, + int flags = 0, + tr_error** error = nullptr); /** * @brief Portability wrapper for `access()`. @@ -369,13 +381,12 @@ bool tr_sys_file_close(tr_sys_file_t handle, struct tr_error** error = nullptr); * @brief Portability wrapper for `fstat()`. * * @param[in] handle Valid file descriptor. - * @param[out] info Result buffer. * @param[out] error Pointer to error object. Optional, pass `nullptr` if you * are not interested in error details. * - * @return `True` on success, `false` otherwise (with `error` set accordingly). + * @return info on success, or nullopt with `error` set accordingly. */ -bool tr_sys_file_get_info(tr_sys_file_t handle, tr_sys_path_info* info, struct tr_error** error = nullptr); +[[nodiscard]] std::optional tr_sys_file_get_info(tr_sys_file_t handle, struct tr_error** error = nullptr); /** * @brief Portability wrapper for `lseek()`. diff --git a/libtransmission/makemeta.cc b/libtransmission/makemeta.cc index f4a46cd6c..98c15ddd7 100644 --- a/libtransmission/makemeta.cc +++ b/libtransmission/makemeta.cc @@ -54,8 +54,9 @@ static struct FileList* getFiles(std::string_view dir, std::string_view base, st auto buf = tr_pathbuf{ dir, '/', base }; tr_sys_path_native_separators(std::data(buf)); - tr_sys_path_info info; - if (tr_error* error = nullptr; !tr_sys_path_get_info(buf, 0, &info, &error)) + tr_error* error = nullptr; + auto const info = tr_sys_path_get_info(buf, 0, &error); + if (!info) { tr_logAddWarn(fmt::format( _("Skipping '{path}': {error} ({error_code})"), @@ -66,27 +67,36 @@ static struct FileList* getFiles(std::string_view dir, std::string_view base, st return list; } - if (tr_sys_dir_t odir = info.type == TR_SYS_PATH_IS_DIRECTORY ? tr_sys_dir_open(buf.c_str()) : TR_BAD_SYS_DIR; - odir != TR_BAD_SYS_DIR) + switch (info->type) { - char const* name = nullptr; - while ((name = tr_sys_dir_read_name(odir)) != nullptr) + case TR_SYS_PATH_IS_DIRECTORY: + if (auto const odir = tr_sys_dir_open(buf.c_str()); odir != TR_BAD_SYS_DIR) { - if (name[0] != '.') /* skip dotfiles */ + char const* name = nullptr; + while ((name = tr_sys_dir_read_name(odir)) != nullptr) { - list = getFiles(buf.c_str(), name, list); + if (name[0] != '.') /* skip dotfiles */ + { + list = getFiles(buf.c_str(), name, list); + } } - } - tr_sys_dir_close(odir); - } - else if (info.type == TR_SYS_PATH_IS_FILE) - { - auto* const node = tr_new0(FileList, 1); - node->size = info.size; - node->filename = tr_strvDup(buf); - node->next = list; - list = node; + tr_sys_dir_close(odir); + } + break; + + case TR_SYS_PATH_IS_FILE: + { + auto* const node = tr_new0(FileList, 1); + node->size = info->size; + node->filename = tr_strvDup(buf); + node->next = list; + list = node; + } + break; + + default: + break; } return list; @@ -145,10 +155,8 @@ tr_metainfo_builder* tr_metaInfoBuilderCreate(char const* topFileArg) ret->top = real_top; - { - tr_sys_path_info info; - ret->isFolder = tr_sys_path_get_info(ret->top, 0, &info) && info.type == TR_SYS_PATH_IS_DIRECTORY; - } + auto const info = tr_sys_path_get_info(ret->top); + ret->isFolder = info && info->isFolder(); /* build a list of files containing top file and, if it's a directory, all of its children */ diff --git a/libtransmission/open-files.cc b/libtransmission/open-files.cc index 3f7f74c95..93fc5b5be 100644 --- a/libtransmission/open-files.cc +++ b/libtransmission/open-files.cc @@ -167,11 +167,11 @@ std::optional tr_open_files::get( } } - auto info = tr_sys_path_info{}; - bool const already_existed = tr_sys_path_get_info(filename, 0, &info) && info.type == TR_SYS_PATH_IS_FILE; + auto const info = tr_sys_path_get_info(filename); + bool const already_existed = info && info->isFile(); // we need write permissions to resize the file - bool const resize_needed = already_existed && (file_size < info.size); + bool const resize_needed = already_existed && (file_size < info->size); writable |= resize_needed; // open the file diff --git a/libtransmission/session.cc b/libtransmission/session.cc index 47b5b7e86..58a2f7e1f 100644 --- a/libtransmission/session.cc +++ b/libtransmission/session.cc @@ -2045,11 +2045,9 @@ static void sessionLoadTorrents(struct sessionLoadTorrentsData* const data) { TR_ASSERT(tr_isSession(data->session)); - tr_sys_path_info info; auto const& dirname = data->session->torrentDir(); - tr_sys_dir_t odir = (tr_sys_path_get_info(dirname.c_str(), 0, &info) && info.type == TR_SYS_PATH_IS_DIRECTORY) ? - tr_sys_dir_open(dirname.c_str()) : - TR_BAD_SYS_DIR; + auto const info = tr_sys_path_get_info(dirname); + auto const odir = info && info->isFolder() ? tr_sys_dir_open(dirname.c_str()) : TR_BAD_SYS_DIR; auto torrents = std::list{}; if (odir != TR_BAD_SYS_DIR) @@ -2342,7 +2340,7 @@ bool tr_sessionIsPortForwardingEnabled(tr_session const* session) static void loadBlocklists(tr_session* session) { auto loadme = std::unordered_set{}; - auto const isEnabled = session->useBlocklist(); + auto const is_enabled = session->useBlocklist(); /* walk the blocklist directory... */ auto const dirname = tr_pathbuf{ session->configDir(), "/blocklists"sv }; @@ -2369,28 +2367,26 @@ static void loadBlocklists(tr_session* session) } else { - tr_sys_path_info path_info; - tr_sys_path_info binname_info; - auto const binname = tr_pathbuf{ dirname, '/', name, ".bin"sv }; - if (!tr_sys_path_get_info(binname, 0, &binname_info)) /* create it */ + if (auto const bininfo = tr_sys_path_get_info(binname); !bininfo) { - BlocklistFile b(binname, isEnabled); + // create it + auto b = BlocklistFile{ binname, is_enabled }; if (auto const n = b.setContent(path); n > 0) { load = binname; } } - else if ( - tr_sys_path_get_info(path, 0, &path_info) && - path_info.last_modified_at >= binname_info.last_modified_at) /* update it */ + else if (auto const pathinfo = tr_sys_path_get_info(path); + path && pathinfo->last_modified_at >= bininfo->last_modified_at) { + // update it auto const old = tr_pathbuf{ binname, ".old"sv }; tr_sys_path_remove(old); tr_sys_path_rename(binname, old); - BlocklistFile b(binname, isEnabled); + BlocklistFile b(binname, is_enabled); if (b.setContent(path) > 0) { @@ -2415,7 +2411,7 @@ static void loadBlocklists(tr_session* session) std::begin(loadme), std::end(loadme), std::back_inserter(session->blocklists), - [&isEnabled](auto const& path) { return std::make_unique(path.c_str(), isEnabled); }); + [&is_enabled](auto const& path) { return std::make_unique(path.c_str(), is_enabled); }); /* cleanup */ tr_sys_dir_close(odir); diff --git a/libtransmission/torrent-files.cc b/libtransmission/torrent-files.cc index 8b7b69078..c99415939 100644 --- a/libtransmission/torrent-files.cc +++ b/libtransmission/torrent-files.cc @@ -27,15 +27,15 @@ namespace using file_func_t = std::function; -bool isDirectory(char const* path) +bool isFolder(std::string_view path) { - auto info = tr_sys_path_info{}; - return tr_sys_path_get_info(path, 0, &info) && (info.type == TR_SYS_PATH_IS_DIRECTORY); + auto const info = tr_sys_path_get_info(path); + return info && info->isFolder(); } -bool isEmptyDirectory(char const* path) +bool isEmptyFolder(char const* path) { - if (!isDirectory(path)) + if (!isFolder(path)) { return false; } @@ -60,7 +60,7 @@ bool isEmptyDirectory(char const* path) void depthFirstWalk(char const* path, file_func_t const& func, std::optional max_depth = {}) { - if (isDirectory(path) && (!max_depth || *max_depth > 0)) + if (isFolder(path) && (!max_depth || *max_depth > 0)) { if (auto const odir = tr_sys_dir_open(path); odir != TR_BAD_SYS_DIR) { @@ -114,7 +114,6 @@ std::optional tr_torrent_files::find( size_t n_paths) const { auto filename = tr_pathbuf{}; - auto file_info = tr_sys_path_info{}; auto const& subpath = path(file_index); for (size_t path_idx = 0; path_idx < n_paths; ++path_idx) @@ -122,15 +121,15 @@ std::optional tr_torrent_files::find( auto const base = search_paths[path_idx]; filename.assign(base, '/', subpath); - if (tr_sys_path_get_info(filename, 0, &file_info)) + if (auto const info = tr_sys_path_get_info(filename); info) { - return FoundFile{ file_info, std::move(filename), std::size(base) }; + return FoundFile{ *info, std::move(filename), std::size(base) }; } - filename.assign(filename, base, '/', subpath, PartialFileSuffix); - if (tr_sys_path_get_info(filename, 0, &file_info)) + filename.assign(base, '/', subpath, PartialFileSuffix); + if (auto const info = tr_sys_path_get_info(filename); info) { - return FoundFile{ file_info, std::move(filename), std::size(base) }; + return FoundFile{ *info, std::move(filename), std::size(base) }; } } @@ -220,7 +219,7 @@ bool tr_torrent_files::move( { auto const remove_empty_directories = [](char const* filename) { - if (isEmptyDirectory(filename)) + if (isEmptyFolder(filename)) { tr_sys_path_remove(filename, nullptr); } @@ -304,7 +303,7 @@ void tr_torrent_files::remove(std::string_view parent_in, std::string_view tmpdi // Remove the first two categories and leave the third alone. auto const remove_junk = [](char const* filename) { - if (isEmptyDirectory(filename) || isJunkFile(filename)) + if (isEmptyFolder(filename) || isJunkFile(filename)) { tr_sys_path_remove(filename); } diff --git a/libtransmission/utils.cc b/libtransmission/utils.cc index 700660bf5..77eb0f20e 100644 --- a/libtransmission/utils.cc +++ b/libtransmission/utils.cc @@ -142,9 +142,9 @@ bool tr_loadFile(std::string_view path_in, std::vector& setme, tr_error** auto const path = tr_pathbuf{ path_in }; /* try to stat the file */ - auto info = tr_sys_path_info{}; tr_error* my_error = nullptr; - if (!tr_sys_path_get_info(path, 0, &info, &my_error)) + auto const info = tr_sys_path_get_info(path, 0, &my_error); + if (!info) { tr_logAddError(fmt::format( _("Couldn't read '{path}': {error} ({error_code})"), @@ -155,7 +155,7 @@ bool tr_loadFile(std::string_view path_in, std::vector& setme, tr_error** return false; } - if (info.type != TR_SYS_PATH_IS_FILE) + if (!info->isFile()) { tr_logAddError(fmt::format(_("Couldn't read '{path}': Not a regular file"), fmt::arg("path", path))); tr_error_set(error, TR_ERROR_EISDIR, "Not a regular file"sv); @@ -175,8 +175,8 @@ bool tr_loadFile(std::string_view path_in, std::vector& setme, tr_error** return false; } - setme.resize(info.size); - if (!tr_sys_file_read(fd, std::data(setme), info.size, nullptr, &my_error)) + setme.resize(info->size); + if (!tr_sys_file_read(fd, std::data(setme), info->size, nullptr, &my_error)) { tr_logAddError(fmt::format( _("Couldn't read '{path}': {error} ({error_code})"), @@ -851,13 +851,13 @@ bool tr_moveFile(std::string_view oldpath_in, std::string_view newpath_in, tr_er auto const newpath = tr_pathbuf{ newpath_in }; // make sure the old file exists - auto info = tr_sys_path_info{}; - if (!tr_sys_path_get_info(oldpath, 0, &info, error)) + auto const info = tr_sys_path_get_info(oldpath, 0, error); + if (!info) { tr_error_prefix(error, "Unable to get information on old file: "); return false; } - if (info.type != TR_SYS_PATH_IS_FILE) + if (!info->isFile()) { tr_error_set(error, TR_ERROR_EINVAL, "Old path does not point to a file."sv); return false; diff --git a/libtransmission/watchdir.cc b/libtransmission/watchdir.cc index 099592159..9c1c90d9e 100644 --- a/libtransmission/watchdir.cc +++ b/libtransmission/watchdir.cc @@ -265,10 +265,8 @@ private: { auto const path = tr_pathbuf{ dir, '/', name }; - auto path_info = tr_sys_path_info{}; tr_error* error = nullptr; - bool const ret = tr_sys_path_get_info(path, 0, &path_info, &error) && (path_info.type == TR_SYS_PATH_IS_FILE); - + auto const info = tr_sys_path_get_info(path, 0, &error); if (error != nullptr) { if (!TR_ERROR_IS_ENOENT(error->code)) @@ -283,7 +281,7 @@ private: tr_error_free(error); } - return ret; + return info && info->isFile(); } static constexpr std::string_view statusToString(tr_watchdir_status status) diff --git a/tests/libtransmission/copy-test.cc b/tests/libtransmission/copy-test.cc index b99ab8f50..22d8864db 100644 --- a/tests/libtransmission/copy-test.cc +++ b/tests/libtransmission/copy-test.cc @@ -81,14 +81,14 @@ private: EXPECT_NE(fd1, TR_BAD_SYS_FILE); EXPECT_NE(fd2, TR_BAD_SYS_FILE); - tr_sys_path_info info1; - tr_sys_path_info info2; - tr_sys_file_get_info(fd1, &info1); - tr_sys_file_get_info(fd2, &info2); - EXPECT_EQ(info1.size, info2.size); + auto const info1 = tr_sys_file_get_info(fd1); + auto const info2 = tr_sys_file_get_info(fd2); + EXPECT_TRUE(info1); + EXPECT_TRUE(info2); + EXPECT_EQ(info1->size, info2->size); - uint64_t bytes_left1 = info1.size; - uint64_t bytes_left2 = info2.size; + auto bytes_left1 = info1->size; + auto bytes_left2 = info2->size; size_t const buflen = 2 * 1024 * 1024; /* 2 MiB buffer */ auto* readbuf1 = static_cast(tr_malloc(buflen)); diff --git a/tests/libtransmission/file-test.cc b/tests/libtransmission/file-test.cc index ea8843bf4..26c9b5306 100644 --- a/tests/libtransmission/file-test.cc +++ b/tests/libtransmission/file-test.cc @@ -107,7 +107,6 @@ protected: while (*p != '\0') { - tr_sys_path_info info; char const* slash_pos = strchr(p, '/'); #ifdef _WIN32 @@ -127,9 +126,8 @@ protected: } auto const path_part = std::string{ path, size_t(slash_pos - path + 1) }; - - if (!tr_sys_path_get_info(path_part.c_str(), TR_SYS_PATH_NO_FOLLOW, &info) || - (info.type != TR_SYS_PATH_IS_FILE && info.type != TR_SYS_PATH_IS_DIRECTORY)) + auto const info = tr_sys_path_get_info(path_part, TR_SYS_PATH_NO_FOLLOW); + if (!info || (!info->isFile() && !info->isFolder())) { return false; } @@ -226,14 +224,14 @@ protected: TEST_F(FileTest, getInfo) { auto const test_dir = createTestDir(currentTestName()); - tr_sys_path_info info; auto const path1 = tr_pathbuf{ test_dir, "/a"sv }; auto const path2 = tr_pathbuf{ test_dir, "/b"sv }; // Can't get info of non-existent file/directory tr_error* err = nullptr; - EXPECT_FALSE(tr_sys_path_get_info(path1, 0, &info, &err)); + auto info = tr_sys_path_get_info(path1, 0, &err); + EXPECT_FALSE(info); EXPECT_NE(nullptr, err); tr_error_clear(&err); @@ -241,23 +239,23 @@ TEST_F(FileTest, getInfo) createFileWithContents(path1, "test"); // Good file info - clearPathInfo(&info); - EXPECT_TRUE(tr_sys_path_get_info(path1, 0, &info, &err)); + info = tr_sys_path_get_info(path1, 0, &err); + EXPECT_TRUE(info); EXPECT_EQ(nullptr, err) << *err; - EXPECT_EQ(TR_SYS_PATH_IS_FILE, info.type); - EXPECT_EQ(4, info.size); - EXPECT_GE(info.last_modified_at, t - 1); - EXPECT_LE(info.last_modified_at, time(nullptr) + 1); + EXPECT_EQ(TR_SYS_PATH_IS_FILE, info->type); + EXPECT_EQ(4U, info->size); + EXPECT_GE(info->last_modified_at, t - 1); + EXPECT_LE(info->last_modified_at, time(nullptr) + 1); // Good file info (by handle) auto fd = tr_sys_file_open(path1, TR_SYS_FILE_READ, 0); - clearPathInfo(&info); - EXPECT_TRUE(tr_sys_file_get_info(fd, &info, &err)); + info = tr_sys_file_get_info(fd, &err); + EXPECT_TRUE(info); EXPECT_EQ(nullptr, err) << *err; - EXPECT_EQ(TR_SYS_PATH_IS_FILE, info.type); - EXPECT_EQ(4, info.size); - EXPECT_GE(info.last_modified_at, t - 1); - EXPECT_LE(info.last_modified_at, time(nullptr) + 1); + EXPECT_EQ(TR_SYS_PATH_IS_FILE, info->type); + EXPECT_EQ(4, info->size); + EXPECT_GE(info->last_modified_at, t - 1); + EXPECT_LE(info->last_modified_at, time(nullptr) + 1); tr_sys_file_close(fd); tr_sys_path_remove(path1); @@ -265,19 +263,20 @@ TEST_F(FileTest, getInfo) // Good directory info t = time(nullptr); tr_sys_dir_create(path1, 0, 0777); - clearPathInfo(&info); - EXPECT_TRUE(tr_sys_path_get_info(path1, 0, &info, &err)); + info = tr_sys_path_get_info(path1, 0, &err); + EXPECT_TRUE(info); EXPECT_EQ(nullptr, err) << *err; - EXPECT_EQ(TR_SYS_PATH_IS_DIRECTORY, info.type); - EXPECT_NE(uint64_t(-1), info.size); - EXPECT_GE(info.last_modified_at, t - 1); - EXPECT_LE(info.last_modified_at, time(nullptr) + 1); + EXPECT_EQ(TR_SYS_PATH_IS_DIRECTORY, info->type); + EXPECT_NE(uint64_t(-1), info->size); + EXPECT_GE(info->last_modified_at, t - 1); + EXPECT_LE(info->last_modified_at, time(nullptr) + 1); tr_sys_path_remove(path1); if (createSymlink(path1, path2, false)) { // Can't get info of non-existent file/directory - EXPECT_FALSE(tr_sys_path_get_info(path1, 0, &info, &err)); + info = tr_sys_path_get_info(path1, 0, &err); + EXPECT_FALSE(info); EXPECT_NE(nullptr, err); tr_error_clear(&err); @@ -285,23 +284,23 @@ TEST_F(FileTest, getInfo) createFileWithContents(path2, "test"); // Good file info - clearPathInfo(&info); - EXPECT_TRUE(tr_sys_path_get_info(path1, 0, &info, &err)); + info = tr_sys_path_get_info(path1, 0, &err); + EXPECT_TRUE(info); EXPECT_EQ(nullptr, err) << *err; - EXPECT_EQ(TR_SYS_PATH_IS_FILE, info.type); - EXPECT_EQ(4, info.size); - EXPECT_GE(info.last_modified_at, t - 1); - EXPECT_LE(info.last_modified_at, time(nullptr) + 1); + EXPECT_EQ(TR_SYS_PATH_IS_FILE, info->type); + EXPECT_EQ(4, info->size); + EXPECT_GE(info->last_modified_at, t - 1); + EXPECT_LE(info->last_modified_at, time(nullptr) + 1); // Good file info (by handle) fd = tr_sys_file_open(path1, TR_SYS_FILE_READ, 0); - clearPathInfo(&info); - EXPECT_TRUE(tr_sys_file_get_info(fd, &info, &err)); + info = tr_sys_file_get_info(fd, &err); + EXPECT_TRUE(info); EXPECT_EQ(nullptr, err) << *err; - EXPECT_EQ(TR_SYS_PATH_IS_FILE, info.type); - EXPECT_EQ(4, info.size); - EXPECT_GE(info.last_modified_at, t - 1); - EXPECT_LE(info.last_modified_at, time(nullptr) + 1); + EXPECT_EQ(TR_SYS_PATH_IS_FILE, info->type); + EXPECT_EQ(4, info->size); + EXPECT_GE(info->last_modified_at, t - 1); + EXPECT_LE(info->last_modified_at, time(nullptr) + 1); tr_sys_file_close(fd); tr_sys_path_remove(path2); @@ -311,13 +310,13 @@ TEST_F(FileTest, getInfo) t = time(nullptr); tr_sys_dir_create(path2, 0, 0777); EXPECT_TRUE(createSymlink(path1, path2, true)); /* Win32: directory and file symlinks differ :( */ - clearPathInfo(&info); - EXPECT_TRUE(tr_sys_path_get_info(path1, 0, &info, &err)); + info = tr_sys_path_get_info(path1, 0, &err); + EXPECT_TRUE(info); EXPECT_EQ(nullptr, err) << *err; - EXPECT_EQ(TR_SYS_PATH_IS_DIRECTORY, info.type); - EXPECT_NE(uint64_t(-1), info.size); - EXPECT_GE(info.last_modified_at, t - 1); - EXPECT_LE(info.last_modified_at, time(nullptr) + 1); + EXPECT_EQ(TR_SYS_PATH_IS_DIRECTORY, info->type); + EXPECT_NE(uint64_t(-1), info->size); + EXPECT_GE(info->last_modified_at, t - 1); + EXPECT_LE(info->last_modified_at, time(nullptr) + 1); tr_sys_path_remove(path2); tr_sys_path_remove(path1); @@ -1088,13 +1087,14 @@ TEST_F(FileTest, fileOpen) EXPECT_EQ(TR_BAD_SYS_FILE, fd); EXPECT_NE(nullptr, err); tr_error_clear(&err); - tr_sys_path_info info; - tr_sys_path_get_info(path1, TR_SYS_PATH_NO_FOLLOW, &info); - EXPECT_EQ(4, info.size); + auto info = tr_sys_path_get_info(path1, TR_SYS_PATH_NO_FOLLOW); + EXPECT_TRUE(info); + EXPECT_EQ(4U, info->size); /* Pointer is at the end of file */ - tr_sys_path_get_info(path1, TR_SYS_PATH_NO_FOLLOW, &info); - EXPECT_EQ(4, info.size); + info = tr_sys_path_get_info(path1, TR_SYS_PATH_NO_FOLLOW); + EXPECT_TRUE(info); + EXPECT_EQ(4U, info->size); fd = tr_sys_file_open(path1, TR_SYS_FILE_WRITE | TR_SYS_FILE_APPEND, 0600, &err); EXPECT_NE(TR_BAD_SYS_FILE, fd); EXPECT_EQ(nullptr, err) << *err; @@ -1105,16 +1105,19 @@ TEST_F(FileTest, fileOpen) tr_sys_file_close(fd); /* File gets truncated */ - tr_sys_path_get_info(path1, TR_SYS_PATH_NO_FOLLOW, &info); - EXPECT_EQ(5, info.size); + info = tr_sys_path_get_info(path1, TR_SYS_PATH_NO_FOLLOW); + EXPECT_TRUE(info); + EXPECT_EQ(5U, info->size); fd = tr_sys_file_open(path1, TR_SYS_FILE_WRITE | TR_SYS_FILE_TRUNCATE, 0600, &err); EXPECT_NE(TR_BAD_SYS_FILE, fd); EXPECT_EQ(nullptr, err) << *err; - tr_sys_file_get_info(fd, &info); - EXPECT_EQ(0, info.size); + info = tr_sys_file_get_info(fd); + EXPECT_TRUE(info); + EXPECT_EQ(0U, info->size); tr_sys_file_close(fd); - tr_sys_path_get_info(path1, TR_SYS_PATH_NO_FOLLOW, &info); - EXPECT_EQ(0, info.size); + info = tr_sys_path_get_info(path1, TR_SYS_PATH_NO_FOLLOW); + EXPECT_TRUE(info); + EXPECT_EQ(0U, info->size); /* TODO: symlink and hardlink tests */ @@ -1214,27 +1217,30 @@ TEST_F(FileTest, fileTruncate) tr_error* err = nullptr; EXPECT_TRUE(tr_sys_file_truncate(fd, 10, &err)); EXPECT_EQ(nullptr, err) << *err; - tr_sys_path_info info; - tr_sys_file_get_info(fd, &info); - EXPECT_EQ(10, info.size); + auto info = tr_sys_file_get_info(fd); + EXPECT_TRUE(info); + EXPECT_EQ(10U, info->size); EXPECT_TRUE(tr_sys_file_truncate(fd, 20, &err)); EXPECT_EQ(nullptr, err) << *err; - tr_sys_file_get_info(fd, &info); - EXPECT_EQ(20, info.size); + info = tr_sys_file_get_info(fd); + EXPECT_TRUE(info); + EXPECT_EQ(20U, info->size); EXPECT_TRUE(tr_sys_file_truncate(fd, 0, &err)); EXPECT_EQ(nullptr, err) << *err; - tr_sys_file_get_info(fd, &info); - EXPECT_EQ(0, info.size); + info = tr_sys_file_get_info(fd); + EXPECT_TRUE(info); + EXPECT_EQ(0U, info->size); EXPECT_TRUE(tr_sys_file_truncate(fd, 50, &err)); EXPECT_EQ(nullptr, err) << *err; tr_sys_file_close(fd); - tr_sys_path_get_info(path1, 0, &info); - EXPECT_EQ(50, info.size); + info = tr_sys_path_get_info(path1); + EXPECT_TRUE(info); + EXPECT_EQ(50U, info->size); fd = tr_sys_file_open(path1, TR_SYS_FILE_WRITE | TR_SYS_FILE_CREATE, 0600); @@ -1243,8 +1249,9 @@ TEST_F(FileTest, fileTruncate) tr_sys_file_close(fd); - tr_sys_path_get_info(path1, 0, &info); - EXPECT_EQ(25, info.size); + info = tr_sys_path_get_info(path1); + EXPECT_TRUE(info); + EXPECT_EQ(25U, info->size); tr_sys_path_remove(path1); } @@ -1261,9 +1268,9 @@ TEST_F(FileTest, filePreallocate) if (tr_sys_file_preallocate(fd, prealloc_size, 0, &err)) { EXPECT_EQ(nullptr, err) << *err; - tr_sys_path_info info; - tr_sys_file_get_info(fd, &info); - EXPECT_EQ(prealloc_size, info.size); + auto info = tr_sys_file_get_info(fd); + EXPECT_TRUE(info); + EXPECT_EQ(prealloc_size, info->size); } else { @@ -1282,9 +1289,9 @@ TEST_F(FileTest, filePreallocate) if (tr_sys_file_preallocate(fd, prealloc_size, TR_SYS_FILE_PREALLOC_SPARSE, &err)) { EXPECT_EQ(nullptr, err) << *err; - tr_sys_path_info info; - tr_sys_file_get_info(fd, &info); - EXPECT_EQ(prealloc_size, info.size); + auto info = tr_sys_file_get_info(fd); + EXPECT_TRUE(info); + EXPECT_EQ(prealloc_size, info->size); } else { diff --git a/tests/libtransmission/test-fixtures.h b/tests/libtransmission/test-fixtures.h index 238a0b721..fe6203bfc 100644 --- a/tests/libtransmission/test-fixtures.h +++ b/tests/libtransmission/test-fixtures.h @@ -45,15 +45,19 @@ using file_func_t = std::function; static void depthFirstWalk(char const* path, file_func_t func) { - auto info = tr_sys_path_info{}; - if (tr_sys_path_get_info(path, 0, &info) && (info.type == TR_SYS_PATH_IS_DIRECTORY)) + if (auto const info = tr_sys_path_get_info(path); info && info->isFolder()) { if (auto const odir = tr_sys_dir_open(path); odir != TR_BAD_SYS_DIR) { - char const* name; - while ((name = tr_sys_dir_read_name(odir)) != nullptr) + for (;;) { - if (strcmp(name, ".") != 0 && strcmp(name, "..") != 0) + char const* const name = tr_sys_dir_read_name(odir); + if (name == nullptr) + { + break; + } + + if ("."sv != name && ".."sv != name) { auto const child = fmt::format("{:s}/{:s}"sv, path, name); depthFirstWalk(child.c_str(), func);