refactor: tr_sys_path_dirname returns a std::string (#2792)

This commit is contained in:
Charles Kerr 2022-03-21 15:22:50 -05:00 committed by GitHub
parent fcc1510ecb
commit 03ee0028d4
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
27 changed files with 259 additions and 288 deletions

View File

@ -263,7 +263,7 @@ bool tr_announce_list::save(std::string const& torrent_file, tr_error** error) c
// confirm that it's good by parsing it back again
auto const contents = tr_variantToStr(&metainfo, TR_VARIANT_FMT_BENC);
tr_variantFree(&metainfo);
if (auto tm = tr_torrent_metainfo{}; !tm.parseBenc(contents))
if (auto tm = tr_torrent_metainfo{}; !tm.parseBenc(contents, error))
{
return false;
}

View File

@ -99,12 +99,10 @@ static void blocklistLoad(tr_blocklistFile* b)
b->byteCount = byteCount;
b->ruleCount = byteCount / sizeof(struct tr_ipv4_range);
char* const base = tr_sys_path_basename(b->filename, nullptr);
tr_logAddInfo(fmt::format(
ngettext("Blocklist '{path}' has {count} entry", "Blocklist '{path}' has {count} entries", b->ruleCount),
fmt::arg("path", base),
fmt::arg("path", tr_sys_path_basename(b->filename)),
fmt::arg("count", b->ruleCount)));
tr_free(base);
}
static void blocklistEnsureLoaded(tr_blocklistFile* b)
@ -481,12 +479,10 @@ int tr_blocklistFileSetContent(tr_blocklistFile* b, char const* filename)
}
else
{
char* base = tr_sys_path_basename(b->filename, nullptr);
tr_logAddInfo(fmt::format(
ngettext("Blocklist '{path}' has {count} entry", "Blocklist '{path}' has {count} entries", b->ruleCount),
fmt::arg("path", base),
fmt::arg("path", tr_sys_path_basename(b->filename)),
fmt::arg("count", b->ruleCount)));
tr_free(base);
}
tr_free(ranges);

View File

@ -164,9 +164,9 @@ static int cached_file_open(
/* create subfolders, if any */
if (writable)
{
char* dir = tr_sys_path_dirname(filename, &error);
auto const dir = tr_sys_path_dirname(filename, &error);
if (dir == nullptr)
if (std::empty(dir))
{
tr_logAddError(fmt::format(
_("Couldn't create '{path}': {error} ({error_code})"),
@ -176,18 +176,15 @@ static int cached_file_open(
goto FAIL;
}
if (!tr_sys_dir_create(dir, TR_SYS_DIR_CREATE_PARENTS, 0777, &error))
if (!tr_sys_dir_create(dir.c_str(), TR_SYS_DIR_CREATE_PARENTS, 0777, &error))
{
tr_logAddError(fmt::format(
_("Couldn't create '{path}': {error} ({error_code})"),
fmt::arg("path", dir),
fmt::arg("error", error->message),
fmt::arg("error_code", error->code)));
tr_free(dir);
goto FAIL;
}
tr_free(dir);
}
already_existed = tr_sys_path_get_info(filename, 0, &info, nullptr) && info.type == TR_SYS_PATH_IS_FILE;

View File

@ -384,42 +384,32 @@ char* tr_sys_path_resolve(char const* path, tr_error** error)
return ret;
}
char* tr_sys_path_basename(std::string_view path, tr_error** error)
std::string tr_sys_path_basename(std::string_view path, tr_error** error)
{
char* const tmp = tr_strvDup(path);
char* ret = basename(tmp);
auto tmp = std::string{ path };
char* ret = basename(std::data(tmp));
if (ret != nullptr)
{
ret = tr_strdup(ret);
}
else
{
set_system_error(error, errno);
return ret;
}
tr_free(tmp);
return ret;
set_system_error(error, errno);
return {};
}
char* tr_sys_path_dirname(std::string_view path, tr_error** error)
std::string tr_sys_path_dirname(std::string_view path, tr_error** error)
{
char* const tmp = tr_strvDup(path);
char* ret = dirname(tmp);
auto tmp = std::string{ path };
char* ret = dirname(std::data(tmp));
if (ret != nullptr)
{
ret = tr_strdup(ret);
}
else
{
set_system_error(error, errno);
return ret;
}
tr_free(tmp);
return ret;
set_system_error(error, errno);
return {};
}
bool tr_sys_path_rename(char const* src_path, char const* dst_path, tr_error** error)

View File

@ -12,6 +12,8 @@
#include <shlobj.h> /* SHCreateDirectoryEx() */
#include <winioctl.h> /* FSCTL_SET_SPARSE */
#include <fmt/core.h>
#include "transmission.h"
#include "crypto-utils.h" /* tr_rand_int() */
#include "error.h"
@ -646,17 +648,17 @@ cleanup:
return ret;
}
char* tr_sys_path_basename(std::string_view path, tr_error** error)
std::string tr_sys_path_basename(std::string_view path, tr_error** error)
{
if (std::empty(path))
{
return tr_strdup(".");
return ".";
}
if (!is_valid_path(path))
{
set_system_error(error, ERROR_PATH_NOT_FOUND);
return nullptr;
return {};
}
char const* const begin = std::data(path);
@ -669,7 +671,7 @@ char* tr_sys_path_basename(std::string_view path, tr_error** error)
if (end == begin)
{
return tr_strdup("/");
return "/";
}
char const* name = end;
@ -681,30 +683,30 @@ char* tr_sys_path_basename(std::string_view path, tr_error** error)
if (name == end)
{
return tr_strdup("/");
return "/";
}
return tr_strndup(name, end - name);
return { name, size_t(end - name) };
}
char* tr_sys_path_dirname(std::string_view path, tr_error** error)
std::string tr_sys_path_dirname(std::string_view path, tr_error** error)
{
if (std::empty(path))
{
return tr_strdup(".");
return ".";
}
if (!is_valid_path(path))
{
set_system_error(error, ERROR_PATH_NOT_FOUND);
return nullptr;
return {};
}
bool const is_unc = is_unc_path(path);
if (is_unc && path[2] == '\0')
{
return tr_strvDup(path);
return std::string{ path };
}
char const* const begin = std::data(path);
@ -717,7 +719,7 @@ char* tr_sys_path_dirname(std::string_view path, tr_error** error)
if (end == begin)
{
return tr_strdup("/");
return "/";
}
char const* name = end;
@ -734,15 +736,15 @@ char* tr_sys_path_dirname(std::string_view path, tr_error** error)
if (name == begin)
{
return tr_strdup(is_unc ? "\\\\" : ".");
return is_unc ? "\\\\" : ".";
}
if (name > begin && *(name - 1) == ':' && *name != '\0' && !is_slash(*name))
{
return tr_strdup_printf("%c:.", begin[0]);
return fmt::format("{}:.", begin[0]);
}
return tr_strndup(begin, name - begin);
return { begin, size_t(name - begin) };
}
bool tr_sys_path_rename(char const* src_path, char const* dst_path, tr_error** error)

View File

@ -8,6 +8,7 @@
#include <cstddef> // size_t
#include <cinttypes> // uintX_t
#include <ctime>
#include <string>
#include <string_view>
#ifdef _WIN32
@ -223,7 +224,7 @@ char* tr_sys_path_resolve(char const* path, struct tr_error** error);
* it when no longer needed), `nullptr` otherwise (with `error` set
* accordingly).
*/
char* tr_sys_path_basename(std::string_view path, struct tr_error** error);
std::string tr_sys_path_basename(std::string_view path, struct tr_error** error = nullptr);
/**
* @brief Portability wrapper for `dirname()`.
@ -237,7 +238,7 @@ char* tr_sys_path_basename(std::string_view path, struct tr_error** error);
* when no longer needed), `nullptr` otherwise (with `error` set
* accordingly).
*/
char* tr_sys_path_dirname(std::string_view path, struct tr_error** error);
std::string tr_sys_path_dirname(std::string_view path, struct tr_error** error = nullptr);
/**
* @brief Portability wrapper for `rename()`.

View File

@ -247,10 +247,9 @@ void tr_logAddMessage(char const* file, int line, tr_log_level level, std::strin
auto name_fallback = std::string{};
if (std::empty(name))
{
auto* base = tr_sys_path_basename(file, nullptr);
name_fallback = fmt::format("{}:{}", (base != nullptr ? base : "?"), line);
auto const base = tr_sys_path_basename(file);
name_fallback = fmt::format("{}:{}", !std::empty(base) ? base : "?", line);
name = name_fallback;
tr_free(base);
}
// message logging shouldn't affect errno

View File

@ -44,9 +44,9 @@ struct FileList
struct FileList* next;
};
static struct FileList* getFiles(char const* dir, char const* base, struct FileList* list)
static struct FileList* getFiles(std::string_view dir, std::string_view base, struct FileList* list)
{
if (dir == nullptr || base == nullptr)
if (std::empty(dir) || std::empty(base))
{
return nullptr;
}
@ -152,14 +152,7 @@ tr_metainfo_builder* tr_metaInfoBuilderCreate(char const* topFileArg)
/* build a list of files containing top file and,
if it's a directory, all of its children */
FileList* files = nullptr;
{
char* dir = tr_sys_path_dirname(ret->top, nullptr);
char* base = tr_sys_path_basename(ret->top, nullptr);
files = getFiles(dir, base, nullptr);
tr_free(base);
tr_free(dir);
}
auto* files = getFiles(tr_sys_path_dirname(ret->top), tr_sys_path_basename(ret->top), nullptr);
for (auto* walk = files; walk != nullptr; walk = walk->next)
{
@ -172,7 +165,7 @@ tr_metainfo_builder* tr_metaInfoBuilderCreate(char const* topFileArg)
auto const offset = strlen(ret->top);
while (files != nullptr)
{
struct FileList* const tmp = files;
auto* const tmp = files;
files = files->next;
auto* const file = &ret->files[i++];
@ -412,10 +405,9 @@ static void makeInfoDict(tr_variant* dict, tr_metainfo_builder* builder)
tr_variantDictAddInt(dict, TR_KEY_length, builder->files[0].size);
}
if (auto* const base = tr_sys_path_basename(builder->top, nullptr); base != nullptr)
if (auto const base = tr_sys_path_basename(builder->top); !std::empty(base))
{
tr_variantDictAddStr(dict, TR_KEY_name, base);
tr_free(base);
}
tr_variantDictAddInt(dict, TR_KEY_piece_length, builder->pieceSize);

View File

@ -45,6 +45,7 @@
using namespace std::literals;
// TODO: use remove this and use tr_strvPath() instead
static char* tr_buildPath(char const* first_element, ...)
{
// pass 1: allocate enough space for the string
@ -401,13 +402,12 @@ char const* tr_getWebClientDir([[maybe_unused]] tr_session const* session)
wchar_t wide_module_path[MAX_PATH];
GetModuleFileNameW(nullptr, wide_module_path, TR_N_ELEMENTS(wide_module_path));
char* module_path = tr_win32_native_to_utf8(wide_module_path, -1);
char* dir = tr_sys_path_dirname(module_path, nullptr);
auto const dir = tr_sys_path_dirname(module_path);
tr_free(module_path);
if (dir != nullptr)
if (!std::empty(dir))
{
char* path = tr_buildPath(dir, "Web", nullptr);
tr_free(dir);
char* path = tr_buildPath(dir.c_str(), "Web", nullptr);
if (isWebClientDir(path))
{

View File

@ -1761,8 +1761,8 @@ static char const* groupSet(
auto& group = session->getBandwidthGroup(name);
auto limits = group.getLimits();
tr_variantDictFindBool(args_in, TR_KEY_speed_limit_down_enabled, &limits.down_limited);
tr_variantDictFindBool(args_in, TR_KEY_speed_limit_up_enabled, &limits.up_limited);
(void)tr_variantDictFindBool(args_in, TR_KEY_speed_limit_down_enabled, &limits.down_limited);
(void)tr_variantDictFindBool(args_in, TR_KEY_speed_limit_up_enabled, &limits.up_limited);
if (auto limit = int64_t{}; tr_variantDictFindInt(args_in, TR_KEY_speed_limit_down, &limit))
{

View File

@ -698,6 +698,7 @@ static void tr_sessionInitImpl(init_data* data)
{
tr_variant const* const clientSettings = data->clientSettings;
tr_session* session = data->session;
auto lock = session->unique_lock();
TR_ASSERT(tr_amInEventThread(session));
TR_ASSERT(tr_variantIsDict(clientSettings));

View File

@ -2219,10 +2219,10 @@ static void deleteLocalData(tr_torrent const* tor, tr_fileFunc func)
{
auto files = std::vector<std::string>{};
auto folders = std::set<std::string>{};
char const* const top = tor->currentDir().c_str();
auto const top = std::string{ tor->currentDir().sv() };
/* don't try to delete local data if the directory's gone missing */
if (!tr_sys_path_exists(top, nullptr))
if (!tr_sys_path_exists(top.c_str(), nullptr))
{
return;
}
@ -2292,17 +2292,14 @@ static void deleteLocalData(tr_torrent const* tor, tr_fileFunc func)
/* go from the bottom up */
for (auto const& file : files)
{
char* walk = tr_strvDup(file);
auto walk = file;
while (tr_sys_path_exists(walk, nullptr) && !tr_sys_path_is_same(tmpdir.c_str(), walk, nullptr))
while (tr_sys_path_exists(walk.c_str(), nullptr) && !tr_sys_path_is_same(tmpdir.c_str(), walk.c_str(), nullptr))
{
char* tmp = tr_sys_path_dirname(walk, nullptr);
(*func)(walk, nullptr);
tr_free(walk);
walk = tmp;
}
(*func)(walk.c_str(), nullptr);
tr_free(walk);
walk = tr_sys_path_dirname(walk);
}
}
/***
@ -2316,33 +2313,29 @@ static void deleteLocalData(tr_torrent const* tor, tr_fileFunc func)
{
/* get the directory that this file goes in... */
auto const filename = tr_strvPath(top, tor->fileSubpath(f));
char* dir = tr_sys_path_dirname(filename.c_str(), nullptr);
if (dir == nullptr)
auto dir = tr_sys_path_dirname(filename);
if (std::empty(dir))
{
continue;
}
/* walk up the directory tree until we reach 'top' */
if (!tr_sys_path_is_same(top, dir, nullptr) && strcmp(top, dir) != 0)
if (!tr_sys_path_is_same(top.c_str(), dir.c_str(), nullptr) && dir == top)
{
for (;;)
{
char* parent = tr_sys_path_dirname(dir, nullptr);
auto const parent = tr_sys_path_dirname(dir);
if (tr_sys_path_is_same(top, parent, nullptr) || strcmp(top, parent) == 0)
if (tr_sys_path_is_same(top.c_str(), parent.c_str(), nullptr) || parent == top)
{
folders.emplace(dir);
tr_free(parent);
break;
}
/* walk upwards to parent */
tr_free(dir);
dir = parent;
}
}
tr_free(dir);
}
for (auto const& folder : folders)
@ -2955,7 +2948,7 @@ static int renamePath(tr_torrent* tor, char const* oldpath, char const* newname)
if (tr_sys_path_exists(src.c_str(), nullptr))
{
char* const parent = tr_sys_path_dirname(src.c_str(), nullptr);
auto const parent = tr_sys_path_dirname(src);
auto const tgt = tr_strvEndsWith(src, ".part"sv) ? tr_strvJoin(parent, TR_PATH_DELIMITER_STR, newname, ".part"sv) :
tr_strvPath(parent, newname);
@ -2977,8 +2970,6 @@ static int renamePath(tr_torrent* tor, char const* oldpath, char const* newname)
errno = tmp;
}
tr_free(parent);
}
return err;
@ -3003,9 +2994,9 @@ static void renameTorrentFileString(tr_torrent* tor, char const* oldpath, char c
}
else
{
char* tmp = tr_sys_path_dirname(oldpath, nullptr);
auto const tmp = tr_sys_path_dirname(oldpath);
if (tmp == nullptr)
if (std::empty(tmp))
{
return;
}
@ -3018,8 +3009,6 @@ static void renameTorrentFileString(tr_torrent* tor, char const* oldpath, char c
{
name = tr_strvPath(tmp, newname, subpath.substr(oldpath_len + 1));
}
tr_free(tmp);
}
if (subpath != name)

View File

@ -33,8 +33,6 @@
****
***/
#include <iostream>
namespace
{
namespace impl
@ -195,7 +193,9 @@ static void libeventThreadFunc(tr_event_handle* events)
// tell the thread that's waiting in tr_eventInit()
// that this thread is ready for business
events->work_queue_mutex.lock();
events->work_queue_cv.notify_one();
events->work_queue_mutex.unlock();
// loop until `tr_eventClose()` kills the loop
event_base_loop(base, EVLOOP_NO_EXIT_ON_EMPTY);

View File

@ -1129,12 +1129,10 @@ bool tr_moveFile(char const* oldpath, char const* newpath, tr_error** error)
return false;
}
/* make sure the target directory exists */
// ensure the target directory exists
{
char* newdir = tr_sys_path_dirname(newpath, error);
bool const i = newdir != nullptr && tr_sys_dir_create(newdir, TR_SYS_DIR_CREATE_PARENTS, 0777, error);
tr_free(newdir);
auto const newdir = tr_sys_path_dirname(newpath, error);
bool const i = !std::empty(newdir) && tr_sys_dir_create(newdir.c_str(), TR_SYS_DIR_CREATE_PARENTS, 0777, error);
if (!i)
{
tr_error_prefix(error, "Unable to create directory for new file: ");

View File

@ -17,6 +17,8 @@
#include "utils.h"
#include "variant.h"
#include "test-fixtures.h"
#include "gtest/gtest.h"
using AnnounceListTest = ::testing::Test;
@ -344,9 +346,9 @@ TEST_F(AnnounceListTest, save)
auto const test_file = tr_strvJoin(::testing::TempDir(), "transmission-announce-list-test.torrent"sv);
tr_error* error = nullptr;
EXPECT_TRUE(tr_loadFile(original_content, OriginalFile, &error));
EXPECT_EQ(nullptr, error);
EXPECT_EQ(nullptr, error) << *error;
EXPECT_TRUE(tr_saveFile(test_file, { std::data(original_content), std::size(original_content) }, &error));
EXPECT_EQ(nullptr, error);
EXPECT_EQ(nullptr, error) << *error;
// make an announce_list for it
auto announce_list = tr_announce_list();
@ -362,7 +364,7 @@ TEST_F(AnnounceListTest, save)
// now save to a real torrent file
EXPECT_TRUE(announce_list.save(test_file, &error));
EXPECT_EQ(nullptr, error);
EXPECT_EQ(nullptr, error) << *error;
// load the original
auto original_tm = tr_torrent_metainfo{};

View File

@ -43,14 +43,10 @@ protected:
#if 0
void createFileWithContents(char const* path, char const* contents)
{
tr_sys_file_t fd;
char* dir;
auto const dir = tr_sys_path_dirname(path);
tr_sys_dir_create(dir.c_str(), TR_SYS_DIR_CREATE_PARENTS, 0700, nullptr);
dir = tr_sys_path_dirname(path, nullptr);
tr_sys_dir_create(dir, TR_SYS_DIR_CREATE_PARENTS, 0700, nullptr);
tr_free(dir);
fd = tr_sys_file_open(path, TR_SYS_FILE_WRITE | TR_SYS_FILE_CREATE | TR_SYS_FILE_TRUNCATE, 0600, nullptr);
auto const fd = tr_sys_file_open(path, TR_SYS_FILE_WRITE | TR_SYS_FILE_CREATE | TR_SYS_FILE_TRUNCATE, 0600, nullptr);
blockingFileWrite(fd, contents, strlen(contents));
tr_sys_file_close(fd, nullptr);

View File

@ -40,7 +40,7 @@ protected:
tr_error* err = nullptr;
/* Copy it. */
EXPECT_TRUE(tr_sys_path_copy(path1.c_str(), path2.c_str(), &err));
EXPECT_EQ(nullptr, err);
EXPECT_EQ(nullptr, err) << ' ' << *err;
tr_error_clear(&err);
EXPECT_TRUE(filesAreIdentical(path1.c_str(), path2.c_str()));

View File

@ -6,6 +6,8 @@
#include "transmission.h"
#include "error.h"
#include "test-fixtures.h"
#include "gtest/gtest.h"
using namespace std::literals;
@ -15,7 +17,7 @@ TEST(Error, errorSet)
tr_error* err = nullptr;
tr_error_prefix(&err, "error: ");
EXPECT_EQ(nullptr, err);
EXPECT_EQ(nullptr, err) << *err;
tr_error_set(&err, 2, "oops"sv);
EXPECT_NE(nullptr, err);
@ -45,7 +47,7 @@ TEST(Error, propagate)
EXPECT_NE(nullptr, err2);
EXPECT_EQ(Code, err2->code);
EXPECT_STREQ("oops", err2->message);
EXPECT_EQ(nullptr, err);
EXPECT_EQ(nullptr, err) << *err;
tr_error_clear(&err2);
}

View File

@ -3,15 +3,9 @@
// or any future license endorsed by Mnemosyne LLC.
// License text can be found in the licenses/ folder.
#include "transmission.h"
#include "error.h"
#include "file.h"
#include "tr-macros.h"
#include "test-fixtures.h"
#include <array>
#include <cstring>
#include <ostream>
#include <string>
#ifndef _WIN32
@ -22,6 +16,14 @@
#include <windows.h>
#endif
#include "transmission.h"
#include "error.h"
#include "file.h"
#include "tr-macros.h"
#include "test-fixtures.h"
#if !defined(__OpenBSD__)
#define HAVE_UNIFIED_BUFFER_CACHE
#endif
@ -156,23 +158,22 @@ protected:
char const* output;
};
static void testPathXname(XnameTestData const* data, size_t data_size, char* (*func)(std::string_view, tr_error**))
static void testPathXname(XnameTestData const* data, size_t data_size, std::string (*func)(std::string_view, tr_error**))
{
for (size_t i = 0; i < data_size; ++i)
{
tr_error* err = nullptr;
char* name = func(data[i].input, &err);
auto const name = func(data[i].input, &err);
if (data[i].output != nullptr)
{
EXPECT_NE(nullptr, name);
EXPECT_EQ(nullptr, err);
EXPECT_STREQ(data[i].output, name);
tr_free(name);
EXPECT_NE(""sv, name);
EXPECT_EQ(nullptr, err) << *err;
EXPECT_EQ(data[i].output, name);
}
else
{
EXPECT_EQ(nullptr, name);
EXPECT_EQ(""sv, name);
EXPECT_NE(nullptr, err);
tr_error_clear(&err);
}
@ -186,12 +187,12 @@ protected:
tr_error* err = nullptr;
auto dd = tr_sys_dir_open(path.c_str(), &err);
EXPECT_NE(TR_BAD_SYS_DIR, dd);
EXPECT_EQ(nullptr, err);
EXPECT_EQ(nullptr, err) << *err;
char const* name;
while ((name = tr_sys_dir_read_name(dd, &err)) != nullptr)
{
EXPECT_EQ(nullptr, err);
EXPECT_EQ(nullptr, err) << *err;
if (strcmp(name, ".") == 0 || strcmp(name, "..") == 0)
{
@ -212,10 +213,10 @@ protected:
}
}
EXPECT_EQ(nullptr, err);
EXPECT_EQ(nullptr, err) << *err;
EXPECT_TRUE(tr_sys_dir_close(dd, &err));
EXPECT_EQ(nullptr, err);
EXPECT_EQ(nullptr, err) << *err;
}
};
@ -239,7 +240,7 @@ TEST_F(FileTest, getInfo)
// Good file info
clearPathInfo(&info);
EXPECT_TRUE(tr_sys_path_get_info(path1.c_str(), 0, &info, &err));
EXPECT_EQ(nullptr, err);
EXPECT_EQ(nullptr, err) << *err;
EXPECT_EQ(TR_SYS_PATH_IS_FILE, info.type);
EXPECT_EQ(4, info.size);
EXPECT_GT(info.last_modified_at, t - 1);
@ -249,7 +250,7 @@ TEST_F(FileTest, getInfo)
auto fd = tr_sys_file_open(path1.c_str(), TR_SYS_FILE_READ, 0, nullptr);
clearPathInfo(&info);
EXPECT_TRUE(tr_sys_file_get_info(fd, &info, &err));
EXPECT_EQ(nullptr, err);
EXPECT_EQ(nullptr, err) << *err;
EXPECT_EQ(TR_SYS_PATH_IS_FILE, info.type);
EXPECT_EQ(4, info.size);
EXPECT_GT(info.last_modified_at, t - 1);
@ -263,7 +264,7 @@ TEST_F(FileTest, getInfo)
tr_sys_dir_create(path1.c_str(), 0, 0777, nullptr);
clearPathInfo(&info);
EXPECT_TRUE(tr_sys_path_get_info(path1.c_str(), 0, &info, &err));
EXPECT_EQ(nullptr, err);
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);
@ -283,7 +284,7 @@ TEST_F(FileTest, getInfo)
// Good file info
clearPathInfo(&info);
EXPECT_TRUE(tr_sys_path_get_info(path1.c_str(), 0, &info, &err));
EXPECT_EQ(nullptr, err);
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);
@ -293,7 +294,7 @@ TEST_F(FileTest, getInfo)
fd = tr_sys_file_open(path1.c_str(), TR_SYS_FILE_READ, 0, nullptr);
clearPathInfo(&info);
EXPECT_TRUE(tr_sys_file_get_info(fd, &info, &err));
EXPECT_EQ(nullptr, err);
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);
@ -309,7 +310,7 @@ TEST_F(FileTest, getInfo)
EXPECT_TRUE(createSymlink(path1.c_str(), path2.c_str(), true)); /* Win32: directory and file symlinks differ :( */
clearPathInfo(&info);
EXPECT_TRUE(tr_sys_path_get_info(path1.c_str(), 0, &info, &err));
EXPECT_EQ(nullptr, err);
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);
@ -334,19 +335,19 @@ TEST_F(FileTest, pathExists)
// Non-existent file does not exist
tr_error* err = nullptr;
EXPECT_FALSE(tr_sys_path_exists(path1.c_str(), &err));
EXPECT_EQ(nullptr, err);
EXPECT_EQ(nullptr, err) << *err;
// Create file and see that it exists
createFileWithContents(path1, "test");
EXPECT_TRUE(tr_sys_path_exists(path1.c_str(), &err));
EXPECT_EQ(nullptr, err);
EXPECT_EQ(nullptr, err) << *err;
tr_sys_path_remove(path1.c_str(), nullptr);
// Create directory and see that it exists
tr_sys_dir_create(path1.c_str(), 0, 0777, nullptr);
EXPECT_TRUE(tr_sys_path_exists(path1.c_str(), &err));
EXPECT_EQ(nullptr, err);
EXPECT_EQ(nullptr, err) << *err;
tr_sys_path_remove(path1.c_str(), nullptr);
@ -354,12 +355,12 @@ TEST_F(FileTest, pathExists)
{
// Non-existent file does not exist (via symlink)
EXPECT_FALSE(tr_sys_path_exists(path1.c_str(), &err));
EXPECT_EQ(nullptr, err);
EXPECT_EQ(nullptr, err) << *err;
// Create file and see that it exists (via symlink)
createFileWithContents(path2, "test");
EXPECT_TRUE(tr_sys_path_exists(path1.c_str(), &err));
EXPECT_EQ(nullptr, err);
EXPECT_EQ(nullptr, err) << *err;
tr_sys_path_remove(path2.c_str(), nullptr);
tr_sys_path_remove(path1.c_str(), nullptr);
@ -368,7 +369,7 @@ TEST_F(FileTest, pathExists)
tr_sys_dir_create(path2.c_str(), 0, 0777, nullptr);
EXPECT_TRUE(createSymlink(path1.c_str(), path2.c_str(), true)); /* Win32: directory and file symlinks differ :( */
EXPECT_TRUE(tr_sys_path_exists(path1.c_str(), &err));
EXPECT_EQ(nullptr, err);
EXPECT_EQ(nullptr, err) << *err;
tr_sys_path_remove(path2.c_str(), nullptr);
tr_sys_path_remove(path1.c_str(), nullptr);
@ -436,45 +437,45 @@ TEST_F(FileTest, pathIsSame)
/* Two non-existent files are not the same */
tr_error* err = nullptr;
EXPECT_FALSE(tr_sys_path_is_same(path1.c_str(), path1.c_str(), &err));
EXPECT_EQ(nullptr, err);
EXPECT_EQ(nullptr, err) << *err;
EXPECT_FALSE(tr_sys_path_is_same(path1.c_str(), path2.c_str(), &err));
EXPECT_EQ(nullptr, err);
EXPECT_EQ(nullptr, err) << *err;
/* Two same files are the same */
createFileWithContents(path1, "test");
EXPECT_TRUE(tr_sys_path_is_same(path1.c_str(), path1.c_str(), &err));
EXPECT_EQ(nullptr, err);
EXPECT_EQ(nullptr, err) << *err;
/* Existent and non-existent files are not the same */
EXPECT_FALSE(tr_sys_path_is_same(path1.c_str(), path2.c_str(), &err));
EXPECT_EQ(nullptr, err);
EXPECT_EQ(nullptr, err) << *err;
EXPECT_FALSE(tr_sys_path_is_same(path2.c_str(), path1.c_str(), &err));
EXPECT_EQ(nullptr, err);
EXPECT_EQ(nullptr, err) << *err;
/* Two separate files (even with same content) are not the same */
createFileWithContents(path2, "test");
EXPECT_FALSE(tr_sys_path_is_same(path1.c_str(), path2.c_str(), &err));
EXPECT_EQ(nullptr, err);
EXPECT_EQ(nullptr, err) << *err;
tr_sys_path_remove(path1.c_str(), nullptr);
/* Two same directories are the same */
tr_sys_dir_create(path1.c_str(), 0, 0777, nullptr);
EXPECT_TRUE(tr_sys_path_is_same(path1.c_str(), path1.c_str(), &err));
EXPECT_EQ(nullptr, err);
EXPECT_EQ(nullptr, err) << *err;
/* File and directory are not the same */
EXPECT_FALSE(tr_sys_path_is_same(path1.c_str(), path2.c_str(), &err));
EXPECT_EQ(nullptr, err);
EXPECT_EQ(nullptr, err) << *err;
EXPECT_FALSE(tr_sys_path_is_same(path2.c_str(), path1.c_str(), &err));
EXPECT_EQ(nullptr, err);
EXPECT_EQ(nullptr, err) << *err;
tr_sys_path_remove(path2.c_str(), nullptr);
/* Two separate directories are not the same */
tr_sys_dir_create(path2.c_str(), 0, 0777, nullptr);
EXPECT_FALSE(tr_sys_path_is_same(path1.c_str(), path2.c_str(), &err));
EXPECT_EQ(nullptr, err);
EXPECT_EQ(nullptr, err) << *err;
tr_sys_path_remove(path1.c_str(), nullptr);
tr_sys_path_remove(path2.c_str(), nullptr);
@ -483,61 +484,61 @@ TEST_F(FileTest, pathIsSame)
{
/* Directory and symlink pointing to it are the same */
EXPECT_TRUE(tr_sys_path_is_same(path1.c_str(), test_dir.data(), &err));
EXPECT_EQ(nullptr, err);
EXPECT_EQ(nullptr, err) << *err;
EXPECT_TRUE(tr_sys_path_is_same(test_dir.data(), path1.c_str(), &err));
EXPECT_EQ(nullptr, err);
EXPECT_EQ(nullptr, err) << *err;
/* Non-existent file and symlink are not the same */
EXPECT_FALSE(tr_sys_path_is_same(path1.c_str(), path2.c_str(), &err));
EXPECT_EQ(nullptr, err);
EXPECT_EQ(nullptr, err) << *err;
EXPECT_FALSE(tr_sys_path_is_same(path2.c_str(), path1.c_str(), &err));
EXPECT_EQ(nullptr, err);
EXPECT_EQ(nullptr, err) << *err;
/* Symlinks pointing to different directories are not the same */
createSymlink(path2.c_str(), "..", true);
EXPECT_FALSE(tr_sys_path_is_same(path1.c_str(), path2.c_str(), &err));
EXPECT_EQ(nullptr, err);
EXPECT_EQ(nullptr, err) << *err;
EXPECT_FALSE(tr_sys_path_is_same(path2.c_str(), path1.c_str(), &err));
EXPECT_EQ(nullptr, err);
EXPECT_EQ(nullptr, err) << *err;
tr_sys_path_remove(path2.c_str(), nullptr);
/* Symlinks pointing to same directory are the same */
createSymlink(path2.c_str(), ".", true);
EXPECT_TRUE(tr_sys_path_is_same(path1.c_str(), path2.c_str(), &err));
EXPECT_EQ(nullptr, err);
EXPECT_EQ(nullptr, err) << *err;
tr_sys_path_remove(path2.c_str(), nullptr);
/* Directory and symlink pointing to another directory are not the same */
tr_sys_dir_create(path2.c_str(), 0, 0777, nullptr);
EXPECT_FALSE(tr_sys_path_is_same(path1.c_str(), path2.c_str(), &err));
EXPECT_EQ(nullptr, err);
EXPECT_EQ(nullptr, err) << *err;
EXPECT_FALSE(tr_sys_path_is_same(path2.c_str(), path1.c_str(), &err));
EXPECT_EQ(nullptr, err);
EXPECT_EQ(nullptr, err) << *err;
/* Symlinks pointing to same directory are the same */
createSymlink(path3.c_str(), "..", true);
EXPECT_TRUE(tr_sys_path_is_same(path1.c_str(), path3.c_str(), &err));
EXPECT_EQ(nullptr, err);
EXPECT_EQ(nullptr, err) << *err;
tr_sys_path_remove(path1.c_str(), nullptr);
/* File and symlink pointing to directory are not the same */
createFileWithContents(path1, "test");
EXPECT_FALSE(tr_sys_path_is_same(path1.c_str(), path3.c_str(), &err));
EXPECT_EQ(nullptr, err);
EXPECT_EQ(nullptr, err) << *err;
EXPECT_FALSE(tr_sys_path_is_same(path3.c_str(), path1.c_str(), &err));
EXPECT_EQ(nullptr, err);
EXPECT_EQ(nullptr, err) << *err;
tr_sys_path_remove(path3.c_str(), nullptr);
/* File and symlink pointing to same file are the same */
createSymlink(path3.c_str(), path1.c_str(), false);
EXPECT_TRUE(tr_sys_path_is_same(path1.c_str(), path3.c_str(), &err));
EXPECT_EQ(nullptr, err);
EXPECT_EQ(nullptr, err) << *err;
EXPECT_TRUE(tr_sys_path_is_same(path3.c_str(), path1.c_str(), &err));
EXPECT_EQ(nullptr, err);
EXPECT_EQ(nullptr, err) << *err;
/* Symlinks pointing to non-existent files are not the same */
tr_sys_path_remove(path1.c_str(), nullptr);
@ -545,25 +546,25 @@ TEST_F(FileTest, pathIsSame)
tr_sys_path_remove(path3.c_str(), nullptr);
createSymlink(path3.c_str(), "missing", false);
EXPECT_FALSE(tr_sys_path_is_same(path1.c_str(), path3.c_str(), &err));
EXPECT_EQ(nullptr, err);
EXPECT_EQ(nullptr, err) << *err;
EXPECT_FALSE(tr_sys_path_is_same(path3.c_str(), path1.c_str(), &err));
EXPECT_EQ(nullptr, err);
EXPECT_EQ(nullptr, err) << *err;
tr_sys_path_remove(path3.c_str(), nullptr);
/* Symlinks pointing to same non-existent file are not the same */
createSymlink(path3.c_str(), ".." NATIVE_PATH_SEP "missing", false);
EXPECT_FALSE(tr_sys_path_is_same(path1.c_str(), path3.c_str(), &err));
EXPECT_EQ(nullptr, err);
EXPECT_EQ(nullptr, err) << *err;
EXPECT_FALSE(tr_sys_path_is_same(path3.c_str(), path1.c_str(), &err));
EXPECT_EQ(nullptr, err);
EXPECT_EQ(nullptr, err) << *err;
/* Non-existent file and symlink pointing to non-existent file are not the same */
tr_sys_path_remove(path3.c_str(), nullptr);
EXPECT_FALSE(tr_sys_path_is_same(path1.c_str(), path3.c_str(), &err));
EXPECT_EQ(nullptr, err);
EXPECT_EQ(nullptr, err) << *err;
EXPECT_FALSE(tr_sys_path_is_same(path3.c_str(), path1.c_str(), &err));
EXPECT_EQ(nullptr, err);
EXPECT_EQ(nullptr, err) << *err;
tr_sys_path_remove(path2.c_str(), nullptr);
tr_sys_path_remove(path1.c_str(), nullptr);
@ -581,19 +582,19 @@ TEST_F(FileTest, pathIsSame)
{
/* File and hardlink to it are the same */
EXPECT_TRUE(tr_sys_path_is_same(path1.c_str(), path2.c_str(), &err));
EXPECT_EQ(nullptr, err);
EXPECT_EQ(nullptr, err) << *err;
/* Two hardlinks to the same file are the same */
createHardlink(path3.c_str(), path2.c_str());
EXPECT_TRUE(tr_sys_path_is_same(path2.c_str(), path3.c_str(), &err));
EXPECT_EQ(nullptr, err);
EXPECT_EQ(nullptr, err) << *err;
EXPECT_TRUE(tr_sys_path_is_same(path1.c_str(), path3.c_str(), &err));
EXPECT_EQ(nullptr, err);
EXPECT_EQ(nullptr, err) << *err;
tr_sys_path_remove(path2.c_str(), nullptr);
EXPECT_TRUE(tr_sys_path_is_same(path1.c_str(), path3.c_str(), &err));
EXPECT_EQ(nullptr, err);
EXPECT_EQ(nullptr, err) << *err;
tr_sys_path_remove(path3.c_str(), nullptr);
@ -601,9 +602,9 @@ TEST_F(FileTest, pathIsSame)
createFileWithContents(path3, "test");
createHardlink(path2.c_str(), path3.c_str());
EXPECT_FALSE(tr_sys_path_is_same(path1.c_str(), path2.c_str(), &err));
EXPECT_EQ(nullptr, err);
EXPECT_EQ(nullptr, err) << *err;
EXPECT_FALSE(tr_sys_path_is_same(path2.c_str(), path1.c_str(), &err));
EXPECT_EQ(nullptr, err);
EXPECT_EQ(nullptr, err) << *err;
tr_sys_path_remove(path3.c_str(), nullptr);
tr_sys_path_remove(path2.c_str(), nullptr);
@ -616,7 +617,7 @@ TEST_F(FileTest, pathIsSame)
if (createSymlink(path2.c_str(), path1.c_str(), false) && createHardlink(path3.c_str(), path1.c_str()))
{
EXPECT_TRUE(tr_sys_path_is_same(path2.c_str(), path3.c_str(), &err));
EXPECT_EQ(nullptr, err);
EXPECT_EQ(nullptr, err) << *err;
}
else
{
@ -641,7 +642,7 @@ TEST_F(FileTest, pathResolve)
if (createSymlink(path2.c_str(), path1.c_str(), false))
{
auto tmp = makeString(tr_sys_path_resolve(path2.c_str(), &err));
EXPECT_EQ(nullptr, err);
EXPECT_EQ(nullptr, err) << *err;
EXPECT_TRUE(pathContainsNoSymlinks(tmp.c_str()));
tr_sys_path_remove(path2.c_str(), nullptr);
@ -650,7 +651,7 @@ TEST_F(FileTest, pathResolve)
tr_sys_dir_create(path1.c_str(), 0, 0755, nullptr);
EXPECT_TRUE(createSymlink(path2.c_str(), path1.c_str(), true)); /* Win32: directory and file symlinks differ :( */
tmp = makeString(tr_sys_path_resolve(path2.c_str(), &err));
EXPECT_EQ(nullptr, err);
EXPECT_EQ(nullptr, err) << *err;
EXPECT_TRUE(pathContainsNoSymlinks(tmp.c_str()));
}
else
@ -678,7 +679,7 @@ TEST_F(FileTest, pathResolve)
tmp = tr_sys_path_resolve("\\\\127.0.0.1\\ADMIN$\\System32", &err);
EXPECT_STREQ("\\\\127.0.0.1\\ADMIN$\\System32", tmp);
EXPECT_EQ(nullptr, err);
EXPECT_EQ(nullptr, err) << *err;
tr_free(tmp);
}
@ -802,13 +803,13 @@ TEST_F(FileTest, pathRename)
EXPECT_TRUE(tr_sys_path_rename(path1.c_str(), path2.c_str(), &err));
EXPECT_FALSE(tr_sys_path_exists(path1.c_str(), nullptr));
EXPECT_TRUE(tr_sys_path_exists(path2.c_str(), nullptr));
EXPECT_EQ(nullptr, err);
EXPECT_EQ(nullptr, err) << *err;
/* Backward rename works */
EXPECT_TRUE(tr_sys_path_rename(path2.c_str(), path1.c_str(), &err));
EXPECT_TRUE(tr_sys_path_exists(path1.c_str(), nullptr));
EXPECT_FALSE(tr_sys_path_exists(path2.c_str(), nullptr));
EXPECT_EQ(nullptr, err);
EXPECT_EQ(nullptr, err) << *err;
/* Another backward rename [of non-existent file] does not work */
EXPECT_FALSE(tr_sys_path_rename(path2.c_str(), path1.c_str(), &err));
@ -829,7 +830,7 @@ TEST_F(FileTest, pathRename)
/* Renaming file does overwrite existing file */
EXPECT_TRUE(tr_sys_path_rename(path2.c_str(), path1.c_str(), &err));
EXPECT_EQ(nullptr, err);
EXPECT_EQ(nullptr, err) << *err;
tr_sys_dir_create(path2.c_str(), 0, 0777, nullptr);
@ -854,7 +855,7 @@ TEST_F(FileTest, pathRename)
/* Rename of symlink works, files stay the same */
EXPECT_TRUE(tr_sys_path_rename(path2.c_str(), path3.c_str(), &err));
EXPECT_EQ(nullptr, err);
EXPECT_EQ(nullptr, err) << *err;
EXPECT_FALSE(tr_sys_path_exists(path2.c_str(), nullptr));
EXPECT_TRUE(tr_sys_path_exists(path3.c_str(), nullptr));
EXPECT_TRUE(tr_sys_path_is_same(path1.c_str(), path3.c_str(), nullptr));
@ -875,7 +876,7 @@ TEST_F(FileTest, pathRename)
/* Rename of hardlink works, files stay the same */
EXPECT_TRUE(tr_sys_path_rename(path2.c_str(), path3.c_str(), &err));
EXPECT_EQ(nullptr, err);
EXPECT_EQ(nullptr, err) << *err;
EXPECT_FALSE(tr_sys_path_exists(path2.c_str(), nullptr));
EXPECT_TRUE(tr_sys_path_exists(path3.c_str(), nullptr));
EXPECT_TRUE(tr_sys_path_is_same(path1.c_str(), path3.c_str(), nullptr));
@ -910,14 +911,14 @@ TEST_F(FileTest, pathRemove)
createFileWithContents(path1, "test");
EXPECT_TRUE(tr_sys_path_exists(path1.c_str(), nullptr));
EXPECT_TRUE(tr_sys_path_remove(path1.c_str(), &err));
EXPECT_EQ(nullptr, err);
EXPECT_EQ(nullptr, err) << *err;
EXPECT_FALSE(tr_sys_path_exists(path1.c_str(), nullptr));
/* Removing empty directory works */
tr_sys_dir_create(path1.c_str(), 0, 0777, nullptr);
EXPECT_TRUE(tr_sys_path_exists(path1.c_str(), nullptr));
EXPECT_TRUE(tr_sys_path_remove(path1.c_str(), &err));
EXPECT_EQ(nullptr, err);
EXPECT_EQ(nullptr, err) << *err;
EXPECT_FALSE(tr_sys_path_exists(path1.c_str(), nullptr));
/* Removing non-empty directory fails */
@ -996,7 +997,7 @@ TEST_F(FileTest, fileOpen)
// can create non-existent file
auto fd = tr_sys_file_open(path1.c_str(), TR_SYS_FILE_WRITE | TR_SYS_FILE_CREATE, 0640, &err);
EXPECT_NE(TR_BAD_SYS_FILE, fd);
EXPECT_EQ(nullptr, err);
EXPECT_EQ(nullptr, err) << *err;
tr_sys_file_close(fd, nullptr);
EXPECT_TRUE(tr_sys_path_exists(path1.c_str(), nullptr));
EXPECT_TRUE(validatePermissions(path1.c_str(), 0640));
@ -1005,11 +1006,11 @@ TEST_F(FileTest, fileOpen)
EXPECT_TRUE(tr_sys_path_exists(path1.c_str(), nullptr));
fd = tr_sys_file_open(path1.c_str(), TR_SYS_FILE_READ, 0600, &err);
EXPECT_NE(TR_BAD_SYS_FILE, fd);
EXPECT_EQ(nullptr, err);
EXPECT_EQ(nullptr, err) << *err;
tr_sys_file_close(fd, nullptr);
fd = tr_sys_file_open(path1.c_str(), TR_SYS_FILE_WRITE, 0600, &err);
EXPECT_NE(TR_BAD_SYS_FILE, fd);
EXPECT_EQ(nullptr, err);
EXPECT_EQ(nullptr, err) << *err;
tr_sys_file_close(fd, nullptr);
tr_sys_path_remove(path1.c_str(), nullptr);
@ -1029,7 +1030,7 @@ TEST_F(FileTest, fileOpen)
EXPECT_EQ(4, info.size);
fd = tr_sys_file_open(path1.c_str(), TR_SYS_FILE_WRITE | TR_SYS_FILE_APPEND, 0600, &err);
EXPECT_NE(TR_BAD_SYS_FILE, fd);
EXPECT_EQ(nullptr, err);
EXPECT_EQ(nullptr, err) << *err;
tr_sys_file_write(fd, "s", 1, nullptr, nullptr); /* On *NIX, pointer is positioned on each write but not initially */
auto n = uint64_t{};
tr_sys_file_seek(fd, 0, TR_SEEK_CUR, &n, nullptr);
@ -1041,7 +1042,7 @@ TEST_F(FileTest, fileOpen)
EXPECT_EQ(5, info.size);
fd = tr_sys_file_open(path1.c_str(), TR_SYS_FILE_WRITE | TR_SYS_FILE_TRUNCATE, 0600, &err);
EXPECT_NE(TR_BAD_SYS_FILE, fd);
EXPECT_EQ(nullptr, err);
EXPECT_EQ(nullptr, err) << *err;
tr_sys_file_get_info(fd, &info, nullptr);
EXPECT_EQ(0, info.size);
tr_sys_file_close(fd, nullptr);
@ -1063,70 +1064,70 @@ TEST_F(FileTest, fileReadWriteSeek)
uint64_t n;
tr_error* err = nullptr;
EXPECT_TRUE(tr_sys_file_seek(fd, 0, TR_SEEK_CUR, &n, &err));
EXPECT_EQ(nullptr, err);
EXPECT_EQ(nullptr, err) << *err;
EXPECT_EQ(0, n);
EXPECT_TRUE(tr_sys_file_write(fd, "test", 4, &n, &err));
EXPECT_EQ(nullptr, err);
EXPECT_EQ(nullptr, err) << *err;
EXPECT_EQ(4, n);
EXPECT_TRUE(tr_sys_file_seek(fd, 0, TR_SEEK_CUR, &n, &err));
EXPECT_EQ(nullptr, err);
EXPECT_EQ(nullptr, err) << *err;
EXPECT_EQ(4, n);
EXPECT_TRUE(tr_sys_file_seek(fd, 0, TR_SEEK_SET, &n, &err));
EXPECT_EQ(nullptr, err);
EXPECT_EQ(nullptr, err) << *err;
EXPECT_EQ(0, n);
auto buf = std::array<char, 100>{};
EXPECT_TRUE(tr_sys_file_read(fd, buf.data(), buf.size(), &n, &err));
EXPECT_EQ(nullptr, err);
EXPECT_EQ(nullptr, err) << *err;
EXPECT_EQ(4, n);
EXPECT_EQ(0, memcmp("test", buf.data(), 4));
EXPECT_TRUE(tr_sys_file_seek(fd, -3, TR_SEEK_CUR, &n, &err));
EXPECT_EQ(nullptr, err);
EXPECT_EQ(nullptr, err) << *err;
EXPECT_EQ(1, n);
EXPECT_TRUE(tr_sys_file_write(fd, "E", 1, &n, &err));
EXPECT_EQ(nullptr, err);
EXPECT_EQ(nullptr, err) << *err;
EXPECT_EQ(1, n);
EXPECT_TRUE(tr_sys_file_seek(fd, -2, TR_SEEK_CUR, &n, &err));
EXPECT_EQ(nullptr, err);
EXPECT_EQ(nullptr, err) << *err;
EXPECT_EQ(0, n);
EXPECT_TRUE(tr_sys_file_read(fd, buf.data(), buf.size(), &n, &err));
EXPECT_EQ(nullptr, err);
EXPECT_EQ(nullptr, err) << *err;
EXPECT_EQ(4, n);
EXPECT_EQ(0, memcmp("tEst", buf.data(), 4));
EXPECT_TRUE(tr_sys_file_seek(fd, 0, TR_SEEK_END, &n, &err));
EXPECT_EQ(nullptr, err);
EXPECT_EQ(nullptr, err) << *err;
EXPECT_EQ(4, n);
EXPECT_TRUE(tr_sys_file_write(fd, " ok", 3, &n, &err));
EXPECT_EQ(nullptr, err);
EXPECT_EQ(nullptr, err) << *err;
EXPECT_EQ(3, n);
EXPECT_TRUE(tr_sys_file_seek(fd, 0, TR_SEEK_SET, &n, &err));
EXPECT_EQ(nullptr, err);
EXPECT_EQ(nullptr, err) << *err;
EXPECT_EQ(0, n);
EXPECT_TRUE(tr_sys_file_read(fd, buf.data(), buf.size(), &n, &err));
EXPECT_EQ(nullptr, err);
EXPECT_EQ(nullptr, err) << *err;
EXPECT_EQ(7, n);
EXPECT_EQ(0, memcmp("tEst ok", buf.data(), 7));
EXPECT_TRUE(tr_sys_file_write_at(fd, "-", 1, 4, &n, &err));
EXPECT_EQ(nullptr, err);
EXPECT_EQ(nullptr, err) << *err;
EXPECT_EQ(1, n);
EXPECT_TRUE(tr_sys_file_read_at(fd, buf.data(), 5, 2, &n, &err));
EXPECT_EQ(nullptr, err);
EXPECT_EQ(nullptr, err) << *err;
EXPECT_EQ(5, n);
EXPECT_EQ(0, memcmp("st-ok", buf.data(), 5));
@ -1145,23 +1146,23 @@ TEST_F(FileTest, fileTruncate)
tr_error* err = nullptr;
EXPECT_TRUE(tr_sys_file_truncate(fd, 10, &err));
EXPECT_EQ(nullptr, err);
EXPECT_EQ(nullptr, err) << *err;
tr_sys_path_info info;
tr_sys_file_get_info(fd, &info, nullptr);
EXPECT_EQ(10, info.size);
EXPECT_TRUE(tr_sys_file_truncate(fd, 20, &err));
EXPECT_EQ(nullptr, err);
EXPECT_EQ(nullptr, err) << *err;
tr_sys_file_get_info(fd, &info, nullptr);
EXPECT_EQ(20, info.size);
EXPECT_TRUE(tr_sys_file_truncate(fd, 0, &err));
EXPECT_EQ(nullptr, err);
EXPECT_EQ(nullptr, err) << *err;
tr_sys_file_get_info(fd, &info, nullptr);
EXPECT_EQ(0, info.size);
EXPECT_TRUE(tr_sys_file_truncate(fd, 50, &err));
EXPECT_EQ(nullptr, err);
EXPECT_EQ(nullptr, err) << *err;
tr_sys_file_close(fd, nullptr);
@ -1171,7 +1172,7 @@ TEST_F(FileTest, fileTruncate)
fd = tr_sys_file_open(path1.c_str(), TR_SYS_FILE_WRITE | TR_SYS_FILE_CREATE, 0600, nullptr);
EXPECT_TRUE(tr_sys_file_truncate(fd, 25, &err));
EXPECT_EQ(nullptr, err);
EXPECT_EQ(nullptr, err) << *err;
tr_sys_file_close(fd, nullptr);
@ -1192,7 +1193,7 @@ TEST_F(FileTest, filePreallocate)
auto prealloc_size = size_t{ 50 };
if (tr_sys_file_preallocate(fd, prealloc_size, 0, &err))
{
EXPECT_EQ(nullptr, err);
EXPECT_EQ(nullptr, err) << *err;
tr_sys_path_info info;
tr_sys_file_get_info(fd, &info, nullptr);
EXPECT_EQ(prealloc_size, info.size);
@ -1213,14 +1214,14 @@ TEST_F(FileTest, filePreallocate)
prealloc_size = 500 * 1024 * 1024;
if (tr_sys_file_preallocate(fd, prealloc_size, TR_SYS_FILE_PREALLOC_SPARSE, &err))
{
EXPECT_EQ(nullptr, err);
EXPECT_EQ(nullptr, err) << *err;
tr_sys_path_info info;
tr_sys_file_get_info(fd, &info, nullptr);
EXPECT_EQ(prealloc_size, info.size);
}
else
{
EXPECT_NE(nullptr, err);
EXPECT_NE(nullptr, err) << *err;
fprintf(stderr, "WARNING: [%s] unable to preallocate file (sparse): %s (%d)\n", __FUNCTION__, err->message, err->code);
tr_error_clear(&err);
}
@ -1244,7 +1245,7 @@ TEST_F(FileTest, map)
auto map_len = contents.size();
auto* view = static_cast<char*>(tr_sys_file_map_for_reading(fd, 0, map_len, &err));
EXPECT_NE(nullptr, view);
EXPECT_EQ(nullptr, err);
EXPECT_EQ(nullptr, err) << *err;
EXPECT_EQ(contents, std::string(view, map_len));
#ifdef HAVE_UNIFIED_BUFFER_CACHE
@ -1254,13 +1255,13 @@ TEST_F(FileTest, map)
tr_sys_file_write_at(fd, contents_2.data(), contents_2.size(), 0, &n_written, &err);
EXPECT_EQ(map_len, contents_2.size());
EXPECT_EQ(map_len, n_written);
EXPECT_EQ(nullptr, err);
EXPECT_EQ(nullptr, err) << *err;
EXPECT_EQ(contents_2, std::string(view, map_len));
#endif
EXPECT_TRUE(tr_sys_file_unmap(view, map_len, &err));
EXPECT_EQ(nullptr, err);
EXPECT_EQ(nullptr, err) << *err;
tr_sys_file_close(fd, nullptr);
@ -1280,31 +1281,31 @@ TEST_F(FileTest, fileUtilities)
tr_error* err = nullptr;
auto buffer = std::array<char, 16>{};
EXPECT_TRUE(tr_sys_file_read_line(fd, buffer.data(), buffer.size(), &err));
EXPECT_EQ(nullptr, err);
EXPECT_EQ(nullptr, err) << *err;
EXPECT_STREQ("a", buffer.data());
EXPECT_TRUE(tr_sys_file_read_line(fd, buffer.data(), buffer.size(), &err));
EXPECT_EQ(nullptr, err);
EXPECT_EQ(nullptr, err) << *err;
EXPECT_STREQ("bc", buffer.data());
EXPECT_TRUE(tr_sys_file_read_line(fd, buffer.data(), buffer.size(), &err));
EXPECT_EQ(nullptr, err);
EXPECT_EQ(nullptr, err) << *err;
EXPECT_STREQ("def", buffer.data());
EXPECT_TRUE(tr_sys_file_read_line(fd, buffer.data(), buffer.size(), &err));
EXPECT_EQ(nullptr, err);
EXPECT_EQ(nullptr, err) << *err;
EXPECT_STREQ("ghij", buffer.data());
EXPECT_TRUE(tr_sys_file_read_line(fd, buffer.data(), buffer.size(), &err));
EXPECT_EQ(nullptr, err);
EXPECT_EQ(nullptr, err) << *err;
EXPECT_STREQ("", buffer.data());
EXPECT_TRUE(tr_sys_file_read_line(fd, buffer.data(), buffer.size(), &err));
EXPECT_EQ(nullptr, err);
EXPECT_EQ(nullptr, err) << *err;
EXPECT_STREQ("", buffer.data());
EXPECT_TRUE(tr_sys_file_read_line(fd, buffer.data(), 4, &err));
EXPECT_EQ(nullptr, err);
EXPECT_EQ(nullptr, err) << *err;
EXPECT_STREQ("klmn", buffer.data());
EXPECT_TRUE(tr_sys_file_read_line(fd, buffer.data(), buffer.size(), &err));
EXPECT_EQ(nullptr, err);
EXPECT_EQ(nullptr, err) << *err;
EXPECT_STREQ("o", buffer.data());
EXPECT_FALSE(tr_sys_file_read_line(fd, buffer.data(), buffer.size(), &err));
EXPECT_EQ(nullptr, err);
EXPECT_EQ(nullptr, err) << *err;
EXPECT_STREQ("o", buffer.data()); // on EOF, buffer stays unchanged
tr_sys_file_close(fd, nullptr);
@ -1312,45 +1313,45 @@ TEST_F(FileTest, fileUtilities)
fd = tr_sys_file_open(path1.c_str(), TR_SYS_FILE_READ | TR_SYS_FILE_WRITE | TR_SYS_FILE_TRUNCATE, 0, nullptr);
EXPECT_TRUE(tr_sys_file_write_line(fd, "p", &err));
EXPECT_EQ(nullptr, err);
EXPECT_EQ(nullptr, err) << *err;
EXPECT_TRUE(tr_sys_file_write_line(fd, "", &err));
EXPECT_EQ(nullptr, err);
EXPECT_EQ(nullptr, err) << *err;
EXPECT_TRUE(tr_sys_file_write_line(fd, "qr", &err));
EXPECT_EQ(nullptr, err);
EXPECT_EQ(nullptr, err) << *err;
EXPECT_TRUE(tr_sys_file_write_line(fd, "stu", &err));
EXPECT_EQ(nullptr, err);
EXPECT_EQ(nullptr, err) << *err;
EXPECT_TRUE(tr_sys_file_write_line(fd, "", &err));
EXPECT_EQ(nullptr, err);
EXPECT_EQ(nullptr, err) << *err;
EXPECT_TRUE(tr_sys_file_write_line(fd, "", &err));
EXPECT_EQ(nullptr, err);
EXPECT_EQ(nullptr, err) << *err;
EXPECT_TRUE(tr_sys_file_write_line(fd, "vwxy2", &err));
EXPECT_EQ(nullptr, err);
EXPECT_EQ(nullptr, err) << *err;
tr_sys_file_seek(fd, 0, TR_SEEK_SET, nullptr, nullptr);
EXPECT_TRUE(tr_sys_file_read_line(fd, buffer.data(), buffer.size(), &err));
EXPECT_EQ(nullptr, err);
EXPECT_EQ(nullptr, err) << *err;
EXPECT_STREQ("p", buffer.data());
EXPECT_TRUE(tr_sys_file_read_line(fd, buffer.data(), buffer.size(), &err));
EXPECT_EQ(nullptr, err);
EXPECT_EQ(nullptr, err) << *err;
EXPECT_STREQ("", buffer.data());
EXPECT_TRUE(tr_sys_file_read_line(fd, buffer.data(), buffer.size(), &err));
EXPECT_EQ(nullptr, err);
EXPECT_EQ(nullptr, err) << *err;
EXPECT_STREQ("qr", buffer.data());
EXPECT_TRUE(tr_sys_file_read_line(fd, buffer.data(), buffer.size(), &err));
EXPECT_EQ(nullptr, err);
EXPECT_EQ(nullptr, err) << *err;
EXPECT_STREQ("stu", buffer.data());
EXPECT_TRUE(tr_sys_file_read_line(fd, buffer.data(), buffer.size(), &err));
EXPECT_EQ(nullptr, err);
EXPECT_EQ(nullptr, err) << *err;
EXPECT_STREQ("", buffer.data());
EXPECT_TRUE(tr_sys_file_read_line(fd, buffer.data(), buffer.size(), &err));
EXPECT_EQ(nullptr, err);
EXPECT_EQ(nullptr, err) << *err;
EXPECT_STREQ("", buffer.data());
EXPECT_TRUE(tr_sys_file_read_line(fd, buffer.data(), buffer.size(), &err));
EXPECT_EQ(nullptr, err);
EXPECT_EQ(nullptr, err) << *err;
EXPECT_STREQ("vwxy2", buffer.data());
EXPECT_FALSE(tr_sys_file_read_line(fd, buffer.data(), buffer.size(), &err));
EXPECT_EQ(nullptr, err);
EXPECT_EQ(nullptr, err) << *err;
EXPECT_STREQ("vwxy2", buffer.data()); // on EOF, buffer stays unchanged
tr_sys_file_close(fd, nullptr);
@ -1368,7 +1369,7 @@ TEST_F(FileTest, dirCreate)
// Can create directory which has parent
tr_error* err = nullptr;
EXPECT_TRUE(tr_sys_dir_create(path1.c_str(), 0, 0700, &err));
EXPECT_EQ(nullptr, err);
EXPECT_EQ(nullptr, err) << *err;
EXPECT_TRUE(tr_sys_path_exists(path1.c_str(), nullptr));
EXPECT_TRUE(validatePermissions(path1.c_str(), 0700));
@ -1393,7 +1394,7 @@ TEST_F(FileTest, dirCreate)
// Can create directory with parent directories
EXPECT_TRUE(tr_sys_dir_create(path2.c_str(), TR_SYS_DIR_CREATE_PARENTS, 0751, &err));
EXPECT_EQ(nullptr, err);
EXPECT_EQ(nullptr, err) << *err;
EXPECT_TRUE(tr_sys_path_exists(path1.c_str(), nullptr));
EXPECT_TRUE(tr_sys_path_exists(path2.c_str(), nullptr));
EXPECT_TRUE(validatePermissions(path1.c_str(), 0751));
@ -1401,9 +1402,9 @@ TEST_F(FileTest, dirCreate)
// Can create existing directory (no-op)
EXPECT_TRUE(tr_sys_dir_create(path1.c_str(), 0, 0700, &err));
EXPECT_EQ(nullptr, err);
EXPECT_EQ(nullptr, err) << *err;
EXPECT_TRUE(tr_sys_dir_create(path1.c_str(), TR_SYS_DIR_CREATE_PARENTS, 0700, &err));
EXPECT_EQ(nullptr, err);
EXPECT_EQ(nullptr, err) << *err;
tr_sys_path_remove(path2.c_str(), nullptr);
tr_sys_path_remove(path1.c_str(), nullptr);

View File

@ -85,13 +85,13 @@ protected:
// quick check of some of the parsed metainfo
EXPECT_EQ(payloadSize, metainfo.totalSize());
EXPECT_EQ(makeString(tr_sys_path_basename(input_file.data(), nullptr)), metainfo.name());
EXPECT_EQ(tr_sys_path_basename(input_file), metainfo.name());
EXPECT_EQ(comment, metainfo.comment());
EXPECT_EQ(isPrivate, metainfo.isPrivate());
EXPECT_EQ(size_t(trackerCount), std::size(metainfo.announceList()));
EXPECT_EQ(size_t(webseedCount), metainfo.webseedCount());
EXPECT_EQ(tr_file_index_t{ 1 }, metainfo.fileCount());
EXPECT_EQ(makeString(tr_sys_path_basename(input_file.data(), nullptr)), metainfo.fileSubpath(0));
EXPECT_EQ(tr_sys_path_basename(input_file), metainfo.fileSubpath(0));
EXPECT_EQ(payloadSize, metainfo.fileSize(0));
// cleanup
@ -177,9 +177,7 @@ protected:
// quick check of some of the parsed metainfo
EXPECT_EQ(total_size, metainfo.totalSize());
auto* tmpstr = tr_sys_path_basename(top.c_str(), nullptr);
EXPECT_EQ(tmpstr, metainfo.name());
tr_free(tmpstr);
EXPECT_EQ(tr_sys_path_basename(top), metainfo.name());
EXPECT_EQ(comment, metainfo.comment());
EXPECT_EQ(source, metainfo.source());
EXPECT_EQ(payload_count, metainfo.fileCount());

View File

@ -3,6 +3,7 @@
// or any future license endorsed by Mnemosyne LLC.
// License text can be found in the licenses/ folder.
#include <iostream>
#include <string>
#include <utility>
@ -23,6 +24,8 @@ namespace libtransmission
namespace test
{
auto constexpr MaxWaitMsec = 5000;
class IncompleteDirTest
: public SessionTest
, public ::testing::WithParamInterface<std::pair<std::string, std::string>>
@ -30,10 +33,10 @@ class IncompleteDirTest
protected:
void SetUp() override
{
auto const incomplete_dir = GetParam().first;
auto const download_dir = GetParam().second;
tr_variantDictAddStr(settings(), TR_KEY_download_dir, download_dir.data());
tr_variantDictAddStr(settings(), TR_KEY_incomplete_dir, incomplete_dir.data());
tr_variantDictAddStr(settings(), TR_KEY_download_dir, download_dir.c_str());
auto const incomplete_dir = GetParam().first;
tr_variantDictAddStr(settings(), TR_KEY_incomplete_dir, incomplete_dir.c_str());
tr_variantDictAddBool(settings(), TR_KEY_incomplete_dir_enabled, true);
SessionTest::SetUp();
@ -126,7 +129,7 @@ TEST_P(IncompleteDirTest, incompleteDir)
{
return completeness != -1;
};
EXPECT_TRUE(waitFor(test, 300));
EXPECT_TRUE(waitFor(test, MaxWaitMsec));
EXPECT_EQ(TR_SEED, completeness);
auto const n = tr_torrentFileCount(tor);
@ -174,7 +177,7 @@ TEST_F(MoveTest, setLocation)
{
return state == TR_LOC_DONE;
};
EXPECT_TRUE(waitFor(test, 300));
EXPECT_TRUE(waitFor(test, MaxWaitMsec));
EXPECT_EQ(TR_LOC_DONE, state);
// confirm the torrent is still complete after being moved

View File

@ -74,7 +74,7 @@ protected:
EXPECT_LT(0, std::size(benc));
tr_error* error = nullptr;
EXPECT_TRUE(tr_ctorSetMetainfo(ctor, std::data(benc), std::size(benc), &error));
EXPECT_EQ(nullptr, error);
EXPECT_EQ(nullptr, error) << *error;
tr_ctorSetPaused(ctor, TR_FORCE, true);
// create the torrent
@ -348,9 +348,7 @@ TEST_F(RenameTest, multifileTorrent)
str = tr_torrentFindFile(tor, 2);
EXPECT_NE(nullptr, str);
tr_sys_path_remove(str, nullptr);
auto* tmp = tr_sys_path_dirname(str, nullptr);
tr_sys_path_remove(tmp, nullptr);
tr_free(tmp);
tr_sys_path_remove(tr_sys_path_dirname(str).c_str(), nullptr);
tr_free(str);
sync();
blockingTorrentVerify(tor);

View File

@ -32,7 +32,7 @@ namespace test
std::string getTestProgramPath(std::string const& filename)
{
auto const exe_path = makeString(tr_sys_path_resolve(testing::internal::GetArgvs().front().data(), nullptr));
auto const exe_dir = makeString(tr_sys_path_dirname(exe_path.data(), nullptr));
auto const exe_dir = tr_sys_path_dirname(exe_path);
return exe_dir + TR_PATH_DELIMITER + filename;
}
@ -118,7 +118,7 @@ TEST_P(SubprocessTest, SpawnAsyncArgs)
tr_error* error = nullptr;
bool const ret = tr_spawn_async(std::data(args), {}, nullptr, &error);
EXPECT_TRUE(ret) << args[0] << ' ' << args[1];
EXPECT_EQ(nullptr, error) << error->code << ", " << error->message;
EXPECT_EQ(nullptr, error) << *error;
waitForFileToExist(result_path);
@ -199,7 +199,7 @@ TEST_P(SubprocessTest, SpawnAsyncEnv)
tr_error* error = nullptr;
bool const ret = tr_spawn_async(std::data(args), env, nullptr, &error);
EXPECT_TRUE(ret);
EXPECT_EQ(nullptr, error);
EXPECT_EQ(nullptr, error) << *error;
waitForFileToExist(result_path);
@ -247,7 +247,7 @@ TEST_P(SubprocessTest, SpawnAsyncCwdExplicit)
tr_error* error = nullptr;
bool const ret = tr_spawn_async(std::data(args), {}, test_dir.c_str(), &error);
EXPECT_TRUE(ret);
EXPECT_EQ(nullptr, error);
EXPECT_EQ(nullptr, error) << *error;
waitForFileToExist(result_path);
@ -275,7 +275,7 @@ TEST_P(SubprocessTest, SpawnAsyncCwdInherit)
tr_error* error = nullptr;
auto const ret = tr_spawn_async(std::data(args), {}, nullptr, &error);
EXPECT_TRUE(ret);
EXPECT_EQ(nullptr, error);
EXPECT_EQ(nullptr, error) << *error;
waitForFileToExist(result_path);
auto fd = tr_sys_file_open(result_path.data(), TR_SYS_FILE_READ, 0, nullptr); // NOLINT

View File

@ -8,6 +8,7 @@
#include <chrono>
#include <cstdlib> // getenv()
#include <cstring> // strlen()
#include <iostream>
#include <memory>
#include <mutex> // std::once_flag()
#include <string>
@ -25,6 +26,12 @@
#include "gtest/gtest.h"
inline std::ostream& operator<<(std::ostream& os, tr_error const& err)
{
os << err.message << ' ' << err.code;
return os;
}
namespace libtransmission
{
@ -176,10 +183,10 @@ protected:
{
auto const tmperr = errno;
auto const dir = makeString(tr_sys_path_dirname(path.c_str(), nullptr));
auto const dir = tr_sys_path_dirname(path);
tr_error* error = nullptr;
tr_sys_dir_create(dir.data(), TR_SYS_DIR_CREATE_PARENTS, 0700, &error);
EXPECT_EQ(nullptr, error) << "path[" << path << "] dir[" << dir << "] " << error->code << ", " << error->message;
EXPECT_EQ(nullptr, error) << "path[" << path << "] dir[" << dir << "] " << *error;
errno = tmperr;
}
@ -376,7 +383,7 @@ protected:
auto* ctor = tr_ctorNew(session_);
tr_error* error = nullptr;
EXPECT_TRUE(tr_ctorSetMetainfo(ctor, std::data(metainfo), std::size(metainfo), &error));
EXPECT_EQ(nullptr, error);
EXPECT_EQ(nullptr, error) << *error;
tr_ctorSetPaused(ctor, TR_FORCE, true);
// create the torrent
@ -397,7 +404,7 @@ protected:
auto path = (!complete && i == 0) ? tr_strvJoin(tor->currentDir().sv(), TR_PATH_DELIMITER_STR, file.name, ".part") :
tr_strvJoin(tor->currentDir().sv(), TR_PATH_DELIMITER_STR, file.name);
auto const dirname = makeString(tr_sys_path_dirname(path.c_str(), nullptr));
auto const dirname = tr_sys_path_dirname(path);
tr_sys_dir_create(dirname.data(), TR_SYS_DIR_CREATE_PARENTS, 0700, nullptr);
auto fd = tr_sys_file_open(
path.c_str(),

View File

@ -148,7 +148,7 @@ TEST_F(TorrentMetainfoTest, AndroidTorrent)
auto* ctor = tr_ctorNew(session_);
tr_error* error = nullptr;
EXPECT_TRUE(tr_ctorSetMetainfoFromFile(ctor, filename.c_str(), &error));
EXPECT_EQ(nullptr, error);
EXPECT_EQ(nullptr, error) << *error;
auto const* const metainfo = tr_ctorGetMetainfo(ctor);
EXPECT_NE(nullptr, metainfo);
EXPECT_EQ(336, metainfo->infoDictOffset());
@ -175,9 +175,9 @@ TEST_F(TorrentMetainfoTest, ctorSaveContents)
// now try saving _with_ metainfo
EXPECT_TRUE(tr_ctorSetMetainfoFromFile(ctor, src_filename.c_str(), &error));
EXPECT_EQ(nullptr, error);
EXPECT_EQ(nullptr, error) << *error;
EXPECT_TRUE(tr_ctorSaveContents(ctor, tgt_filename, &error));
EXPECT_EQ(nullptr, error);
EXPECT_EQ(nullptr, error) << *error;
// the saved contents should match the source file's contents
auto src_contents = std::vector<char>{};
@ -188,7 +188,7 @@ TEST_F(TorrentMetainfoTest, ctorSaveContents)
// cleanup
EXPECT_TRUE(tr_sys_path_remove(tgt_filename.c_str(), &error));
EXPECT_EQ(nullptr, error);
EXPECT_EQ(nullptr, error) << *error;
tr_error_clear(&error);
tr_ctorFree(ctor);
}

View File

@ -466,18 +466,18 @@ TEST_F(UtilsTest, saveFile)
auto contents = "these are the contents"sv;
tr_error* error = nullptr;
EXPECT_TRUE(tr_saveFile(filename, contents, &error));
EXPECT_EQ(nullptr, error);
EXPECT_EQ(nullptr, error) << *error;
// now read the file back in and confirm the contents are the same
auto buf = std::vector<char>{};
EXPECT_TRUE(tr_loadFile(buf, filename, &error));
EXPECT_EQ(nullptr, error);
EXPECT_EQ(nullptr, error) << *error;
auto sv = std::string_view{ std::data(buf), std::size(buf) };
EXPECT_EQ(contents, sv);
// remove the tempfile
EXPECT_TRUE(tr_sys_path_remove(filename.c_str(), &error));
EXPECT_EQ(nullptr, error);
EXPECT_EQ(nullptr, error) << *error;
// try saving a file to a path that doesn't exist
filename = "/this/path/does/not/exist/foo.txt";

View File

@ -171,9 +171,9 @@ int tr_main(int argc, char* argv[])
if (std::empty(options.outfile))
{
tr_error* error = nullptr;
char* base = tr_sys_path_basename(options.infile, &error);
auto const base = tr_sys_path_basename(options.infile, &error);
if (base == nullptr)
if (std::empty(base))
{
fprintf(stderr, "ERROR: Cannot deduce output path from input path: %s\n", error->message);
return EXIT_FAILURE;
@ -183,7 +183,6 @@ int tr_main(int argc, char* argv[])
char* cwd = tr_getcwd();
options.outfile = tr_strvDup(tr_strvPath(cwd, end.c_str()));
tr_free(cwd);
tr_free(base);
}
if (std::empty(options.trackers))