mirror of
https://github.com/transmission/transmission
synced 2024-07-08 19:55:54 +00:00
refactor: remove the tr_error** idiom (#6198)
* refactor: remove the tr_error** idiom * fix: tr_error::message() is only constexpr in c++20 and up * chore: silence a couple of g++-12 Wshadow warnings
This commit is contained in:
parent
4d95aa5298
commit
a952a0731f
12
cli/cli.cc
12
cli/cli.cc
|
@ -245,12 +245,14 @@ int tr_main(int argc, char* argv[])
|
|||
|
||||
if (!tr_sys_path_exists(sz_download_dir))
|
||||
{
|
||||
tr_error* error = nullptr;
|
||||
|
||||
if (!tr_sys_dir_create(sz_download_dir, TR_SYS_DIR_CREATE_PARENTS, 0700, &error))
|
||||
if (auto error = tr_error{}; !tr_sys_dir_create(sz_download_dir, TR_SYS_DIR_CREATE_PARENTS, 0700, &error) && error)
|
||||
{
|
||||
fprintf(stderr, "Unable to create download directory \"%s\": %s\n", sz_download_dir.c_str(), error->message);
|
||||
tr_error_free(error);
|
||||
auto const errmsg = fmt::format(
|
||||
"Couldn't create '{path}': {error} ({error_code})",
|
||||
fmt::arg("path", sz_download_dir),
|
||||
fmt::arg("error", error.message()),
|
||||
fmt::arg("error_code", error.code()));
|
||||
fmt::print(stderr, "{:s}\n", errmsg);
|
||||
return EXIT_FAILURE;
|
||||
}
|
||||
}
|
||||
|
|
|
@ -24,9 +24,9 @@
|
|||
|
||||
#include "daemon.h"
|
||||
|
||||
static void set_system_error(tr_error** error, int code, std::string_view message)
|
||||
static void set_system_error(tr_error& error, int code, std::string_view message)
|
||||
{
|
||||
tr_error_set(error, code, fmt::format(FMT_STRING("{:s}: {:s} ({:d}"), message, tr_strerror(code), code));
|
||||
error.set(code, fmt::format(FMT_STRING("{:s}: {:s} ({:d}"), message, tr_strerror(code), code));
|
||||
}
|
||||
|
||||
#ifdef HAVE_SYS_SIGNALFD_H
|
||||
|
@ -131,7 +131,7 @@ void tr_daemon::cleanup_signals(struct event* sig_ev) const
|
|||
#endif /* HAVE_SYS_SIGNALFD_H */
|
||||
}
|
||||
|
||||
bool tr_daemon::spawn(bool foreground, int* exit_code, tr_error** error)
|
||||
bool tr_daemon::spawn(bool foreground, int* exit_code, tr_error& error)
|
||||
{
|
||||
*exit_code = 1;
|
||||
|
||||
|
|
|
@ -34,10 +34,10 @@ static DWORD current_state = SERVICE_STOPPED;
|
|||
static HANDLE service_thread = nullptr;
|
||||
static HANDLE service_stop_thread = nullptr;
|
||||
|
||||
static void set_system_error(tr_error** error, DWORD code, char const* message)
|
||||
static void set_system_error(tr_error& error, DWORD code, char const* message)
|
||||
{
|
||||
auto const system_message = tr_win32_format_message(code);
|
||||
tr_error_set(error, code, fmt::format(FMT_STRING("{:s} ({:#08x}): {:s})"), message, code, system_message));
|
||||
error.set(code, fmt::format(FMT_STRING("{:s} ({:#08x}): {:s})"), message, code, system_message));
|
||||
}
|
||||
|
||||
static void do_log_system_error(char const* file, int line, tr_log_level level, DWORD code, char const* message)
|
||||
|
@ -209,7 +209,7 @@ void tr_daemon::cleanup_signals([[maybe_unused]] struct event* sig_ev) const
|
|||
{
|
||||
}
|
||||
|
||||
bool tr_daemon::spawn(bool foreground, int* exit_code, tr_error** error)
|
||||
bool tr_daemon::spawn(bool foreground, int* exit_code, tr_error& error)
|
||||
{
|
||||
daemon = this;
|
||||
|
||||
|
|
|
@ -165,7 +165,7 @@ static auto constexpr Options = std::array<tr_option, 45>{
|
|||
|
||||
bool tr_daemon::reopen_log_file(char const* filename)
|
||||
{
|
||||
tr_error* error = nullptr;
|
||||
auto error = tr_error{};
|
||||
tr_sys_file_t const old_log_file = logfile_;
|
||||
tr_sys_file_t const new_log_file = tr_sys_file_open(
|
||||
filename,
|
||||
|
@ -175,8 +175,12 @@ bool tr_daemon::reopen_log_file(char const* filename)
|
|||
|
||||
if (new_log_file == TR_BAD_SYS_FILE)
|
||||
{
|
||||
fprintf(stderr, "Couldn't (re)open log file \"%s\": %s\n", filename, error->message);
|
||||
tr_error_free(error);
|
||||
auto const errmsg = fmt::format(
|
||||
"Couldn't open '{path}': {error} ({error_code})",
|
||||
fmt::arg("path", filename),
|
||||
fmt::arg("error", error.message()),
|
||||
fmt::arg("error_code", error.code()));
|
||||
fmt::print(stderr, "{:s}\n", errmsg);
|
||||
return false;
|
||||
}
|
||||
|
||||
|
@ -236,15 +240,14 @@ static auto onFileAdded(tr_session const* session, std::string_view dirname, std
|
|||
else // is_magnet
|
||||
{
|
||||
auto content = std::vector<char>{};
|
||||
tr_error* error = nullptr;
|
||||
auto error = tr_error{};
|
||||
if (!tr_file_read(filename, content, &error))
|
||||
{
|
||||
tr_logAddWarn(fmt::format(
|
||||
_("Couldn't read '{path}': {error} ({error_code})"),
|
||||
fmt::arg("path", basename),
|
||||
fmt::arg("error", error->message),
|
||||
fmt::arg("error_code", error->code)));
|
||||
tr_error_free(error);
|
||||
fmt::arg("error", error.message()),
|
||||
fmt::arg("error_code", error.code())));
|
||||
retry = true;
|
||||
}
|
||||
else
|
||||
|
@ -275,18 +278,15 @@ static auto onFileAdded(tr_session const* session, std::string_view dirname, std
|
|||
|
||||
if (test && trash)
|
||||
{
|
||||
tr_error* error = nullptr;
|
||||
|
||||
tr_logAddInfo(fmt::format(_("Removing torrent file '{path}'"), fmt::arg("path", basename)));
|
||||
|
||||
if (!tr_sys_path_remove(filename, &error))
|
||||
if (auto error = tr_error{}; !tr_sys_path_remove(filename, &error))
|
||||
{
|
||||
tr_logAddError(fmt::format(
|
||||
_("Couldn't remove '{path}': {error} ({error_code})"),
|
||||
fmt::arg("path", basename),
|
||||
fmt::arg("error", error->message),
|
||||
fmt::arg("error_code", error->code)));
|
||||
tr_error_free(error);
|
||||
fmt::arg("error", error.message()),
|
||||
fmt::arg("error_code", error.code())));
|
||||
}
|
||||
}
|
||||
else
|
||||
|
@ -736,7 +736,7 @@ int tr_daemon::start([[maybe_unused]] bool foreground)
|
|||
auto const sz_pid_filename = std::string{ sv };
|
||||
if (!std::empty(sz_pid_filename))
|
||||
{
|
||||
tr_error* error = nullptr;
|
||||
auto error = tr_error{};
|
||||
tr_sys_file_t fp = tr_sys_file_open(
|
||||
sz_pid_filename.c_str(),
|
||||
TR_SYS_FILE_WRITE | TR_SYS_FILE_CREATE | TR_SYS_FILE_TRUNCATE,
|
||||
|
@ -756,9 +756,8 @@ int tr_daemon::start([[maybe_unused]] bool foreground)
|
|||
tr_logAddError(fmt::format(
|
||||
_("Couldn't save '{path}': {error} ({error_code})"),
|
||||
fmt::arg("path", sz_pid_filename),
|
||||
fmt::arg("error", error->message),
|
||||
fmt::arg("error_code", error->code)));
|
||||
tr_error_free(error);
|
||||
fmt::arg("error", error.message()),
|
||||
fmt::arg("error_code", error.code())));
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -939,11 +938,10 @@ EXIT_EARLY:
|
|||
return false;
|
||||
}
|
||||
|
||||
void tr_daemon::handle_error(tr_error* error) const
|
||||
void tr_daemon::handle_error(tr_error const& error) const
|
||||
{
|
||||
auto const errmsg = fmt::format(FMT_STRING("Couldn't daemonize: {:s} ({:d})"), error->message, error->code);
|
||||
auto const errmsg = fmt::format("Couldn't daemonize: {:s} ({:d})", error.message(), error.code());
|
||||
printMessage(logfile_, TR_LOG_ERROR, MyName, errmsg, __FILE__, __LINE__);
|
||||
tr_error_free(error);
|
||||
}
|
||||
|
||||
int tr_main(int argc, char* argv[])
|
||||
|
@ -952,16 +950,15 @@ int tr_main(int argc, char* argv[])
|
|||
|
||||
tr_locale_set_global("");
|
||||
|
||||
int ret;
|
||||
tr_daemon daemon;
|
||||
bool foreground;
|
||||
tr_error* error = nullptr;
|
||||
|
||||
auto foreground = bool{};
|
||||
auto ret = int{};
|
||||
auto daemon = tr_daemon{};
|
||||
if (!daemon.init(argc, argv, &foreground, &ret))
|
||||
{
|
||||
return ret;
|
||||
}
|
||||
if (!daemon.spawn(foreground, &ret, &error))
|
||||
|
||||
if (auto error = tr_error{}; !daemon.spawn(foreground, &ret, error))
|
||||
{
|
||||
daemon.handle_error(error);
|
||||
}
|
||||
|
|
|
@ -33,9 +33,9 @@ public:
|
|||
#endif /* signalfd API */
|
||||
}
|
||||
|
||||
bool spawn(bool foreground, int* exit_code, tr_error** error);
|
||||
bool spawn(bool foreground, int* exit_code, tr_error& error);
|
||||
bool init(int argc, char const* const argv[], bool* foreground, int* ret);
|
||||
void handle_error(tr_error*) const;
|
||||
void handle_error(tr_error const&) const;
|
||||
int start(bool foreground);
|
||||
void periodic_update();
|
||||
void reconfigure();
|
||||
|
|
|
@ -67,7 +67,7 @@ public:
|
|||
BaseObjectType* cast_item,
|
||||
Glib::RefPtr<Gtk::Builder> const& builder,
|
||||
tr_metainfo_builder& metainfo_builder,
|
||||
std::future<tr_error*> future,
|
||||
std::future<tr_error> future,
|
||||
std::string_view target,
|
||||
Glib::RefPtr<Session> const& core);
|
||||
~MakeProgressDialog() override;
|
||||
|
@ -77,7 +77,7 @@ public:
|
|||
static std::unique_ptr<MakeProgressDialog> create(
|
||||
std::string_view target,
|
||||
tr_metainfo_builder& metainfo_builder,
|
||||
std::future<tr_error*> future,
|
||||
std::future<tr_error> future,
|
||||
Glib::RefPtr<Session> const& core);
|
||||
|
||||
[[nodiscard]] bool success() const
|
||||
|
@ -93,7 +93,7 @@ private:
|
|||
|
||||
private:
|
||||
tr_metainfo_builder& builder_;
|
||||
std::future<tr_error*> future_;
|
||||
std::future<tr_error> future_;
|
||||
std::string const target_;
|
||||
Glib::RefPtr<Session> const core_;
|
||||
bool success_ = false;
|
||||
|
@ -190,14 +190,14 @@ bool MakeProgressDialog::onProgressDialogRefresh()
|
|||
}
|
||||
else
|
||||
{
|
||||
tr_error* error = future_.get();
|
||||
auto error = future_.get();
|
||||
|
||||
if (error == nullptr)
|
||||
if (!error)
|
||||
{
|
||||
builder_.save(target_, &error);
|
||||
}
|
||||
|
||||
if (error == nullptr)
|
||||
if (!error)
|
||||
{
|
||||
str = fmt::format(_("Created '{path}'"), fmt::arg("path", base));
|
||||
success = true;
|
||||
|
@ -207,9 +207,8 @@ bool MakeProgressDialog::onProgressDialogRefresh()
|
|||
str = fmt::format(
|
||||
_("Couldn't create '{path}': {error} ({error_code})"),
|
||||
fmt::arg("path", base),
|
||||
fmt::arg("error", error->message),
|
||||
fmt::arg("error_code", error->code));
|
||||
tr_error_free(error);
|
||||
fmt::arg("error", error.message()),
|
||||
fmt::arg("error_code", error.code()));
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -280,7 +279,7 @@ MakeProgressDialog::MakeProgressDialog(
|
|||
BaseObjectType* cast_item,
|
||||
Glib::RefPtr<Gtk::Builder> const& builder,
|
||||
tr_metainfo_builder& metainfo_builder,
|
||||
std::future<tr_error*> future,
|
||||
std::future<tr_error> future,
|
||||
std::string_view target,
|
||||
Glib::RefPtr<Session> const& core)
|
||||
: Gtk::Dialog(cast_item)
|
||||
|
@ -302,7 +301,7 @@ MakeProgressDialog::MakeProgressDialog(
|
|||
std::unique_ptr<MakeProgressDialog> MakeProgressDialog::create(
|
||||
std::string_view target,
|
||||
tr_metainfo_builder& metainfo_builder,
|
||||
std::future<tr_error*> future,
|
||||
std::future<tr_error> future,
|
||||
Glib::RefPtr<Session> const& core)
|
||||
{
|
||||
auto const builder = Gtk::Builder::create_from_resource(gtr_get_full_resource_path("MakeProgressDialog.ui"));
|
||||
|
|
|
@ -911,7 +911,7 @@ void Session::remove_torrent(tr_torrent_id_t id, bool delete_files)
|
|||
tr_torrentRemove(
|
||||
&torrent->get_underlying(),
|
||||
delete_files,
|
||||
[](char const* filename, void* /*user_data*/, tr_error** error)
|
||||
[](char const* filename, void* /*user_data*/, tr_error* error)
|
||||
{ return gtr_file_trash_or_remove(filename, error); },
|
||||
nullptr);
|
||||
}
|
||||
|
|
26
gtk/Utils.cc
26
gtk/Utils.cc
|
@ -524,14 +524,18 @@ void setup_item_view_button_event_handling(
|
|||
|
||||
#endif
|
||||
|
||||
bool gtr_file_trash_or_remove(std::string const& filename, tr_error** error)
|
||||
bool gtr_file_trash_or_remove(std::string const& filename, tr_error* error)
|
||||
{
|
||||
bool trashed = false;
|
||||
bool result = true;
|
||||
|
||||
g_return_val_if_fail(!filename.empty(), false);
|
||||
|
||||
auto local_error = tr_error{};
|
||||
if (error == nullptr)
|
||||
{
|
||||
error = &local_error;
|
||||
}
|
||||
|
||||
auto const file = Gio::File::create_for_path(filename);
|
||||
bool trashed = false;
|
||||
|
||||
if (gtr_pref_flag_get(TR_KEY_trash_can_enabled))
|
||||
{
|
||||
|
@ -541,15 +545,16 @@ bool gtr_file_trash_or_remove(std::string const& filename, tr_error** error)
|
|||
}
|
||||
catch (Glib::Error const& e)
|
||||
{
|
||||
error->set(e.code(), TR_GLIB_EXCEPTION_WHAT(e));
|
||||
gtr_message(fmt::format(
|
||||
_("Couldn't move '{path}' to trash: {error} ({error_code})"),
|
||||
fmt::arg("path", filename),
|
||||
fmt::arg("error", TR_GLIB_EXCEPTION_WHAT(e)),
|
||||
fmt::arg("error_code", e.code())));
|
||||
tr_error_set(error, e.code(), TR_GLIB_EXCEPTION_WHAT(e));
|
||||
fmt::arg("error", error->message()),
|
||||
fmt::arg("error_code", error->code())));
|
||||
}
|
||||
}
|
||||
|
||||
bool result = true;
|
||||
if (!trashed)
|
||||
{
|
||||
try
|
||||
|
@ -558,13 +563,12 @@ bool gtr_file_trash_or_remove(std::string const& filename, tr_error** error)
|
|||
}
|
||||
catch (Glib::Error const& e)
|
||||
{
|
||||
error->set(e.code(), TR_GLIB_EXCEPTION_WHAT(e));
|
||||
gtr_message(fmt::format(
|
||||
_("Couldn't remove '{path}': {error} ({error_code})"),
|
||||
fmt::arg("path", filename),
|
||||
fmt::arg("error", TR_GLIB_EXCEPTION_WHAT(e)),
|
||||
fmt::arg("error_code", e.code())));
|
||||
tr_error_clear(error);
|
||||
tr_error_set(error, e.code(), TR_GLIB_EXCEPTION_WHAT(e));
|
||||
fmt::arg("error", error->message()),
|
||||
fmt::arg("error_code", error->code())));
|
||||
result = false;
|
||||
}
|
||||
}
|
||||
|
|
|
@ -185,7 +185,7 @@ void setup_item_view_button_event_handling(
|
|||
#endif
|
||||
|
||||
/* move a file to the trashcan if GIO is available; otherwise, delete it */
|
||||
bool gtr_file_trash_or_remove(std::string const& filename, tr_error** error);
|
||||
bool gtr_file_trash_or_remove(std::string const& filename, tr_error* error = nullptr);
|
||||
|
||||
void gtr_paste_clipboard_url_into_entry(Gtk::Entry& entry);
|
||||
|
||||
|
|
|
@ -264,14 +264,19 @@ void tr_announce_list::add_to_map(tr_variant::Map& setme) const
|
|||
}
|
||||
}
|
||||
|
||||
bool tr_announce_list::save(std::string_view torrent_file, tr_error** error) const
|
||||
bool tr_announce_list::save(std::string_view torrent_file, tr_error* error) const
|
||||
{
|
||||
// load the torrent file
|
||||
auto serde = tr_variant_serde::benc();
|
||||
auto ometainfo = serde.parse_file(torrent_file);
|
||||
if (!ometainfo)
|
||||
{
|
||||
tr_error_propagate(error, &serde.error_);
|
||||
if (error != nullptr)
|
||||
{
|
||||
*error = std::move(serde.error_);
|
||||
serde.error_ = {};
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
auto& metainfo = *ometainfo;
|
||||
|
|
|
@ -127,7 +127,7 @@ public:
|
|||
bool parse(std::string_view text);
|
||||
[[nodiscard]] std::string to_string() const;
|
||||
|
||||
bool save(std::string_view torrent_file, tr_error** error = nullptr) const;
|
||||
bool save(std::string_view torrent_file, tr_error* error = nullptr) const;
|
||||
|
||||
[[nodiscard]] static std::optional<std::string> announce_to_scrape(std::string_view announce);
|
||||
|
||||
|
|
|
@ -440,17 +440,16 @@ void tr_announcerParseHttpAnnounceResponse(tr_announce_response& response, std::
|
|||
|
||||
auto stack = transmission::benc::ParserStack<MaxBencDepth>{};
|
||||
auto handler = AnnounceHandler{ response, log_name };
|
||||
tr_error* error = nullptr;
|
||||
auto error = tr_error{};
|
||||
transmission::benc::parse(benc, stack, handler, nullptr, &error);
|
||||
if (error != nullptr)
|
||||
if (error)
|
||||
{
|
||||
tr_logAddWarn(
|
||||
fmt::format(
|
||||
_("Couldn't parse announce response: {error} ({error_code})"),
|
||||
fmt::arg("error", error->message),
|
||||
fmt::arg("error_code", error->code)),
|
||||
fmt::arg("error", error.message()),
|
||||
fmt::arg("error_code", error.code())),
|
||||
log_name);
|
||||
tr_error_clear(&error);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -648,16 +647,15 @@ void tr_announcerParseHttpScrapeResponse(tr_scrape_response& response, std::stri
|
|||
|
||||
auto stack = transmission::benc::ParserStack<MaxBencDepth>{};
|
||||
auto handler = ScrapeHandler{ response, log_name };
|
||||
tr_error* error = nullptr;
|
||||
auto error = tr_error{};
|
||||
transmission::benc::parse(benc, stack, handler, nullptr, &error);
|
||||
if (error != nullptr)
|
||||
if (error)
|
||||
{
|
||||
tr_logAddWarn(
|
||||
fmt::format(
|
||||
_("Couldn't parse scrape response: {error} ({error_code})"),
|
||||
fmt::arg("error", error->message),
|
||||
fmt::arg("error_code", error->code)),
|
||||
fmt::arg("error", error.message()),
|
||||
fmt::arg("error_code", error.code())),
|
||||
log_name);
|
||||
tr_error_clear(&error);
|
||||
}
|
||||
}
|
||||
|
|
|
@ -33,7 +33,7 @@ struct Handler
|
|||
class Context
|
||||
{
|
||||
public:
|
||||
constexpr Context(char const* stream_begin_in, tr_error** error_in)
|
||||
constexpr Context(char const* stream_begin_in, tr_error& error_in)
|
||||
: error{ error_in }
|
||||
, stream_begin_{ stream_begin_in }
|
||||
{
|
||||
|
@ -55,7 +55,7 @@ struct Handler
|
|||
token_end_ = token_begin_ + len;
|
||||
}
|
||||
|
||||
tr_error** error = nullptr;
|
||||
tr_error& error;
|
||||
|
||||
private:
|
||||
char const* token_begin_ = nullptr;
|
||||
|
@ -219,17 +219,17 @@ struct ParserStack
|
|||
return stack[depth].parent_type;
|
||||
}
|
||||
|
||||
std::optional<ParentType> pop(tr_error** error)
|
||||
std::optional<ParentType> pop(tr_error& error)
|
||||
{
|
||||
if (depth == 0)
|
||||
{
|
||||
tr_error_set(error, EILSEQ, "Cannot pop empty stack");
|
||||
error.set(EILSEQ, "Cannot pop empty stack");
|
||||
return {};
|
||||
}
|
||||
|
||||
if (stack[depth].parent_type == ParentType::Dict && ((stack[depth].n_children_walked % 2) != 0))
|
||||
{
|
||||
tr_error_set(error, EILSEQ, "Premature end-of-dict found. Malformed benc?");
|
||||
error.set(EILSEQ, "Premature end-of-dict found. Malformed benc?");
|
||||
return {};
|
||||
}
|
||||
|
||||
|
@ -238,11 +238,11 @@ struct ParserStack
|
|||
return ret;
|
||||
}
|
||||
|
||||
bool push(ParentType parent_type, tr_error** error)
|
||||
bool push(ParentType parent_type, tr_error& error)
|
||||
{
|
||||
if (depth + 1 >= std::size(stack))
|
||||
{
|
||||
tr_error_set(error, E2BIG, "Max stack depth reached; unable to continue parsing");
|
||||
error.set(E2BIG, "Max stack depth reached; unable to continue parsing");
|
||||
return false;
|
||||
}
|
||||
|
||||
|
@ -258,11 +258,18 @@ bool parse(
|
|||
ParserStack<MaxDepth>& stack,
|
||||
Handler& handler,
|
||||
char const** setme_end = nullptr,
|
||||
tr_error** error = nullptr)
|
||||
tr_error* error = nullptr)
|
||||
{
|
||||
// ensure `error` isn't a nullptr
|
||||
auto local_error = tr_error{};
|
||||
if (error == nullptr)
|
||||
{
|
||||
error = &local_error;
|
||||
}
|
||||
|
||||
stack.clear();
|
||||
auto const* const stream_begin = std::data(benc);
|
||||
auto context = Handler::Context(stream_begin, error);
|
||||
auto context = Handler::Context{ stream_begin, *error };
|
||||
|
||||
int err = 0;
|
||||
for (;;)
|
||||
|
@ -283,8 +290,8 @@ bool parse(
|
|||
case 'i': // int
|
||||
if (auto const value = impl::ParseInt(&benc); !value)
|
||||
{
|
||||
tr_error_set(error, err, "Malformed benc? Unable to parse integer");
|
||||
err = EILSEQ;
|
||||
error->set(err, "Malformed benc? Unable to parse integer");
|
||||
}
|
||||
else
|
||||
{
|
||||
|
@ -304,8 +311,8 @@ bool parse(
|
|||
case 'l': // list
|
||||
case 'd': // dict
|
||||
{
|
||||
bool ok = benc.front() == 'l' ? stack.push(ParserStack<MaxDepth>::ParentType::Array, error) :
|
||||
stack.push(ParserStack<MaxDepth>::ParentType::Dict, error);
|
||||
bool ok = benc.front() == 'l' ? stack.push(ParserStack<MaxDepth>::ParentType::Array, *error) :
|
||||
stack.push(ParserStack<MaxDepth>::ParentType::Dict, *error);
|
||||
if (!ok)
|
||||
{
|
||||
err = EILSEQ;
|
||||
|
@ -326,7 +333,7 @@ bool parse(
|
|||
case 'e': // end of list or dict
|
||||
benc.remove_prefix(1);
|
||||
|
||||
if (auto const parent_type = stack.pop(error); !parent_type)
|
||||
if (auto const parent_type = stack.pop(*error); !parent_type)
|
||||
{
|
||||
err = EILSEQ;
|
||||
}
|
||||
|
@ -357,7 +364,7 @@ bool parse(
|
|||
if (auto const sv = impl::ParseString(&benc); !sv)
|
||||
{
|
||||
err = EILSEQ;
|
||||
tr_error_set(error, err, "Malformed benc? Unable to parse string");
|
||||
error->set(err, "Malformed benc? Unable to parse string");
|
||||
}
|
||||
else
|
||||
{
|
||||
|
@ -398,7 +405,7 @@ bool parse(
|
|||
if (stack.depth != 0)
|
||||
{
|
||||
err = EILSEQ;
|
||||
tr_error_set(error, err, "premature end-of-data reached");
|
||||
error->set(err, "premature end-of-data reached");
|
||||
errno = err;
|
||||
return false;
|
||||
}
|
||||
|
@ -406,7 +413,7 @@ bool parse(
|
|||
if (stack.stack[0].n_children_walked == 0)
|
||||
{
|
||||
err = EILSEQ;
|
||||
tr_error_set(error, err, "no bencoded data to parse");
|
||||
error->set(err, "no bencoded data to parse");
|
||||
errno = err;
|
||||
return false;
|
||||
}
|
||||
|
|
|
@ -324,16 +324,15 @@ void Blocklists::Blocklist::ensureLoaded() const
|
|||
}
|
||||
|
||||
// get the file's size
|
||||
tr_error* error = nullptr;
|
||||
auto error = tr_error{};
|
||||
auto const file_info = tr_sys_path_get_info(bin_file_, 0, &error);
|
||||
if (error != nullptr)
|
||||
if (error)
|
||||
{
|
||||
tr_logAddWarn(fmt::format(
|
||||
_("Couldn't read '{path}': {error} ({error_code})"),
|
||||
fmt::arg("path", bin_file_),
|
||||
fmt::arg("error", error->message),
|
||||
fmt::arg("error_code", error->code)));
|
||||
tr_error_clear(&error);
|
||||
fmt::arg("error", error.message()),
|
||||
fmt::arg("error_code", error.code())));
|
||||
}
|
||||
if (!file_info)
|
||||
{
|
||||
|
@ -460,16 +459,15 @@ std::optional<Blocklists::Blocklist> Blocklists::Blocklist::saveNew(
|
|||
// make a copy of `external_file` for our own safekeeping
|
||||
auto const src_file = std::string{ std::data(bin_file), std::size(bin_file) - std::size(BinFileSuffix) };
|
||||
tr_sys_path_remove(src_file.c_str());
|
||||
tr_error* error = nullptr;
|
||||
auto error = tr_error{};
|
||||
auto const copied = tr_sys_path_copy(tr_pathbuf{ external_file }, src_file.c_str(), &error);
|
||||
if (error != nullptr)
|
||||
if (error)
|
||||
{
|
||||
tr_logAddWarn(fmt::format(
|
||||
_("Couldn't save '{path}': {error} ({error_code})"),
|
||||
fmt::arg("path", src_file),
|
||||
fmt::arg("error", error->message),
|
||||
fmt::arg("error_code", error->code)));
|
||||
tr_error_clear(&error);
|
||||
fmt::arg("error", error.message()),
|
||||
fmt::arg("error_code", error.code())));
|
||||
}
|
||||
if (!copied)
|
||||
{
|
||||
|
|
|
@ -3,95 +3,12 @@
|
|||
// or any future license endorsed by Mnemosyne LLC.
|
||||
// License text can be found in the licenses/ folder.
|
||||
|
||||
#include <algorithm>
|
||||
#include <string_view>
|
||||
|
||||
#include <fmt/core.h>
|
||||
|
||||
#include "libtransmission/error.h"
|
||||
#include "libtransmission/tr-assert.h"
|
||||
#include "libtransmission/utils.h"
|
||||
|
||||
namespace
|
||||
void tr_error::set_from_errno(int errnum)
|
||||
{
|
||||
[[nodiscard]] char* tr_strvdup(std::string_view in)
|
||||
{
|
||||
auto const n = std::size(in);
|
||||
auto* const ret = new char[n + 1];
|
||||
std::copy(std::begin(in), std::end(in), ret);
|
||||
ret[n] = '\0';
|
||||
return ret;
|
||||
}
|
||||
} // namespace
|
||||
|
||||
void tr_error_free(tr_error* error)
|
||||
{
|
||||
if (error == nullptr)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
delete[] error->message;
|
||||
delete error;
|
||||
}
|
||||
|
||||
void tr_error_set(tr_error** error, int code, std::string_view message)
|
||||
{
|
||||
if (error == nullptr)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
TR_ASSERT(*error == nullptr);
|
||||
*error = new tr_error{ code, tr_strvdup(message) };
|
||||
}
|
||||
|
||||
void tr_error_set_from_errno(tr_error** error, int errnum)
|
||||
{
|
||||
tr_error_set(error, errnum, tr_strerror(errnum));
|
||||
}
|
||||
|
||||
void tr_error_propagate(tr_error** new_error, tr_error** old_error)
|
||||
{
|
||||
TR_ASSERT(old_error != nullptr);
|
||||
TR_ASSERT(*old_error != nullptr);
|
||||
|
||||
if (new_error != nullptr)
|
||||
{
|
||||
TR_ASSERT(*new_error == nullptr);
|
||||
|
||||
*new_error = *old_error;
|
||||
*old_error = nullptr;
|
||||
}
|
||||
else
|
||||
{
|
||||
tr_error_clear(old_error);
|
||||
}
|
||||
}
|
||||
|
||||
void tr_error_clear(tr_error** error)
|
||||
{
|
||||
if (error == nullptr)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
tr_error_free(*error);
|
||||
|
||||
*error = nullptr;
|
||||
}
|
||||
|
||||
void tr_error_prefix(tr_error** error, char const* prefix)
|
||||
{
|
||||
TR_ASSERT(prefix != nullptr);
|
||||
|
||||
if (error == nullptr || *error == nullptr)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
auto* err = *error;
|
||||
auto* const new_message = tr_strvdup(fmt::format(FMT_STRING("{:s}{:s}"), prefix, err->message));
|
||||
delete[] err->message;
|
||||
err->message = new_message;
|
||||
code_ = errnum;
|
||||
|
||||
message_ = errnum != 0 ? tr_strerror(errnum) : "";
|
||||
}
|
||||
|
|
|
@ -5,77 +5,61 @@
|
|||
|
||||
#pragma once
|
||||
|
||||
#include <string>
|
||||
#include <string_view>
|
||||
|
||||
/**
|
||||
* @addtogroup error Error reporting
|
||||
* @{
|
||||
*/
|
||||
#include "libtransmission/tr-macros.h"
|
||||
|
||||
/** @brief Structure holding error information. */
|
||||
struct tr_error
|
||||
{
|
||||
/** @brief Error code, platform-specific */
|
||||
int code;
|
||||
public:
|
||||
tr_error() = default;
|
||||
|
||||
tr_error(int code, std::string message)
|
||||
: message_{ std::move(message) }
|
||||
, code_{ code }
|
||||
{
|
||||
}
|
||||
|
||||
[[nodiscard]] constexpr auto code() const noexcept
|
||||
{
|
||||
return code_;
|
||||
}
|
||||
|
||||
[[nodiscard]] TR_CONSTEXPR20 auto message() const noexcept
|
||||
{
|
||||
return std::string_view{ message_ };
|
||||
}
|
||||
|
||||
[[nodiscard]] constexpr auto has_value() const noexcept
|
||||
{
|
||||
return code_ != 0;
|
||||
}
|
||||
|
||||
[[nodiscard]] constexpr operator bool() const noexcept
|
||||
{
|
||||
return has_value();
|
||||
}
|
||||
|
||||
void set(int code, std::string_view message)
|
||||
{
|
||||
code_ = code;
|
||||
message_.assign(message);
|
||||
}
|
||||
|
||||
void prefix_message(std::string_view prefix)
|
||||
{
|
||||
message_.insert(std::begin(message_), std::begin(prefix), std::end(prefix));
|
||||
}
|
||||
|
||||
// convenience utility for `set(errno, tr_strerror(errno))`
|
||||
void set_from_errno(int errnum);
|
||||
|
||||
private:
|
||||
/** @brief Error message */
|
||||
char* message;
|
||||
std::string message_;
|
||||
|
||||
/** @brief Error code, platform-specific */
|
||||
int code_ = 0;
|
||||
};
|
||||
|
||||
/**
|
||||
* @brief Free memory used by error object.
|
||||
*
|
||||
* @param[in] error Error object to be freed.
|
||||
*/
|
||||
void tr_error_free(tr_error* error);
|
||||
|
||||
/**
|
||||
* @brief Create and set new error object using literal error message.
|
||||
*
|
||||
* If passed pointer to error object is `nullptr`, do nothing.
|
||||
*
|
||||
* @param[in,out] error Pointer to error object to be set.
|
||||
* @param[in] code Error code (platform-specific).
|
||||
* @param[in] message Error message.
|
||||
*/
|
||||
void tr_error_set(tr_error** error, int code, std::string_view message);
|
||||
|
||||
/**
|
||||
* @brief shorthand for `tr_error_set(error, errno, tr_strerror(errno))`
|
||||
*/
|
||||
void tr_error_set_from_errno(tr_error** error, int errnum);
|
||||
|
||||
/**
|
||||
* @brief Propagate existing error object upwards.
|
||||
*
|
||||
* If passed pointer to new error object is not `nullptr`, copy old error object
|
||||
* to new error object and free old error object. Otherwise, just free old error
|
||||
* object.
|
||||
*
|
||||
* @param[in,out] new_error Pointer to error object to be set.
|
||||
* @param[in,out] old_error Error object to be propagated. Cleared on return.
|
||||
*/
|
||||
void tr_error_propagate(tr_error** new_error, tr_error** old_error);
|
||||
|
||||
/**
|
||||
* @brief Clear error object.
|
||||
*
|
||||
* Free error object being pointed and set pointer to `nullptr`. If passed
|
||||
* pointer is `nullptr`, do nothing.
|
||||
*
|
||||
* @param[in,out] error Pointer to error object to be cleared.
|
||||
*/
|
||||
void tr_error_clear(tr_error** error);
|
||||
|
||||
/**
|
||||
* @brief Prefix message of existing error object.
|
||||
*
|
||||
* If passed pointer to error object is not `nullptr`, prefix its message with
|
||||
* `printf`-style formatted text. Otherwise, do nothing.
|
||||
*
|
||||
* @param[in,out] error Pointer to error object to be set.
|
||||
* @param[in] prefix_format Prefix format string.
|
||||
* @param[in] ... Format arguments.
|
||||
*/
|
||||
void tr_error_prefix(tr_error** error, char const* prefix);
|
||||
|
||||
/** @} */
|
||||
|
|
|
@ -509,9 +509,15 @@ tr_sys_path_capacity tr_device_info_get_disk_space(struct tr_device_info const&
|
|||
|
||||
} // namespace
|
||||
|
||||
std::optional<tr_sys_path_capacity> tr_sys_path_get_capacity(std::string_view path, tr_error** error)
|
||||
std::optional<tr_sys_path_capacity> tr_sys_path_get_capacity(std::string_view path, tr_error* error)
|
||||
{
|
||||
auto const info = tr_sys_path_get_info(path, 0, error);
|
||||
auto local_error = tr_error{};
|
||||
if (error == nullptr)
|
||||
{
|
||||
error = &local_error;
|
||||
}
|
||||
|
||||
auto const info = tr_sys_path_get_info(path, 0, &local_error);
|
||||
if (!info)
|
||||
{
|
||||
return {};
|
||||
|
@ -519,16 +525,15 @@ std::optional<tr_sys_path_capacity> tr_sys_path_get_capacity(std::string_view pa
|
|||
|
||||
if (!info->isFolder())
|
||||
{
|
||||
tr_error_set_from_errno(error, ENOTDIR);
|
||||
error->set_from_errno(ENOTDIR);
|
||||
return {};
|
||||
}
|
||||
|
||||
auto const device = tr_device_info_create(path);
|
||||
auto capacity = tr_device_info_get_disk_space(device);
|
||||
|
||||
if (capacity.free < 0 || capacity.total < 0)
|
||||
{
|
||||
tr_error_set_from_errno(error, EINVAL);
|
||||
error->set_from_errno(EINVAL);
|
||||
return {};
|
||||
}
|
||||
|
||||
|
|
|
@ -97,14 +97,6 @@ using namespace std::literals;
|
|||
|
||||
namespace
|
||||
{
|
||||
void set_system_error_if_file_found(tr_error** error, int code)
|
||||
{
|
||||
if (code != ENOENT)
|
||||
{
|
||||
tr_error_set_from_errno(error, code);
|
||||
}
|
||||
}
|
||||
|
||||
void set_file_for_single_pass(tr_sys_file_t handle)
|
||||
{
|
||||
/* Set hints about the lookahead buffer and caching. It's okay
|
||||
|
@ -134,21 +126,21 @@ void set_file_for_single_pass(tr_sys_file_t handle)
|
|||
}
|
||||
} // namespace
|
||||
|
||||
bool tr_sys_path_exists(char const* path, tr_error** error)
|
||||
bool tr_sys_path_exists(char const* path, tr_error* error)
|
||||
{
|
||||
TR_ASSERT(path != nullptr);
|
||||
|
||||
bool const ret = access(path, F_OK) != -1;
|
||||
|
||||
if (!ret)
|
||||
if (error != nullptr && !ret && errno != ENOENT)
|
||||
{
|
||||
set_system_error_if_file_found(error, errno);
|
||||
error->set_from_errno(errno);
|
||||
}
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
std::optional<tr_sys_path_info> tr_sys_path_get_info(std::string_view path, int flags, tr_error** error)
|
||||
std::optional<tr_sys_path_info> tr_sys_path_get_info(std::string_view path, int flags, tr_error* error)
|
||||
{
|
||||
struct stat sb = {};
|
||||
|
||||
|
@ -166,7 +158,11 @@ std::optional<tr_sys_path_info> tr_sys_path_get_info(std::string_view path, int
|
|||
|
||||
if (!ok)
|
||||
{
|
||||
tr_error_set_from_errno(error, errno);
|
||||
if (error != nullptr)
|
||||
{
|
||||
error->set_from_errno(errno);
|
||||
}
|
||||
|
||||
return {};
|
||||
}
|
||||
|
||||
|
@ -196,7 +192,7 @@ bool tr_sys_path_is_relative(std::string_view path)
|
|||
return std::empty(path) || path.front() != '/';
|
||||
}
|
||||
|
||||
bool tr_sys_path_is_same(char const* path1, char const* path2, tr_error** error)
|
||||
bool tr_sys_path_is_same(char const* path1, char const* path2, tr_error* error)
|
||||
{
|
||||
TR_ASSERT(path1 != nullptr);
|
||||
TR_ASSERT(path2 != nullptr);
|
||||
|
@ -209,15 +205,15 @@ bool tr_sys_path_is_same(char const* path1, char const* path2, tr_error** error)
|
|||
{
|
||||
ret = sb1.st_dev == sb2.st_dev && sb1.st_ino == sb2.st_ino;
|
||||
}
|
||||
else
|
||||
else if (error != nullptr && errno != ENOENT)
|
||||
{
|
||||
set_system_error_if_file_found(error, errno);
|
||||
error->set_from_errno(errno);
|
||||
}
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
std::string tr_sys_path_resolve(std::string_view path, tr_error** error)
|
||||
std::string tr_sys_path_resolve(std::string_view path, tr_error* error)
|
||||
{
|
||||
auto const szpath = tr_pathbuf{ path };
|
||||
auto buf = std::array<char, PATH_MAX>{};
|
||||
|
@ -227,11 +223,15 @@ std::string tr_sys_path_resolve(std::string_view path, tr_error** error)
|
|||
return ret;
|
||||
}
|
||||
|
||||
tr_error_set_from_errno(error, errno);
|
||||
if (error != nullptr)
|
||||
{
|
||||
error->set_from_errno(errno);
|
||||
}
|
||||
|
||||
return {};
|
||||
}
|
||||
|
||||
std::string_view tr_sys_path_basename(std::string_view path, tr_error** /*error*/)
|
||||
std::string_view tr_sys_path_basename(std::string_view path, tr_error* /*error*/)
|
||||
{
|
||||
// As per the basename() manpage:
|
||||
// If path [is] an empty string, then basename() return[s] the string "."
|
||||
|
@ -305,16 +305,16 @@ std::string_view tr_sys_path_dirname(std::string_view path)
|
|||
return path.substr(0, end);
|
||||
}
|
||||
|
||||
bool tr_sys_path_rename(char const* src_path, char const* dst_path, tr_error** error)
|
||||
bool tr_sys_path_rename(char const* src_path, char const* dst_path, tr_error* error)
|
||||
{
|
||||
TR_ASSERT(src_path != nullptr);
|
||||
TR_ASSERT(dst_path != nullptr);
|
||||
|
||||
bool const ret = rename(src_path, dst_path) != -1;
|
||||
|
||||
if (!ret)
|
||||
if (error != nullptr && !ret)
|
||||
{
|
||||
tr_error_set_from_errno(error, errno);
|
||||
error->set_from_errno(errno);
|
||||
}
|
||||
|
||||
return ret;
|
||||
|
@ -323,15 +323,21 @@ bool tr_sys_path_rename(char const* src_path, char const* dst_path, tr_error** e
|
|||
/* We try to do a fast (in-kernel) copy using a variety of non-portable system
|
||||
* calls. If the current implementation does not support in-kernel copying, we
|
||||
* use a user-space fallback instead. */
|
||||
bool tr_sys_path_copy(char const* src_path, char const* dst_path, tr_error** error)
|
||||
bool tr_sys_path_copy(char const* src_path, char const* dst_path, tr_error* error)
|
||||
{
|
||||
TR_ASSERT(src_path != nullptr);
|
||||
TR_ASSERT(dst_path != nullptr);
|
||||
|
||||
auto local_error = tr_error{};
|
||||
if (error == nullptr)
|
||||
{
|
||||
error = &local_error;
|
||||
}
|
||||
|
||||
#if defined(USE_COPYFILE)
|
||||
if (copyfile(src_path, dst_path, nullptr, COPYFILE_CLONE | COPYFILE_ALL) < 0)
|
||||
{
|
||||
tr_error_set_from_errno(error, errno);
|
||||
error->set_from_errno(errno);
|
||||
return false;
|
||||
}
|
||||
|
||||
|
@ -342,7 +348,7 @@ bool tr_sys_path_copy(char const* src_path, char const* dst_path, tr_error** err
|
|||
auto const info = tr_sys_path_get_info(src_path, 0, error);
|
||||
if (!info)
|
||||
{
|
||||
tr_error_prefix(error, "Unable to get information on source file: ");
|
||||
error->prefix_message("Unable to get information on source file: ");
|
||||
return false;
|
||||
}
|
||||
|
||||
|
@ -350,7 +356,7 @@ bool tr_sys_path_copy(char const* src_path, char const* dst_path, tr_error** err
|
|||
tr_sys_file_t const in = tr_sys_file_open(src_path, TR_SYS_FILE_READ | TR_SYS_FILE_SEQUENTIAL, 0, error);
|
||||
if (in == TR_BAD_SYS_FILE)
|
||||
{
|
||||
tr_error_prefix(error, "Unable to open source file: ");
|
||||
error->prefix_message("Unable to open source file: ");
|
||||
return false;
|
||||
}
|
||||
|
||||
|
@ -361,8 +367,8 @@ bool tr_sys_path_copy(char const* src_path, char const* dst_path, tr_error** err
|
|||
error);
|
||||
if (out == TR_BAD_SYS_FILE)
|
||||
{
|
||||
tr_error_prefix(error, "Unable to open destination file: ");
|
||||
tr_sys_file_close(in);
|
||||
error->prefix_message("Unable to open destination file: ");
|
||||
return false;
|
||||
}
|
||||
|
||||
|
@ -387,7 +393,7 @@ bool tr_sys_path_copy(char const* src_path, char const* dst_path, tr_error** err
|
|||
errno_cpy = errno; /* remember me for later */
|
||||
if (errno != EXDEV) /* EXDEV is expected, don't log error */
|
||||
{
|
||||
tr_error_set_from_errno(error, errno);
|
||||
error->set_from_errno(errno);
|
||||
}
|
||||
if (file_size > 0U)
|
||||
{
|
||||
|
@ -423,7 +429,7 @@ bool tr_sys_path_copy(char const* src_path, char const* dst_path, tr_error** err
|
|||
{
|
||||
if (errno_cpy == 0)
|
||||
{
|
||||
tr_error_set_from_errno(error, errno);
|
||||
error->set_from_errno(errno);
|
||||
}
|
||||
}
|
||||
else
|
||||
|
@ -440,7 +446,7 @@ bool tr_sys_path_copy(char const* src_path, char const* dst_path, tr_error** err
|
|||
/* use sendfile with EINVAL (invalid argument) for falling to user-space copy */
|
||||
if (errno != EINVAL) /* EINVAL is expected on some 32-bit devices (of Synology), don't log error */
|
||||
{
|
||||
tr_error_set_from_errno(error, errno);
|
||||
error->set_from_errno(errno);
|
||||
}
|
||||
if (file_size > 0U)
|
||||
{
|
||||
|
@ -475,7 +481,7 @@ bool tr_sys_path_copy(char const* src_path, char const* dst_path, tr_error** err
|
|||
{
|
||||
if (errno_cpy == 0)
|
||||
{
|
||||
tr_error_set_from_errno(error, errno);
|
||||
error->set_from_errno(errno);
|
||||
}
|
||||
}
|
||||
else
|
||||
|
@ -511,7 +517,7 @@ bool tr_sys_path_copy(char const* src_path, char const* dst_path, tr_error** err
|
|||
|
||||
if (file_size != 0)
|
||||
{
|
||||
tr_error_prefix(error, "Unable to read/write: ");
|
||||
error->prefix_message("Unable to read/write: ");
|
||||
return false;
|
||||
}
|
||||
|
||||
|
@ -520,15 +526,15 @@ bool tr_sys_path_copy(char const* src_path, char const* dst_path, tr_error** err
|
|||
#endif /* USE_COPYFILE */
|
||||
}
|
||||
|
||||
bool tr_sys_path_remove(char const* path, tr_error** error)
|
||||
bool tr_sys_path_remove(char const* path, tr_error* error)
|
||||
{
|
||||
TR_ASSERT(path != nullptr);
|
||||
|
||||
bool const ret = remove(path) != -1;
|
||||
|
||||
if (!ret)
|
||||
if (error != nullptr && !ret)
|
||||
{
|
||||
tr_error_set_from_errno(error, errno);
|
||||
error->set_from_errno(errno);
|
||||
}
|
||||
|
||||
return ret;
|
||||
|
@ -539,7 +545,7 @@ char* tr_sys_path_native_separators(char* path)
|
|||
return path;
|
||||
}
|
||||
|
||||
tr_sys_file_t tr_sys_file_get_std(tr_std_sys_file_t std_file, tr_error** error)
|
||||
tr_sys_file_t tr_sys_file_get_std(tr_std_sys_file_t std_file, tr_error* error)
|
||||
{
|
||||
tr_sys_file_t ret = TR_BAD_SYS_FILE;
|
||||
|
||||
|
@ -559,13 +565,18 @@ tr_sys_file_t tr_sys_file_get_std(tr_std_sys_file_t std_file, tr_error** error)
|
|||
|
||||
default:
|
||||
TR_ASSERT_MSG(false, fmt::format(FMT_STRING("unknown standard file {:d}"), static_cast<int>(std_file)));
|
||||
tr_error_set_from_errno(error, EINVAL);
|
||||
|
||||
if (error != nullptr)
|
||||
{
|
||||
error->set_from_errno(EINVAL);
|
||||
}
|
||||
break;
|
||||
}
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
tr_sys_file_t tr_sys_file_open(char const* path, int flags, int permissions, tr_error** error)
|
||||
tr_sys_file_t tr_sys_file_open(char const* path, int flags, int permissions, tr_error* error)
|
||||
{
|
||||
TR_ASSERT(path != nullptr);
|
||||
TR_ASSERT((flags & (TR_SYS_FILE_READ | TR_SYS_FILE_WRITE)) != 0);
|
||||
|
@ -606,23 +617,23 @@ tr_sys_file_t tr_sys_file_open(char const* path, int flags, int permissions, tr_
|
|||
set_file_for_single_pass(ret);
|
||||
}
|
||||
}
|
||||
else
|
||||
else if (error != nullptr)
|
||||
{
|
||||
tr_error_set_from_errno(error, errno);
|
||||
error->set_from_errno(errno);
|
||||
}
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
tr_sys_file_t tr_sys_file_open_temp(char* path_template, tr_error** error)
|
||||
tr_sys_file_t tr_sys_file_open_temp(char* path_template, tr_error* error)
|
||||
{
|
||||
TR_ASSERT(path_template != nullptr);
|
||||
|
||||
tr_sys_file_t const ret = mkstemp(path_template);
|
||||
|
||||
if (ret == TR_BAD_SYS_FILE)
|
||||
if (error != nullptr && ret == TR_BAD_SYS_FILE)
|
||||
{
|
||||
tr_error_set_from_errno(error, errno);
|
||||
error->set_from_errno(errno);
|
||||
}
|
||||
|
||||
set_file_for_single_pass(ret);
|
||||
|
@ -630,21 +641,21 @@ tr_sys_file_t tr_sys_file_open_temp(char* path_template, tr_error** error)
|
|||
return ret;
|
||||
}
|
||||
|
||||
bool tr_sys_file_close(tr_sys_file_t handle, tr_error** error)
|
||||
bool tr_sys_file_close(tr_sys_file_t handle, tr_error* error)
|
||||
{
|
||||
TR_ASSERT(handle != TR_BAD_SYS_FILE);
|
||||
|
||||
bool const ret = close(handle) != -1;
|
||||
|
||||
if (!ret)
|
||||
if (error != nullptr && !ret)
|
||||
{
|
||||
tr_error_set_from_errno(error, errno);
|
||||
error->set_from_errno(errno);
|
||||
}
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
bool tr_sys_file_read(tr_sys_file_t handle, void* buffer, uint64_t size, uint64_t* bytes_read, tr_error** error)
|
||||
bool tr_sys_file_read(tr_sys_file_t handle, void* buffer, uint64_t size, uint64_t* bytes_read, tr_error* error)
|
||||
{
|
||||
TR_ASSERT(handle != TR_BAD_SYS_FILE);
|
||||
TR_ASSERT(buffer != nullptr || size == 0);
|
||||
|
@ -663,9 +674,9 @@ bool tr_sys_file_read(tr_sys_file_t handle, void* buffer, uint64_t size, uint64_
|
|||
|
||||
ret = true;
|
||||
}
|
||||
else
|
||||
else if (error != nullptr)
|
||||
{
|
||||
tr_error_set_from_errno(error, errno);
|
||||
error->set_from_errno(errno);
|
||||
}
|
||||
|
||||
return ret;
|
||||
|
@ -677,7 +688,7 @@ bool tr_sys_file_read_at(
|
|||
uint64_t size,
|
||||
uint64_t offset,
|
||||
uint64_t* bytes_read,
|
||||
tr_error** error)
|
||||
tr_error* error)
|
||||
{
|
||||
TR_ASSERT(handle != TR_BAD_SYS_FILE);
|
||||
TR_ASSERT(buffer != nullptr || size == 0);
|
||||
|
@ -707,15 +718,15 @@ bool tr_sys_file_read_at(
|
|||
|
||||
ret = true;
|
||||
}
|
||||
else if (my_bytes_read == -1)
|
||||
else if (error != nullptr && my_bytes_read == -1)
|
||||
{
|
||||
tr_error_set_from_errno(error, errno);
|
||||
error->set_from_errno(errno);
|
||||
}
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
bool tr_sys_file_write(tr_sys_file_t handle, void const* buffer, uint64_t size, uint64_t* bytes_written, tr_error** error)
|
||||
bool tr_sys_file_write(tr_sys_file_t handle, void const* buffer, uint64_t size, uint64_t* bytes_written, tr_error* error)
|
||||
{
|
||||
TR_ASSERT(handle != TR_BAD_SYS_FILE);
|
||||
TR_ASSERT(buffer != nullptr || size == 0);
|
||||
|
@ -734,9 +745,9 @@ bool tr_sys_file_write(tr_sys_file_t handle, void const* buffer, uint64_t size,
|
|||
|
||||
ret = true;
|
||||
}
|
||||
else
|
||||
else if (error != nullptr)
|
||||
{
|
||||
tr_error_set_from_errno(error, errno);
|
||||
error->set_from_errno(errno);
|
||||
}
|
||||
|
||||
return ret;
|
||||
|
@ -748,7 +759,7 @@ bool tr_sys_file_write_at(
|
|||
uint64_t size,
|
||||
uint64_t offset,
|
||||
uint64_t* bytes_written,
|
||||
tr_error** error)
|
||||
tr_error* error)
|
||||
{
|
||||
TR_ASSERT(handle != TR_BAD_SYS_FILE);
|
||||
TR_ASSERT(buffer != nullptr || size == 0);
|
||||
|
@ -778,29 +789,29 @@ bool tr_sys_file_write_at(
|
|||
|
||||
ret = true;
|
||||
}
|
||||
else
|
||||
else if (error != nullptr)
|
||||
{
|
||||
tr_error_set_from_errno(error, errno);
|
||||
error->set_from_errno(errno);
|
||||
}
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
bool tr_sys_file_flush(tr_sys_file_t handle, tr_error** error)
|
||||
bool tr_sys_file_flush(tr_sys_file_t handle, tr_error* error)
|
||||
{
|
||||
TR_ASSERT(handle != TR_BAD_SYS_FILE);
|
||||
|
||||
bool const ret = (fsync(handle) != -1);
|
||||
|
||||
if (!ret)
|
||||
if (error != nullptr && !ret)
|
||||
{
|
||||
tr_error_set_from_errno(error, errno);
|
||||
error->set_from_errno(errno);
|
||||
}
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
bool tr_sys_file_flush_possible(tr_sys_file_t handle, tr_error** error)
|
||||
bool tr_sys_file_flush_possible(tr_sys_file_t handle, tr_error* error)
|
||||
{
|
||||
TR_ASSERT(handle != TR_BAD_SYS_FILE);
|
||||
|
||||
|
@ -809,19 +820,23 @@ bool tr_sys_file_flush_possible(tr_sys_file_t handle, tr_error** error)
|
|||
return S_ISREG(statbuf.st_mode);
|
||||
}
|
||||
|
||||
tr_error_set_from_errno(error, errno);
|
||||
if (error != nullptr)
|
||||
{
|
||||
error->set_from_errno(errno);
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
bool tr_sys_file_truncate(tr_sys_file_t handle, uint64_t size, tr_error** error)
|
||||
bool tr_sys_file_truncate(tr_sys_file_t handle, uint64_t size, tr_error* error)
|
||||
{
|
||||
TR_ASSERT(handle != TR_BAD_SYS_FILE);
|
||||
|
||||
bool const ret = ftruncate(handle, size) != -1;
|
||||
|
||||
if (!ret)
|
||||
if (error != nullptr && !ret)
|
||||
{
|
||||
tr_error_set_from_errno(error, errno);
|
||||
error->set_from_errno(errno);
|
||||
}
|
||||
|
||||
return ret;
|
||||
|
@ -832,7 +847,7 @@ bool tr_sys_file_advise(
|
|||
[[maybe_unused]] uint64_t offset,
|
||||
[[maybe_unused]] uint64_t size,
|
||||
[[maybe_unused]] tr_sys_file_advice_t advice,
|
||||
[[maybe_unused]] tr_error** error)
|
||||
[[maybe_unused]] tr_error* error)
|
||||
{
|
||||
TR_ASSERT(handle != TR_BAD_SYS_FILE);
|
||||
TR_ASSERT(size > 0);
|
||||
|
@ -850,7 +865,11 @@ bool tr_sys_file_advise(
|
|||
|
||||
if (int const code = posix_fadvise(handle, offset, size, native_advice); code != 0)
|
||||
{
|
||||
tr_error_set_from_errno(error, code);
|
||||
if (error != nullptr)
|
||||
{
|
||||
error->set_from_errno(errno);
|
||||
}
|
||||
|
||||
ret = false;
|
||||
}
|
||||
|
||||
|
@ -864,9 +883,9 @@ bool tr_sys_file_advise(
|
|||
|
||||
ret = fcntl(handle, F_RDADVISE, &radv) != -1;
|
||||
|
||||
if (!ret)
|
||||
if (error != nullptr && !ret)
|
||||
{
|
||||
tr_error_set_from_errno(error, errno);
|
||||
error->set_from_errno(errno);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -877,7 +896,8 @@ bool tr_sys_file_advise(
|
|||
|
||||
namespace
|
||||
{
|
||||
|
||||
namespace preallocate_helpers
|
||||
{
|
||||
#ifdef HAVE_FALLOCATE64
|
||||
bool preallocate_fallocate64(tr_sys_file_t handle, uint64_t size)
|
||||
{
|
||||
|
@ -938,11 +958,13 @@ bool full_preallocate_posix(tr_sys_file_t handle, uint64_t size)
|
|||
return posix_fallocate(handle, 0, size) == 0;
|
||||
}
|
||||
#endif
|
||||
|
||||
} // namespace preallocate_helpers
|
||||
} // unnamed namespace
|
||||
|
||||
bool tr_sys_file_preallocate(tr_sys_file_t handle, uint64_t size, int flags, tr_error** error)
|
||||
bool tr_sys_file_preallocate(tr_sys_file_t handle, uint64_t size, int flags, tr_error* error)
|
||||
{
|
||||
using namespace preallocate_helpers;
|
||||
|
||||
TR_ASSERT(handle != TR_BAD_SYS_FILE);
|
||||
|
||||
using prealloc_func = bool (*)(tr_sys_file_t, uint64_t);
|
||||
|
@ -992,11 +1014,15 @@ bool tr_sys_file_preallocate(tr_sys_file_t handle, uint64_t size, int flags, tr_
|
|||
}
|
||||
}
|
||||
|
||||
tr_error_set_from_errno(error, errno);
|
||||
if (error != nullptr)
|
||||
{
|
||||
error->set_from_errno(errno ? errno : ENOSYS);
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
bool tr_sys_file_lock([[maybe_unused]] tr_sys_file_t handle, [[maybe_unused]] int operation, tr_error** error)
|
||||
bool tr_sys_file_lock([[maybe_unused]] tr_sys_file_t handle, [[maybe_unused]] int operation, tr_error* error)
|
||||
{
|
||||
TR_ASSERT(handle != TR_BAD_SYS_FILE);
|
||||
TR_ASSERT((operation & ~(TR_SYS_FILE_LOCK_SH | TR_SYS_FILE_LOCK_EX | TR_SYS_FILE_LOCK_NB | TR_SYS_FILE_LOCK_UN)) == 0);
|
||||
|
@ -1072,15 +1098,15 @@ bool tr_sys_file_lock([[maybe_unused]] tr_sys_file_t handle, [[maybe_unused]] in
|
|||
|
||||
#endif
|
||||
|
||||
if (!ret)
|
||||
if (error != nullptr && !ret)
|
||||
{
|
||||
tr_error_set_from_errno(error, errno);
|
||||
error->set_from_errno(errno);
|
||||
}
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
std::string tr_sys_dir_get_current(tr_error** error)
|
||||
std::string tr_sys_dir_get_current(tr_error* error)
|
||||
{
|
||||
auto buf = std::vector<char>{};
|
||||
buf.resize(PATH_MAX);
|
||||
|
@ -1092,20 +1118,25 @@ std::string tr_sys_dir_get_current(tr_error** error)
|
|||
return ret;
|
||||
}
|
||||
|
||||
if (errno != ERANGE)
|
||||
if (errno == ERANGE)
|
||||
{
|
||||
tr_error_set_from_errno(error, errno);
|
||||
return {};
|
||||
buf.resize(std::size(buf) * 2U);
|
||||
continue;
|
||||
}
|
||||
|
||||
buf.resize(std::size(buf) * 2);
|
||||
if (error != nullptr)
|
||||
{
|
||||
error->set_from_errno(errno);
|
||||
}
|
||||
|
||||
return {};
|
||||
}
|
||||
}
|
||||
|
||||
namespace
|
||||
{
|
||||
#ifndef HAVE_MKDIRP
|
||||
[[nodiscard]] bool tr_mkdirp_(std::string_view path, int permissions, tr_error** error)
|
||||
[[nodiscard]] bool tr_mkdirp_(std::string_view path, int permissions, tr_error* error)
|
||||
{
|
||||
auto walk = path.find_first_not_of('/'); // walk past the root
|
||||
auto subpath = tr_pathbuf{};
|
||||
|
@ -1117,12 +1148,20 @@ namespace
|
|||
auto const info = tr_sys_path_get_info(subpath, 0);
|
||||
if (info && !info->isFolder())
|
||||
{
|
||||
tr_error_set(error, ENOTDIR, fmt::format(FMT_STRING("File is in the way: {:s}"), path));
|
||||
if (error != nullptr)
|
||||
{
|
||||
error->set(ENOTDIR, fmt::format(FMT_STRING("File is in the way: {:s}"), path));
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
if (!info && mkdir(subpath, permissions) == -1)
|
||||
{
|
||||
tr_error_set_from_errno(error, errno);
|
||||
if (error != nullptr)
|
||||
{
|
||||
error->set_from_errno(errno);
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
if (end == std::string_view::npos)
|
||||
|
@ -1137,19 +1176,19 @@ namespace
|
|||
#endif
|
||||
} // namespace
|
||||
|
||||
bool tr_sys_dir_create(char const* path, int flags, int permissions, tr_error** error)
|
||||
bool tr_sys_dir_create(char const* path, int flags, int permissions, tr_error* error)
|
||||
{
|
||||
TR_ASSERT(path != nullptr);
|
||||
|
||||
bool ret = false;
|
||||
tr_error* my_error = nullptr;
|
||||
auto ret = bool{ false };
|
||||
auto local_error = tr_error{};
|
||||
|
||||
if ((flags & TR_SYS_DIR_CREATE_PARENTS) != 0)
|
||||
{
|
||||
#ifdef HAVE_MKDIRP
|
||||
ret = mkdirp(path, permissions) != -1;
|
||||
#else
|
||||
ret = tr_mkdirp_(path, permissions, &my_error);
|
||||
ret = tr_mkdirp_(path, permissions, &local_error);
|
||||
#endif
|
||||
}
|
||||
else
|
||||
|
@ -1161,7 +1200,7 @@ bool tr_sys_dir_create(char const* path, int flags, int permissions, tr_error**
|
|||
{
|
||||
if (auto const info = tr_sys_path_get_info(path); info && info->type == TR_SYS_PATH_IS_DIRECTORY)
|
||||
{
|
||||
tr_error_clear(&my_error);
|
||||
local_error = {};
|
||||
ret = true;
|
||||
}
|
||||
else
|
||||
|
@ -1170,22 +1209,20 @@ bool tr_sys_dir_create(char const* path, int flags, int permissions, tr_error**
|
|||
}
|
||||
}
|
||||
|
||||
if (!ret)
|
||||
if (error != nullptr && !ret)
|
||||
{
|
||||
if (my_error != nullptr)
|
||||
if (!local_error)
|
||||
{
|
||||
tr_error_propagate(error, &my_error);
|
||||
}
|
||||
else
|
||||
{
|
||||
tr_error_set_from_errno(error, errno);
|
||||
local_error.set_from_errno(errno);
|
||||
}
|
||||
|
||||
*error = std::move(local_error);
|
||||
}
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
bool tr_sys_dir_create_temp(char* path_template, tr_error** error)
|
||||
bool tr_sys_dir_create_temp(char* path_template, tr_error* error)
|
||||
{
|
||||
TR_ASSERT(path_template != nullptr);
|
||||
|
||||
|
@ -1199,57 +1236,61 @@ bool tr_sys_dir_create_temp(char* path_template, tr_error** error)
|
|||
|
||||
#endif
|
||||
|
||||
if (!ret)
|
||||
if (error != nullptr && !ret)
|
||||
{
|
||||
tr_error_set_from_errno(error, errno);
|
||||
error->set_from_errno(errno);
|
||||
}
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
tr_sys_dir_t tr_sys_dir_open(std::string_view path, tr_error** error)
|
||||
tr_sys_dir_t tr_sys_dir_open(std::string_view path, tr_error* error)
|
||||
{
|
||||
auto* const ret = opendir(tr_pathbuf{ path });
|
||||
|
||||
if (ret == nullptr)
|
||||
if (auto* const ret = opendir(tr_pathbuf{ path }); ret != nullptr)
|
||||
{
|
||||
tr_error_set_from_errno(error, errno);
|
||||
return TR_BAD_SYS_DIR;
|
||||
return (tr_sys_dir_t)ret;
|
||||
}
|
||||
|
||||
return (tr_sys_dir_t)ret;
|
||||
if (error != nullptr)
|
||||
{
|
||||
error->set_from_errno(errno);
|
||||
}
|
||||
|
||||
return TR_BAD_SYS_DIR;
|
||||
}
|
||||
|
||||
char const* tr_sys_dir_read_name(tr_sys_dir_t handle, tr_error** error)
|
||||
char const* tr_sys_dir_read_name(tr_sys_dir_t handle, tr_error* error)
|
||||
{
|
||||
TR_ASSERT(handle != TR_BAD_SYS_DIR);
|
||||
|
||||
char const* ret = nullptr;
|
||||
|
||||
errno = 0;
|
||||
|
||||
if (auto const* const entry = readdir(static_cast<DIR*>(handle)); entry != nullptr)
|
||||
{
|
||||
ret = entry->d_name;
|
||||
}
|
||||
else if (errno != 0)
|
||||
{
|
||||
tr_error_set_from_errno(error, errno);
|
||||
return entry->d_name;
|
||||
}
|
||||
|
||||
return ret;
|
||||
if (error != nullptr && errno != 0)
|
||||
{
|
||||
error->set_from_errno(errno);
|
||||
}
|
||||
|
||||
return {};
|
||||
}
|
||||
|
||||
bool tr_sys_dir_close(tr_sys_dir_t handle, tr_error** error)
|
||||
bool tr_sys_dir_close(tr_sys_dir_t handle, tr_error* error)
|
||||
{
|
||||
TR_ASSERT(handle != TR_BAD_SYS_DIR);
|
||||
|
||||
bool const ret = closedir(static_cast<DIR*>(handle)) != -1;
|
||||
|
||||
if (!ret)
|
||||
if (auto const ret = closedir(static_cast<DIR*>(handle)) != -1; ret)
|
||||
{
|
||||
tr_error_set_from_errno(error, errno);
|
||||
return ret;
|
||||
}
|
||||
|
||||
return ret;
|
||||
if (error != nullptr)
|
||||
{
|
||||
error->set_from_errno(errno);
|
||||
}
|
||||
|
||||
return {};
|
||||
}
|
||||
|
|
|
@ -46,24 +46,16 @@ struct tr_sys_dir_win32
|
|||
static auto constexpr NativeLocalPathPrefix = L"\\\\?\\"sv;
|
||||
static auto constexpr NativeUncPathPrefix = L"\\\\?\\UNC\\"sv;
|
||||
|
||||
static void set_system_error(tr_error** error, DWORD code)
|
||||
static void set_system_error(tr_error* error, DWORD code)
|
||||
{
|
||||
if (error == nullptr)
|
||||
if (error != nullptr)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
if (auto const message = tr_win32_format_message(code); !std::empty(message))
|
||||
{
|
||||
tr_error_set(error, code, message);
|
||||
}
|
||||
else
|
||||
{
|
||||
tr_error_set(error, code, fmt::format(FMT_STRING("Unknown error: {:#08x}"), code));
|
||||
auto const message = tr_win32_format_message(code);
|
||||
error->set(code, !std::empty(message) ? message : fmt::format(FMT_STRING("Unknown error: {:#08x}"), code));
|
||||
}
|
||||
}
|
||||
|
||||
static void set_system_error_if_file_found(tr_error** error, DWORD code)
|
||||
static void set_system_error_if_file_found(tr_error* error, DWORD code)
|
||||
{
|
||||
if (code != ERROR_FILE_NOT_FOUND && code != ERROR_PATH_NOT_FOUND && code != ERROR_NO_MORE_FILES)
|
||||
{
|
||||
|
@ -229,7 +221,7 @@ static std::string native_path_to_path(std::wstring_view wide_path)
|
|||
return tr_win32_native_to_utf8(wide_path);
|
||||
}
|
||||
|
||||
static tr_sys_file_t open_file(std::string_view path, DWORD access, DWORD disposition, DWORD flags, tr_error** error)
|
||||
static tr_sys_file_t open_file(std::string_view path, DWORD access, DWORD disposition, DWORD flags, tr_error* error)
|
||||
{
|
||||
tr_sys_file_t ret = TR_BAD_SYS_FILE;
|
||||
|
||||
|
@ -253,7 +245,7 @@ static tr_sys_file_t open_file(std::string_view path, DWORD access, DWORD dispos
|
|||
return ret;
|
||||
}
|
||||
|
||||
static bool create_dir(std::string_view path, int flags, int /*permissions*/, bool okay_if_exists, tr_error** error)
|
||||
static bool create_dir(std::string_view path, int flags, int /*permissions*/, bool okay_if_exists, tr_error* error)
|
||||
{
|
||||
bool ret;
|
||||
DWORD error_code = ERROR_SUCCESS;
|
||||
|
@ -300,9 +292,9 @@ static bool create_dir(std::string_view path, int flags, int /*permissions*/, bo
|
|||
|
||||
static void create_temp_path(
|
||||
char* path_template,
|
||||
void (*callback)(char const* path, void* param, tr_error** error),
|
||||
void (*callback)(char const* path, void* param, tr_error* error),
|
||||
void* callback_param,
|
||||
tr_error** error)
|
||||
tr_error* error)
|
||||
{
|
||||
TR_ASSERT(path_template != nullptr);
|
||||
TR_ASSERT(callback != nullptr);
|
||||
|
@ -312,7 +304,7 @@ static void create_temp_path(
|
|||
|
||||
TR_ASSERT(path_size > 0);
|
||||
|
||||
tr_error* my_error = nullptr;
|
||||
auto local_error = tr_error{};
|
||||
|
||||
for (int attempt = 0; attempt < 100; ++attempt)
|
||||
{
|
||||
|
@ -327,27 +319,27 @@ static void create_temp_path(
|
|||
|
||||
TR_ASSERT(path_size >= i + 6);
|
||||
|
||||
tr_error_clear(&my_error);
|
||||
local_error = {};
|
||||
|
||||
(*callback)(path.c_str(), callback_param, &my_error);
|
||||
(*callback)(path.c_str(), callback_param, &local_error);
|
||||
|
||||
if (my_error == nullptr)
|
||||
if (!local_error)
|
||||
{
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if (my_error != nullptr)
|
||||
{
|
||||
tr_error_propagate(error, &my_error);
|
||||
}
|
||||
else
|
||||
if (!local_error)
|
||||
{
|
||||
std::copy_n(std::begin(path), path_size, path_template);
|
||||
}
|
||||
else if (error != nullptr)
|
||||
{
|
||||
*error = std::move(local_error);
|
||||
}
|
||||
}
|
||||
|
||||
bool tr_sys_path_exists(char const* path, tr_error** error)
|
||||
bool tr_sys_path_exists(char const* path, tr_error* error)
|
||||
{
|
||||
TR_ASSERT(path != nullptr);
|
||||
|
||||
|
@ -385,7 +377,7 @@ bool tr_sys_path_exists(char const* path, tr_error** error)
|
|||
return ret;
|
||||
}
|
||||
|
||||
static std::optional<tr_sys_path_info> tr_sys_file_get_info_(tr_sys_file_t handle, tr_error** error)
|
||||
static std::optional<tr_sys_path_info> tr_sys_file_get_info_(tr_sys_file_t handle, tr_error* error)
|
||||
{
|
||||
TR_ASSERT(handle != TR_BAD_SYS_FILE);
|
||||
|
||||
|
@ -403,7 +395,7 @@ static std::optional<tr_sys_path_info> tr_sys_file_get_info_(tr_sys_file_t handl
|
|||
return {};
|
||||
}
|
||||
|
||||
std::optional<tr_sys_path_info> tr_sys_path_get_info(std::string_view path, int flags, tr_error** error)
|
||||
std::optional<tr_sys_path_info> tr_sys_path_get_info(std::string_view path, int flags, tr_error* error)
|
||||
{
|
||||
if (auto const wide_path = path_to_native_path(path); std::empty(wide_path))
|
||||
{
|
||||
|
@ -457,7 +449,7 @@ bool tr_sys_path_is_relative(std::string_view path)
|
|||
return true;
|
||||
}
|
||||
|
||||
static std::optional<BY_HANDLE_FILE_INFORMATION> get_file_info(char const* path, tr_error** error)
|
||||
static std::optional<BY_HANDLE_FILE_INFORMATION> get_file_info(char const* path, tr_error* error)
|
||||
{
|
||||
auto const wpath = path_to_native_path(path);
|
||||
if (std::empty(wpath))
|
||||
|
@ -486,7 +478,7 @@ static std::optional<BY_HANDLE_FILE_INFORMATION> get_file_info(char const* path,
|
|||
return info;
|
||||
}
|
||||
|
||||
bool tr_sys_path_is_same(char const* path1, char const* path2, tr_error** error)
|
||||
bool tr_sys_path_is_same(char const* path1, char const* path2, tr_error* error)
|
||||
{
|
||||
TR_ASSERT(path1 != nullptr);
|
||||
TR_ASSERT(path2 != nullptr);
|
||||
|
@ -507,7 +499,7 @@ bool tr_sys_path_is_same(char const* path1, char const* path2, tr_error** error)
|
|||
fi1->nFileIndexLow == fi2->nFileIndexLow;
|
||||
}
|
||||
|
||||
std::string tr_sys_path_resolve(std::string_view path, tr_error** error)
|
||||
std::string tr_sys_path_resolve(std::string_view path, tr_error* error)
|
||||
{
|
||||
auto ret = std::string{};
|
||||
|
||||
|
@ -549,7 +541,7 @@ std::string tr_sys_path_resolve(std::string_view path, tr_error** error)
|
|||
return {};
|
||||
}
|
||||
|
||||
std::string_view tr_sys_path_basename(std::string_view path, tr_error** error)
|
||||
std::string_view tr_sys_path_basename(std::string_view path, tr_error* error)
|
||||
{
|
||||
if (std::empty(path))
|
||||
{
|
||||
|
@ -705,7 +697,7 @@ std::string_view tr_sys_path_dirname(std::string_view path)
|
|||
return path.substr(0, end);
|
||||
}
|
||||
|
||||
bool tr_sys_path_rename(char const* src_path, char const* dst_path, tr_error** error)
|
||||
bool tr_sys_path_rename(char const* src_path, char const* dst_path, tr_error* error)
|
||||
{
|
||||
TR_ASSERT(src_path != nullptr);
|
||||
TR_ASSERT(dst_path != nullptr);
|
||||
|
@ -746,7 +738,7 @@ bool tr_sys_path_rename(char const* src_path, char const* dst_path, tr_error** e
|
|||
return ret;
|
||||
}
|
||||
|
||||
bool tr_sys_path_copy(char const* src_path, char const* dst_path, tr_error** error)
|
||||
bool tr_sys_path_copy(char const* src_path, char const* dst_path, tr_error* error)
|
||||
{
|
||||
TR_ASSERT(src_path != nullptr);
|
||||
TR_ASSERT(dst_path != nullptr);
|
||||
|
@ -770,7 +762,7 @@ bool tr_sys_path_copy(char const* src_path, char const* dst_path, tr_error** err
|
|||
return true;
|
||||
}
|
||||
|
||||
bool tr_sys_path_remove(char const* path, tr_error** error)
|
||||
bool tr_sys_path_remove(char const* path, tr_error* error)
|
||||
{
|
||||
TR_ASSERT(path != nullptr);
|
||||
|
||||
|
@ -816,7 +808,7 @@ char* tr_sys_path_native_separators(char* path)
|
|||
return path;
|
||||
}
|
||||
|
||||
tr_sys_file_t tr_sys_file_get_std(tr_std_sys_file_t std_file, tr_error** error)
|
||||
tr_sys_file_t tr_sys_file_get_std(tr_std_sys_file_t std_file, tr_error* error)
|
||||
{
|
||||
tr_sys_file_t ret = TR_BAD_SYS_FILE;
|
||||
|
||||
|
@ -852,7 +844,7 @@ tr_sys_file_t tr_sys_file_get_std(tr_std_sys_file_t std_file, tr_error** error)
|
|||
return ret;
|
||||
}
|
||||
|
||||
tr_sys_file_t tr_sys_file_open(char const* path, int flags, int /*permissions*/, tr_error** error)
|
||||
tr_sys_file_t tr_sys_file_open(char const* path, int flags, int /*permissions*/, tr_error* error)
|
||||
{
|
||||
TR_ASSERT(path != nullptr);
|
||||
TR_ASSERT((flags & (TR_SYS_FILE_READ | TR_SYS_FILE_WRITE)) != 0);
|
||||
|
@ -898,10 +890,7 @@ tr_sys_file_t tr_sys_file_open(char const* path, int flags, int /*permissions*/,
|
|||
|
||||
if (!success)
|
||||
{
|
||||
if (error == nullptr)
|
||||
{
|
||||
set_system_error(error, GetLastError());
|
||||
}
|
||||
set_system_error(error, GetLastError());
|
||||
|
||||
CloseHandle(ret);
|
||||
ret = TR_BAD_SYS_FILE;
|
||||
|
@ -910,16 +899,16 @@ tr_sys_file_t tr_sys_file_open(char const* path, int flags, int /*permissions*/,
|
|||
return ret;
|
||||
}
|
||||
|
||||
static void file_open_temp_callback(char const* path, void* param, tr_error** error)
|
||||
static void file_open_temp_callback(char const* path, void* param, tr_error* error)
|
||||
{
|
||||
tr_sys_file_t* result = (tr_sys_file_t*)param;
|
||||
auto* const result = static_cast<tr_sys_file_t*>(param);
|
||||
|
||||
TR_ASSERT(result != nullptr);
|
||||
|
||||
*result = open_file(path, GENERIC_READ | GENERIC_WRITE, CREATE_NEW, FILE_ATTRIBUTE_TEMPORARY, error);
|
||||
}
|
||||
|
||||
tr_sys_file_t tr_sys_file_open_temp(char* path_template, tr_error** error)
|
||||
tr_sys_file_t tr_sys_file_open_temp(char* path_template, tr_error* error)
|
||||
{
|
||||
TR_ASSERT(path_template != nullptr);
|
||||
|
||||
|
@ -930,7 +919,7 @@ tr_sys_file_t tr_sys_file_open_temp(char* path_template, tr_error** error)
|
|||
return ret;
|
||||
}
|
||||
|
||||
bool tr_sys_file_close(tr_sys_file_t handle, tr_error** error)
|
||||
bool tr_sys_file_close(tr_sys_file_t handle, tr_error* error)
|
||||
{
|
||||
TR_ASSERT(handle != TR_BAD_SYS_FILE);
|
||||
|
||||
|
@ -944,7 +933,7 @@ bool tr_sys_file_close(tr_sys_file_t handle, tr_error** error)
|
|||
return ret;
|
||||
}
|
||||
|
||||
bool tr_sys_file_read(tr_sys_file_t handle, void* buffer, uint64_t size, uint64_t* bytes_read, tr_error** error)
|
||||
bool tr_sys_file_read(tr_sys_file_t handle, void* buffer, uint64_t size, uint64_t* bytes_read, tr_error* error)
|
||||
{
|
||||
TR_ASSERT(handle != TR_BAD_SYS_FILE);
|
||||
TR_ASSERT(buffer != nullptr || size == 0);
|
||||
|
@ -981,7 +970,7 @@ bool tr_sys_file_read_at(
|
|||
uint64_t size,
|
||||
uint64_t offset,
|
||||
uint64_t* bytes_read,
|
||||
tr_error** error)
|
||||
tr_error* error)
|
||||
{
|
||||
TR_ASSERT(handle != TR_BAD_SYS_FILE);
|
||||
TR_ASSERT(buffer != nullptr || size == 0);
|
||||
|
@ -1018,7 +1007,7 @@ bool tr_sys_file_read_at(
|
|||
return ret;
|
||||
}
|
||||
|
||||
bool tr_sys_file_write(tr_sys_file_t handle, void const* buffer, uint64_t size, uint64_t* bytes_written, tr_error** error)
|
||||
bool tr_sys_file_write(tr_sys_file_t handle, void const* buffer, uint64_t size, uint64_t* bytes_written, tr_error* error)
|
||||
{
|
||||
TR_ASSERT(handle != TR_BAD_SYS_FILE);
|
||||
TR_ASSERT(buffer != nullptr || size == 0);
|
||||
|
@ -1055,7 +1044,7 @@ bool tr_sys_file_write_at(
|
|||
uint64_t size,
|
||||
uint64_t offset,
|
||||
uint64_t* bytes_written,
|
||||
tr_error** error)
|
||||
tr_error* error)
|
||||
{
|
||||
TR_ASSERT(handle != TR_BAD_SYS_FILE);
|
||||
TR_ASSERT(buffer != nullptr || size == 0);
|
||||
|
@ -1092,7 +1081,7 @@ bool tr_sys_file_write_at(
|
|||
return ret;
|
||||
}
|
||||
|
||||
bool tr_sys_file_flush(tr_sys_file_t handle, tr_error** error)
|
||||
bool tr_sys_file_flush(tr_sys_file_t handle, tr_error* error)
|
||||
{
|
||||
TR_ASSERT(handle != TR_BAD_SYS_FILE);
|
||||
|
||||
|
@ -1106,7 +1095,7 @@ bool tr_sys_file_flush(tr_sys_file_t handle, tr_error** error)
|
|||
return ret;
|
||||
}
|
||||
|
||||
bool tr_sys_file_flush_possible(tr_sys_file_t handle, tr_error** error)
|
||||
bool tr_sys_file_flush_possible(tr_sys_file_t handle, tr_error* error)
|
||||
{
|
||||
TR_ASSERT(handle != TR_BAD_SYS_FILE);
|
||||
|
||||
|
@ -1121,7 +1110,7 @@ bool tr_sys_file_flush_possible(tr_sys_file_t handle, tr_error** error)
|
|||
return type == FILE_TYPE_DISK;
|
||||
}
|
||||
|
||||
bool tr_sys_file_truncate(tr_sys_file_t handle, uint64_t size, tr_error** error)
|
||||
bool tr_sys_file_truncate(tr_sys_file_t handle, uint64_t size, tr_error* error)
|
||||
{
|
||||
TR_ASSERT(handle != TR_BAD_SYS_FILE);
|
||||
|
||||
|
@ -1143,7 +1132,7 @@ bool tr_sys_file_advise(
|
|||
uint64_t /*offset*/,
|
||||
[[maybe_unused]] uint64_t size,
|
||||
[[maybe_unused]] tr_sys_file_advice_t advice,
|
||||
tr_error** /*error*/)
|
||||
tr_error* /*error*/)
|
||||
{
|
||||
TR_ASSERT(handle != TR_BAD_SYS_FILE);
|
||||
TR_ASSERT(size > 0);
|
||||
|
@ -1156,7 +1145,7 @@ bool tr_sys_file_advise(
|
|||
return ret;
|
||||
}
|
||||
|
||||
bool tr_sys_file_preallocate(tr_sys_file_t handle, uint64_t size, int flags, tr_error** error)
|
||||
bool tr_sys_file_preallocate(tr_sys_file_t handle, uint64_t size, int flags, tr_error* error)
|
||||
{
|
||||
TR_ASSERT(handle != TR_BAD_SYS_FILE);
|
||||
|
||||
|
@ -1174,7 +1163,7 @@ bool tr_sys_file_preallocate(tr_sys_file_t handle, uint64_t size, int flags, tr_
|
|||
return tr_sys_file_truncate(handle, size, error);
|
||||
}
|
||||
|
||||
bool tr_sys_file_lock(tr_sys_file_t handle, int operation, tr_error** error)
|
||||
bool tr_sys_file_lock(tr_sys_file_t handle, int operation, tr_error* error)
|
||||
{
|
||||
TR_ASSERT(handle != TR_BAD_SYS_FILE);
|
||||
TR_ASSERT((operation & ~(TR_SYS_FILE_LOCK_SH | TR_SYS_FILE_LOCK_EX | TR_SYS_FILE_LOCK_NB | TR_SYS_FILE_LOCK_UN)) == 0);
|
||||
|
@ -1213,7 +1202,7 @@ bool tr_sys_file_lock(tr_sys_file_t handle, int operation, tr_error** error)
|
|||
return ret;
|
||||
}
|
||||
|
||||
std::string tr_sys_dir_get_current(tr_error** error)
|
||||
std::string tr_sys_dir_get_current(tr_error* error)
|
||||
{
|
||||
if (auto const size = GetCurrentDirectoryW(0, nullptr); size != 0)
|
||||
{
|
||||
|
@ -1231,21 +1220,21 @@ std::string tr_sys_dir_get_current(tr_error** error)
|
|||
return {};
|
||||
}
|
||||
|
||||
bool tr_sys_dir_create(char const* path, int flags, int permissions, tr_error** error)
|
||||
bool tr_sys_dir_create(char const* path, int flags, int permissions, tr_error* error)
|
||||
{
|
||||
return create_dir(path, flags, permissions, true, error);
|
||||
}
|
||||
|
||||
static void dir_create_temp_callback(char const* path, void* param, tr_error** error)
|
||||
static void dir_create_temp_callback(char const* path, void* param, tr_error* error)
|
||||
{
|
||||
bool* result = (bool*)param;
|
||||
auto* const result = static_cast<bool*>(param);
|
||||
|
||||
TR_ASSERT(result != nullptr);
|
||||
|
||||
*result = create_dir(path, 0, 0, false, error);
|
||||
}
|
||||
|
||||
bool tr_sys_dir_create_temp(char* path_template, tr_error** error)
|
||||
bool tr_sys_dir_create_temp(char* path_template, tr_error* error)
|
||||
{
|
||||
TR_ASSERT(path_template != nullptr);
|
||||
|
||||
|
@ -1256,9 +1245,9 @@ bool tr_sys_dir_create_temp(char* path_template, tr_error** error)
|
|||
return ret;
|
||||
}
|
||||
|
||||
tr_sys_dir_t tr_sys_dir_open(std::string_view path, tr_error** error)
|
||||
tr_sys_dir_t tr_sys_dir_open(std::string_view path, tr_error* error)
|
||||
{
|
||||
TR_ASSERT(path != nullptr);
|
||||
TR_ASSERT(!std::empty(path));
|
||||
|
||||
if (auto const info = tr_sys_path_get_info(path, 0); !info || !info->isFolder())
|
||||
{
|
||||
|
@ -1266,7 +1255,7 @@ tr_sys_dir_t tr_sys_dir_open(std::string_view path, tr_error** error)
|
|||
return TR_BAD_SYS_DIR;
|
||||
}
|
||||
|
||||
auto pattern = path_to_native_path(path);
|
||||
auto const pattern = path_to_native_path(path);
|
||||
if (std::empty(pattern))
|
||||
{
|
||||
set_system_error(error, GetLastError());
|
||||
|
@ -1279,7 +1268,7 @@ tr_sys_dir_t tr_sys_dir_open(std::string_view path, tr_error** error)
|
|||
return ret;
|
||||
}
|
||||
|
||||
char const* tr_sys_dir_read_name(tr_sys_dir_t handle, tr_error** error)
|
||||
char const* tr_sys_dir_read_name(tr_sys_dir_t handle, tr_error* error)
|
||||
{
|
||||
TR_ASSERT(handle != TR_BAD_SYS_DIR);
|
||||
|
||||
|
@ -1318,7 +1307,7 @@ char const* tr_sys_dir_read_name(tr_sys_dir_t handle, tr_error** error)
|
|||
return nullptr;
|
||||
}
|
||||
|
||||
bool tr_sys_dir_close(tr_sys_dir_t handle, tr_error** error)
|
||||
bool tr_sys_dir_close(tr_sys_dir_t handle, tr_error* error)
|
||||
{
|
||||
TR_ASSERT(handle != TR_BAD_SYS_DIR);
|
||||
|
||||
|
|
|
@ -7,6 +7,7 @@
|
|||
#include <string_view>
|
||||
#include <vector>
|
||||
|
||||
#include "libtransmission/error.h"
|
||||
#include "libtransmission/file.h"
|
||||
#include "libtransmission/tr-assert.h"
|
||||
|
||||
|
@ -18,7 +19,7 @@ static auto constexpr NativeEol = "\r\n"sv;
|
|||
static auto constexpr NativeEol = "\n"sv;
|
||||
#endif
|
||||
|
||||
bool tr_sys_file_write_line(tr_sys_file_t handle, std::string_view buffer, tr_error** error)
|
||||
bool tr_sys_file_write_line(tr_sys_file_t handle, std::string_view buffer, tr_error* error)
|
||||
{
|
||||
TR_ASSERT(handle != TR_BAD_SYS_FILE);
|
||||
|
||||
|
@ -29,7 +30,7 @@ bool tr_sys_file_write_line(tr_sys_file_t handle, std::string_view buffer, tr_er
|
|||
std::vector<std::string> tr_sys_dir_get_files(
|
||||
std::string_view folder,
|
||||
std::function<bool(std::string_view)> const& test,
|
||||
tr_error** error)
|
||||
tr_error* error)
|
||||
{
|
||||
if (auto const info = tr_sys_path_get_info(folder); !info || !info->isFolder())
|
||||
{
|
||||
|
|
|
@ -146,7 +146,7 @@ struct tr_sys_path_capacity
|
|||
*
|
||||
* @return `True` on success, `false` otherwise (with `error` set accordingly).
|
||||
*/
|
||||
bool tr_sys_path_copy(char const* src_path, char const* dst_path, struct tr_error** error = nullptr);
|
||||
bool tr_sys_path_copy(char const* src_path, char const* dst_path, tr_error* error = nullptr);
|
||||
|
||||
/**
|
||||
* @brief Portability wrapper for `stat()`.
|
||||
|
@ -161,7 +161,7 @@ bool tr_sys_path_copy(char const* src_path, char const* dst_path, struct tr_erro
|
|||
[[nodiscard]] std::optional<tr_sys_path_info> tr_sys_path_get_info(
|
||||
std::string_view path,
|
||||
int flags = 0,
|
||||
tr_error** error = nullptr);
|
||||
tr_error* error = nullptr);
|
||||
|
||||
/**
|
||||
* @brief Get disk capacity and free disk space (in bytes) for the specified folder.
|
||||
|
@ -170,7 +170,7 @@ bool tr_sys_path_copy(char const* src_path, char const* dst_path, struct tr_erro
|
|||
* @param[out] error Pointer to error object. Optional, pass `nullptr` if you
|
||||
* are not interested in error details.
|
||||
*/
|
||||
[[nodiscard]] std::optional<tr_sys_path_capacity> tr_sys_path_get_capacity(std::string_view path, tr_error** error = nullptr);
|
||||
[[nodiscard]] std::optional<tr_sys_path_capacity> tr_sys_path_get_capacity(std::string_view path, tr_error* error = nullptr);
|
||||
|
||||
/**
|
||||
* @brief Portability wrapper for `access()`.
|
||||
|
@ -183,10 +183,10 @@ bool tr_sys_path_copy(char const* src_path, char const* dst_path, struct tr_erro
|
|||
* be returned in case of error; if you need to distinguish the two,
|
||||
* check if `error` is `nullptr` afterwards.
|
||||
*/
|
||||
bool tr_sys_path_exists(char const* path, struct tr_error** error = nullptr);
|
||||
bool tr_sys_path_exists(char const* path, tr_error* error = nullptr);
|
||||
|
||||
template<typename T, typename = decltype(&T::c_str)>
|
||||
bool tr_sys_path_exists(T const& path, struct tr_error** error = nullptr)
|
||||
bool tr_sys_path_exists(T const& path, tr_error* error = nullptr)
|
||||
{
|
||||
return tr_sys_path_exists(path.c_str(), error);
|
||||
}
|
||||
|
@ -215,10 +215,10 @@ bool tr_sys_path_is_relative(std::string_view path);
|
|||
* if you need to distinguish the two, check if `error` is `nullptr`
|
||||
* afterwards.
|
||||
*/
|
||||
bool tr_sys_path_is_same(char const* path1, char const* path2, struct tr_error** error = nullptr);
|
||||
bool tr_sys_path_is_same(char const* path1, char const* path2, tr_error* error = nullptr);
|
||||
|
||||
template<typename T, typename U, typename = decltype(&T::c_str), typename = decltype(&U::c_str)>
|
||||
bool tr_sys_path_is_same(T const& path1, U const& path2, struct tr_error** error = nullptr)
|
||||
bool tr_sys_path_is_same(T const& path1, U const& path2, tr_error* error = nullptr)
|
||||
{
|
||||
return tr_sys_path_is_same(path1.c_str(), path2.c_str(), error);
|
||||
}
|
||||
|
@ -233,7 +233,7 @@ bool tr_sys_path_is_same(T const& path1, U const& path2, struct tr_error** error
|
|||
* @return Full path with symbolic links, `.` and `..` resolved on success,
|
||||
* or an empty string otherwise (with `error` set accordingly).
|
||||
*/
|
||||
std::string tr_sys_path_resolve(std::string_view path, struct tr_error** error = nullptr);
|
||||
std::string tr_sys_path_resolve(std::string_view path, tr_error* error = nullptr);
|
||||
|
||||
/**
|
||||
* @brief Portability wrapper for `basename()`.
|
||||
|
@ -245,7 +245,7 @@ std::string tr_sys_path_resolve(std::string_view path, struct tr_error** error =
|
|||
* @return base name (last path component; parent path removed) on success,
|
||||
* or empty string otherwise (with `error` set accordingly).
|
||||
*/
|
||||
std::string_view tr_sys_path_basename(std::string_view path, struct tr_error** error = nullptr);
|
||||
std::string_view tr_sys_path_basename(std::string_view path, tr_error* error = nullptr);
|
||||
|
||||
/**
|
||||
* @brief Portability wrapper for `dirname()`.
|
||||
|
@ -269,10 +269,10 @@ std::string_view tr_sys_path_dirname(std::string_view path);
|
|||
* Rename will generally only succeed if both source and destination are
|
||||
* on the same partition.
|
||||
*/
|
||||
bool tr_sys_path_rename(char const* src_path, char const* dst_path, struct tr_error** error = nullptr);
|
||||
bool tr_sys_path_rename(char const* src_path, char const* dst_path, tr_error* error = nullptr);
|
||||
|
||||
template<typename T, typename U, typename = decltype(&T::c_str), typename = decltype(&U::c_str)>
|
||||
bool tr_sys_path_rename(T const& src_path, U const& dst_path, struct tr_error** error = nullptr)
|
||||
bool tr_sys_path_rename(T const& src_path, U const& dst_path, tr_error* error = nullptr)
|
||||
{
|
||||
return tr_sys_path_rename(src_path.c_str(), dst_path.c_str(), error);
|
||||
}
|
||||
|
@ -288,10 +288,10 @@ bool tr_sys_path_rename(T const& src_path, U const& dst_path, struct tr_error**
|
|||
* Directory removal will only succeed if it is empty (contains no other
|
||||
* files and directories).
|
||||
*/
|
||||
bool tr_sys_path_remove(char const* path, struct tr_error** error = nullptr);
|
||||
bool tr_sys_path_remove(char const* path, tr_error* error = nullptr);
|
||||
|
||||
template<typename T, typename = decltype(&T::c_str)>
|
||||
bool tr_sys_path_remove(T const& path, struct tr_error** error = nullptr)
|
||||
bool tr_sys_path_remove(T const& path, tr_error* error = nullptr)
|
||||
{
|
||||
return tr_sys_path_remove(path.c_str(), error);
|
||||
}
|
||||
|
@ -318,7 +318,7 @@ char* tr_sys_path_native_separators(char* path);
|
|||
* `error` set accordingly). DO NOT pass this descriptor to
|
||||
* @ref tr_sys_file_close (unless you know what you are doing).
|
||||
*/
|
||||
tr_sys_file_t tr_sys_file_get_std(tr_std_sys_file_t std_file, struct tr_error** error = nullptr);
|
||||
tr_sys_file_t tr_sys_file_get_std(tr_std_sys_file_t std_file, tr_error* error = nullptr);
|
||||
|
||||
/**
|
||||
* @brief Portability wrapper for `open()`.
|
||||
|
@ -333,7 +333,7 @@ tr_sys_file_t tr_sys_file_get_std(tr_std_sys_file_t std_file, struct tr_error**
|
|||
* @return Opened file descriptor on success, `TR_BAD_SYS_FILE` otherwise (with
|
||||
* `error` set accordingly).
|
||||
*/
|
||||
tr_sys_file_t tr_sys_file_open(char const* path, int flags, int permissions, struct tr_error** error = nullptr);
|
||||
tr_sys_file_t tr_sys_file_open(char const* path, int flags, int permissions, tr_error* error = nullptr);
|
||||
|
||||
/**
|
||||
* @brief Portability wrapper for `mkstemp()`.
|
||||
|
@ -349,7 +349,7 @@ tr_sys_file_t tr_sys_file_open(char const* path, int flags, int permissions, str
|
|||
* @return Opened file descriptor on success, `TR_BAD_SYS_FILE` otherwise (with
|
||||
* `error` set accordingly).
|
||||
*/
|
||||
tr_sys_file_t tr_sys_file_open_temp(char* path_template, struct tr_error** error = nullptr);
|
||||
tr_sys_file_t tr_sys_file_open_temp(char* path_template, tr_error* error = nullptr);
|
||||
|
||||
/**
|
||||
* @brief Portability wrapper for `close()`.
|
||||
|
@ -360,7 +360,7 @@ tr_sys_file_t tr_sys_file_open_temp(char* path_template, struct tr_error** error
|
|||
*
|
||||
* @return `True` on success, `false` otherwise (with `error` set accordingly).
|
||||
*/
|
||||
bool tr_sys_file_close(tr_sys_file_t handle, struct tr_error** error = nullptr);
|
||||
bool tr_sys_file_close(tr_sys_file_t handle, tr_error* error = nullptr);
|
||||
|
||||
/**
|
||||
* @brief Portability wrapper for `read()`.
|
||||
|
@ -375,12 +375,7 @@ bool tr_sys_file_close(tr_sys_file_t handle, struct tr_error** error = nullptr);
|
|||
*
|
||||
* @return `True` on success, `false` otherwise (with `error` set accordingly).
|
||||
*/
|
||||
bool tr_sys_file_read(
|
||||
tr_sys_file_t handle,
|
||||
void* buffer,
|
||||
uint64_t size,
|
||||
uint64_t* bytes_read,
|
||||
struct tr_error** error = nullptr);
|
||||
bool tr_sys_file_read(tr_sys_file_t handle, void* buffer, uint64_t size, uint64_t* bytes_read, tr_error* error = nullptr);
|
||||
|
||||
/**
|
||||
* @brief Like `pread()`, except that the position is undefined afterwards.
|
||||
|
@ -403,7 +398,7 @@ bool tr_sys_file_read_at(
|
|||
uint64_t size,
|
||||
uint64_t offset,
|
||||
uint64_t* bytes_read,
|
||||
struct tr_error** error = nullptr);
|
||||
tr_error* error = nullptr);
|
||||
|
||||
/**
|
||||
* @brief Portability wrapper for `write()`.
|
||||
|
@ -423,7 +418,7 @@ bool tr_sys_file_write(
|
|||
void const* buffer,
|
||||
uint64_t size,
|
||||
uint64_t* bytes_written,
|
||||
struct tr_error** error = nullptr);
|
||||
tr_error* error = nullptr);
|
||||
|
||||
/**
|
||||
* @brief Like `pwrite()`, except that the position is undefined afterwards.
|
||||
|
@ -446,7 +441,7 @@ bool tr_sys_file_write_at(
|
|||
uint64_t size,
|
||||
uint64_t offset,
|
||||
uint64_t* bytes_written,
|
||||
struct tr_error** error = nullptr);
|
||||
tr_error* error = nullptr);
|
||||
|
||||
/**
|
||||
* @brief Portability wrapper for `fsync()`.
|
||||
|
@ -457,10 +452,10 @@ bool tr_sys_file_write_at(
|
|||
*
|
||||
* @return `True` on success, `false` otherwise (with `error` set accordingly).
|
||||
*/
|
||||
bool tr_sys_file_flush(tr_sys_file_t handle, struct tr_error** error = nullptr);
|
||||
bool tr_sys_file_flush(tr_sys_file_t handle, tr_error* error = nullptr);
|
||||
|
||||
/* @brief Check whether `handle` may be flushed via `tr_sys_file_flush()`. */
|
||||
bool tr_sys_file_flush_possible(tr_sys_file_t handle, struct tr_error** error = nullptr);
|
||||
bool tr_sys_file_flush_possible(tr_sys_file_t handle, tr_error* error = nullptr);
|
||||
|
||||
/**
|
||||
* @brief Portability wrapper for `ftruncate()`.
|
||||
|
@ -472,7 +467,7 @@ bool tr_sys_file_flush_possible(tr_sys_file_t handle, struct tr_error** error =
|
|||
*
|
||||
* @return `True` on success, `false` otherwise (with `error` set accordingly).
|
||||
*/
|
||||
bool tr_sys_file_truncate(tr_sys_file_t handle, uint64_t size, struct tr_error** error = nullptr);
|
||||
bool tr_sys_file_truncate(tr_sys_file_t handle, uint64_t size, tr_error* error = nullptr);
|
||||
|
||||
/**
|
||||
* @brief Tell system to prefetch or discard some part of file which is [not] to be read soon.
|
||||
|
@ -490,7 +485,7 @@ bool tr_sys_file_advise(
|
|||
uint64_t offset,
|
||||
uint64_t size,
|
||||
tr_sys_file_advice_t advice,
|
||||
struct tr_error** error = nullptr);
|
||||
tr_error* error = nullptr);
|
||||
|
||||
/**
|
||||
* @brief Preallocate file to specified size in full or sparse mode.
|
||||
|
@ -503,7 +498,7 @@ bool tr_sys_file_advise(
|
|||
*
|
||||
* @return `True` on success, `false` otherwise (with `error` set accordingly).
|
||||
*/
|
||||
bool tr_sys_file_preallocate(tr_sys_file_t handle, uint64_t size, int flags, struct tr_error** error = nullptr);
|
||||
bool tr_sys_file_preallocate(tr_sys_file_t handle, uint64_t size, int flags, tr_error* error = nullptr);
|
||||
|
||||
/**
|
||||
* @brief Portability wrapper for `flock()`.
|
||||
|
@ -518,7 +513,7 @@ bool tr_sys_file_preallocate(tr_sys_file_t handle, uint64_t size, int flags, str
|
|||
*
|
||||
* @return `True` on success, `false` otherwise (with `error` set accordingly).
|
||||
*/
|
||||
bool tr_sys_file_lock(tr_sys_file_t handle, int operation, struct tr_error** error = nullptr);
|
||||
bool tr_sys_file_lock(tr_sys_file_t handle, int operation, tr_error* error = nullptr);
|
||||
|
||||
/* File-related wrappers (utility) */
|
||||
|
||||
|
@ -538,7 +533,7 @@ bool tr_sys_file_lock(tr_sys_file_t handle, int operation, struct tr_error** err
|
|||
*
|
||||
* @return `True` on success, `false` otherwise (with `error` set accordingly).
|
||||
*/
|
||||
bool tr_sys_file_write_line(tr_sys_file_t handle, std::string_view buffer, struct tr_error** error = nullptr);
|
||||
bool tr_sys_file_write_line(tr_sys_file_t handle, std::string_view buffer, tr_error* error = nullptr);
|
||||
|
||||
/* Directory-related wrappers */
|
||||
|
||||
|
@ -551,7 +546,7 @@ bool tr_sys_file_write_line(tr_sys_file_t handle, std::string_view buffer, struc
|
|||
* @return current directory on success, or an empty string otherwise
|
||||
* (with `error` set accordingly).
|
||||
*/
|
||||
std::string tr_sys_dir_get_current(struct tr_error** error = nullptr);
|
||||
std::string tr_sys_dir_get_current(tr_error* error = nullptr);
|
||||
|
||||
/**
|
||||
* @brief Like `mkdir()`, but makes parent directories if needed.
|
||||
|
@ -565,10 +560,10 @@ std::string tr_sys_dir_get_current(struct tr_error** error = nullptr);
|
|||
*
|
||||
* @return `True` on success, `false` otherwise (with `error` set accordingly).
|
||||
*/
|
||||
bool tr_sys_dir_create(char const* path, int flags, int permissions, struct tr_error** error = nullptr);
|
||||
bool tr_sys_dir_create(char const* path, int flags, int permissions, tr_error* error = nullptr);
|
||||
|
||||
template<typename T, typename = decltype(&T::c_str)>
|
||||
bool tr_sys_dir_create(T const& path, int flags, int permissions, struct tr_error** error = nullptr)
|
||||
bool tr_sys_dir_create(T const& path, int flags, int permissions, tr_error* error = nullptr)
|
||||
{
|
||||
return tr_sys_dir_create(path.c_str(), flags, permissions, error);
|
||||
}
|
||||
|
@ -586,7 +581,7 @@ bool tr_sys_dir_create(T const& path, int flags, int permissions, struct tr_erro
|
|||
*
|
||||
* @return `True` on success, `false` otherwise (with `error` set accordingly).
|
||||
*/
|
||||
bool tr_sys_dir_create_temp(char* path_template, struct tr_error** error = nullptr);
|
||||
bool tr_sys_dir_create_temp(char* path_template, tr_error* error = nullptr);
|
||||
|
||||
/**
|
||||
* @brief Portability wrapper for `opendir()`.
|
||||
|
@ -598,7 +593,7 @@ bool tr_sys_dir_create_temp(char* path_template, struct tr_error** error = nullp
|
|||
* @return Opened directory descriptor on success, `TR_BAD_SYS_DIR` otherwise
|
||||
* (with `error` set accordingly).
|
||||
*/
|
||||
tr_sys_dir_t tr_sys_dir_open(std::string_view path, struct tr_error** error = nullptr);
|
||||
tr_sys_dir_t tr_sys_dir_open(std::string_view path, tr_error* error = nullptr);
|
||||
|
||||
/**
|
||||
* @brief Portability wrapper for `readdir()`.
|
||||
|
@ -613,7 +608,7 @@ tr_sys_dir_t tr_sys_dir_open(std::string_view path, struct tr_error** error = nu
|
|||
* If you need to distinguish the two, check if `error` is `nullptr`
|
||||
* afterwards.
|
||||
*/
|
||||
char const* tr_sys_dir_read_name(tr_sys_dir_t handle, struct tr_error** error = nullptr);
|
||||
char const* tr_sys_dir_read_name(tr_sys_dir_t handle, tr_error* error = nullptr);
|
||||
|
||||
/**
|
||||
* @brief Portability wrapper for `closedir()`.
|
||||
|
@ -624,7 +619,7 @@ char const* tr_sys_dir_read_name(tr_sys_dir_t handle, struct tr_error** error =
|
|||
*
|
||||
* @return `True` on success, `false` otherwise (with `error` set accordingly).
|
||||
*/
|
||||
bool tr_sys_dir_close(tr_sys_dir_t handle, struct tr_error** error = nullptr);
|
||||
bool tr_sys_dir_close(tr_sys_dir_t handle, tr_error* error = nullptr);
|
||||
|
||||
[[nodiscard]] constexpr bool tr_basename_is_not_dotfile(std::string_view sv)
|
||||
{
|
||||
|
@ -634,7 +629,7 @@ bool tr_sys_dir_close(tr_sys_dir_t handle, struct tr_error** error = nullptr);
|
|||
[[nodiscard]] std::vector<std::string> tr_sys_dir_get_files(
|
||||
std::string_view folder,
|
||||
std::function<bool(std::string_view name)> const& test = tr_basename_is_not_dotfile,
|
||||
tr_error** error = nullptr);
|
||||
tr_error* error = nullptr);
|
||||
|
||||
/** @} */
|
||||
/** @} */
|
||||
|
|
|
@ -632,7 +632,7 @@ void tr_handshake::on_error(tr_peerIo* io, tr_error const& error, void* vhandsha
|
|||
auto const info = handshake->mediator_->torrent(info_hash);
|
||||
|
||||
/* Don't mark a peer as non-µTP unless it's really a connect failure. */
|
||||
if ((error.code == ETIMEDOUT || error.code == ECONNREFUSED) && info)
|
||||
if ((error.code() == ETIMEDOUT || error.code() == ECONNREFUSED) && info)
|
||||
{
|
||||
handshake->mediator_->set_utp_failed(info_hash, io->socket_address());
|
||||
}
|
||||
|
@ -657,7 +657,7 @@ void tr_handshake::on_error(tr_peerIo* io, tr_error const& error, void* vhandsha
|
|||
return;
|
||||
}
|
||||
|
||||
tr_logAddTraceHand(handshake, fmt::format("handshake socket err: {:s} ({:d})", error.message, error.code));
|
||||
tr_logAddTraceHand(handshake, fmt::format("handshake socket err: {:s} ({:d})", error.message(), error.code()));
|
||||
handshake->done(false);
|
||||
}
|
||||
|
||||
|
|
|
@ -32,7 +32,7 @@ using namespace std::literals;
|
|||
namespace
|
||||
{
|
||||
|
||||
bool readEntireBuf(tr_sys_file_t fd, uint64_t file_offset, uint8_t* buf, uint64_t buflen, tr_error** error)
|
||||
bool readEntireBuf(tr_sys_file_t fd, uint64_t file_offset, uint8_t* buf, uint64_t buflen, tr_error* error)
|
||||
{
|
||||
while (buflen > 0)
|
||||
{
|
||||
|
@ -51,7 +51,7 @@ bool readEntireBuf(tr_sys_file_t fd, uint64_t file_offset, uint8_t* buf, uint64_
|
|||
return true;
|
||||
}
|
||||
|
||||
bool writeEntireBuf(tr_sys_file_t fd, uint64_t file_offset, uint8_t const* buf, uint64_t buflen, tr_error** error)
|
||||
bool writeEntireBuf(tr_sys_file_t fd, uint64_t file_offset, uint8_t const* buf, uint64_t buflen, tr_error* error)
|
||||
{
|
||||
while (buflen > 0)
|
||||
{
|
||||
|
@ -106,7 +106,7 @@ void readOrWriteBytes(
|
|||
uint64_t file_offset,
|
||||
uint8_t* buf,
|
||||
size_t buflen,
|
||||
tr_error** error)
|
||||
tr_error* error)
|
||||
{
|
||||
TR_ASSERT(file_index < tor->file_count());
|
||||
|
||||
|
@ -120,6 +120,12 @@ void readOrWriteBytes(
|
|||
return;
|
||||
}
|
||||
|
||||
auto local_error = tr_error{};
|
||||
if (error == nullptr)
|
||||
{
|
||||
error = &local_error;
|
||||
}
|
||||
|
||||
// --- Find the fd
|
||||
|
||||
auto fd = session->openFiles().get(tor->id(), file_index, do_write);
|
||||
|
@ -127,12 +133,13 @@ void readOrWriteBytes(
|
|||
if (!fd && !getFilename(filename, tor, file_index, io_mode))
|
||||
{
|
||||
auto const err = ENOENT;
|
||||
auto const msg = fmt::format(
|
||||
_("Couldn't get '{path}': {error} ({error_code})"),
|
||||
fmt::arg("path", tor->file_subpath(file_index)),
|
||||
fmt::arg("error", tr_strerror(err)),
|
||||
fmt::arg("error_code", err));
|
||||
tr_error_set(error, err, msg);
|
||||
error->set(
|
||||
err,
|
||||
fmt::format(
|
||||
_("Couldn't get '{path}': {error} ({error_code})"),
|
||||
fmt::arg("path", tor->file_subpath(file_index)),
|
||||
fmt::arg("error", tr_strerror(err)),
|
||||
fmt::arg("error_code", err)));
|
||||
return;
|
||||
}
|
||||
|
||||
|
@ -151,45 +158,44 @@ void readOrWriteBytes(
|
|||
|
||||
if (!fd) // couldn't create/open it either
|
||||
{
|
||||
auto const err = errno;
|
||||
auto msg = fmt::format(
|
||||
_("Couldn't get '{path}': {error} ({error_code})"),
|
||||
fmt::arg("path", filename),
|
||||
fmt::arg("error", tr_strerror(err)),
|
||||
fmt::arg("error_code", err));
|
||||
tr_error_set(error, err, msg);
|
||||
tr_logAddErrorTor(tor, std::move(msg));
|
||||
auto const errnum = errno;
|
||||
error->set(
|
||||
errnum,
|
||||
fmt::format(
|
||||
_("Couldn't get '{path}': {error} ({error_code})"),
|
||||
fmt::arg("path", filename),
|
||||
fmt::arg("error", tr_strerror(errnum)),
|
||||
fmt::arg("error_code", errnum)));
|
||||
tr_logAddErrorTor(tor, std::string{ error->message() });
|
||||
return;
|
||||
}
|
||||
|
||||
switch (io_mode)
|
||||
{
|
||||
case IoMode::Read:
|
||||
if (tr_error* my_error = nullptr; !readEntireBuf(*fd, file_offset, buf, buflen, &my_error) && my_error != nullptr)
|
||||
if (!readEntireBuf(*fd, file_offset, buf, buflen, error) && *error)
|
||||
{
|
||||
tr_logAddErrorTor(
|
||||
tor,
|
||||
fmt::format(
|
||||
_("Couldn't read '{path}': {error} ({error_code})"),
|
||||
fmt::arg("path", tor->file_subpath(file_index)),
|
||||
fmt::arg("error", my_error->message),
|
||||
fmt::arg("error_code", my_error->code)));
|
||||
tr_error_propagate(error, &my_error);
|
||||
fmt::arg("error", error->message()),
|
||||
fmt::arg("error_code", error->code())));
|
||||
return;
|
||||
}
|
||||
break;
|
||||
|
||||
case IoMode::Write:
|
||||
if (tr_error* my_error = nullptr; !writeEntireBuf(*fd, file_offset, buf, buflen, &my_error) && my_error != nullptr)
|
||||
if (!writeEntireBuf(*fd, file_offset, buf, buflen, error) && *error)
|
||||
{
|
||||
tr_logAddErrorTor(
|
||||
tor,
|
||||
fmt::format(
|
||||
_("Couldn't save '{path}': {error} ({error_code})"),
|
||||
fmt::arg("path", tor->file_subpath(file_index)),
|
||||
fmt::arg("error", my_error->message),
|
||||
fmt::arg("error_code", my_error->code)));
|
||||
tr_error_propagate(error, &my_error);
|
||||
fmt::arg("error", error->message()),
|
||||
fmt::arg("error_code", error->code())));
|
||||
return;
|
||||
}
|
||||
break;
|
||||
|
@ -214,20 +220,17 @@ int readOrWritePiece(tr_torrent* tor, IoMode io_mode, tr_block_info::Location lo
|
|||
{
|
||||
uint64_t const bytes_this_pass = std::min(uint64_t{ buflen }, uint64_t{ tor->file_size(file_index) - file_offset });
|
||||
|
||||
tr_error* error = nullptr;
|
||||
auto error = tr_error{};
|
||||
readOrWriteBytes(tor->session, tor, io_mode, file_index, file_offset, buf, bytes_this_pass, &error);
|
||||
|
||||
if (error != nullptr) // if IO failed, set torrent's error if not already set
|
||||
if (error) // if IO failed, set torrent's error if not already set
|
||||
{
|
||||
if (io_mode == IoMode::Write && tor->error().error_type() != TR_STAT_LOCAL_ERROR)
|
||||
{
|
||||
tor->error().set_local_error(error->message);
|
||||
tor->error().set_local_error(error.message());
|
||||
tr_torrentStop(tor);
|
||||
}
|
||||
|
||||
auto const error_code = error->code;
|
||||
tr_error_clear(&error);
|
||||
return error_code;
|
||||
return error.code();
|
||||
}
|
||||
|
||||
if (buf != nullptr)
|
||||
|
|
|
@ -208,7 +208,7 @@ void tr_magnet_metainfo::add_webseed(std::string_view webseed)
|
|||
urls.emplace_back(webseed);
|
||||
}
|
||||
|
||||
bool tr_magnet_metainfo::parseMagnet(std::string_view magnet_link, tr_error** error)
|
||||
bool tr_magnet_metainfo::parseMagnet(std::string_view magnet_link, tr_error* error)
|
||||
{
|
||||
magnet_link = tr_strv_strip(magnet_link);
|
||||
if (auto const hash = parseHash(magnet_link); hash)
|
||||
|
@ -219,7 +219,11 @@ bool tr_magnet_metainfo::parseMagnet(std::string_view magnet_link, tr_error** er
|
|||
auto const parsed = tr_urlParse(magnet_link);
|
||||
if (!parsed || parsed->scheme != "magnet"sv)
|
||||
{
|
||||
tr_error_set(error, TR_ERROR_EINVAL, "Error parsing URL"sv);
|
||||
if (error != nullptr)
|
||||
{
|
||||
error->set(TR_ERROR_EINVAL, "Error parsing URL"sv);
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
|
|
|
@ -22,7 +22,7 @@ class tr_magnet_metainfo
|
|||
friend struct MetainfoHandler;
|
||||
|
||||
public:
|
||||
bool parseMagnet(std::string_view magnet_link, tr_error** error = nullptr);
|
||||
bool parseMagnet(std::string_view magnet_link, tr_error* error = nullptr);
|
||||
|
||||
[[nodiscard]] std::string magnet() const;
|
||||
|
||||
|
|
|
@ -73,16 +73,15 @@ void walkTree(std::string_view const top, std::string_view const subpath, std::s
|
|||
|
||||
auto path = tr_pathbuf{ top, '/', subpath };
|
||||
tr_sys_path_native_separators(std::data(path));
|
||||
tr_error* error = nullptr;
|
||||
auto error = tr_error{};
|
||||
auto const info = tr_sys_path_get_info(path, 0, &error);
|
||||
if (error != nullptr)
|
||||
if (error)
|
||||
{
|
||||
tr_logAddWarn(fmt::format(
|
||||
_("Skipping '{path}': {error} ({error_code})"),
|
||||
fmt::arg("path", path),
|
||||
fmt::arg("error", error->message),
|
||||
fmt::arg("error_code", error->code)));
|
||||
tr_error_free(error);
|
||||
fmt::arg("error", error.message()),
|
||||
fmt::arg("error_code", error.code())));
|
||||
}
|
||||
if (!info)
|
||||
{
|
||||
|
@ -150,14 +149,18 @@ bool tr_metainfo_builder::set_piece_size(uint32_t piece_size) noexcept
|
|||
return true;
|
||||
}
|
||||
|
||||
bool tr_metainfo_builder::blocking_make_checksums(tr_error** error)
|
||||
bool tr_metainfo_builder::blocking_make_checksums(tr_error* error)
|
||||
{
|
||||
checksum_piece_ = 0;
|
||||
cancel_ = false;
|
||||
|
||||
if (total_size() == 0U)
|
||||
{
|
||||
tr_error_set_from_errno(error, ENOENT);
|
||||
if (error != nullptr)
|
||||
{
|
||||
error->set_from_errno(ENOENT);
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
|
@ -246,7 +249,11 @@ bool tr_metainfo_builder::blocking_make_checksums(tr_error** error)
|
|||
|
||||
if (cancel_)
|
||||
{
|
||||
tr_error_set_from_errno(error, ECANCELED);
|
||||
if (error != nullptr)
|
||||
{
|
||||
error->set_from_errno(ECANCELED);
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
|
@ -254,7 +261,7 @@ bool tr_metainfo_builder::blocking_make_checksums(tr_error** error)
|
|||
return true;
|
||||
}
|
||||
|
||||
std::string tr_metainfo_builder::benc(tr_error** error) const
|
||||
std::string tr_metainfo_builder::benc(tr_error* error) const
|
||||
{
|
||||
TR_ASSERT_MSG(!std::empty(piece_hashes_), "did you forget to call makeChecksums() first?");
|
||||
|
||||
|
@ -265,7 +272,11 @@ std::string tr_metainfo_builder::benc(tr_error** error) const
|
|||
|
||||
if (total_size() == 0)
|
||||
{
|
||||
tr_error_set_from_errno(error, ENOENT);
|
||||
if (error != nullptr)
|
||||
{
|
||||
error->set_from_errno(ENOENT);
|
||||
}
|
||||
|
||||
return {};
|
||||
}
|
||||
|
||||
|
|
|
@ -17,13 +17,12 @@
|
|||
|
||||
#include "libtransmission/announce-list.h"
|
||||
#include "libtransmission/block-info.h"
|
||||
#include "libtransmission/error.h"
|
||||
#include "libtransmission/file.h"
|
||||
#include "libtransmission/torrent-files.h"
|
||||
#include "libtransmission/tr-macros.h" // TR_CONSTEXPR20
|
||||
#include "libtransmission/utils.h" // for tr_file_save()
|
||||
|
||||
struct tr_error;
|
||||
|
||||
class tr_metainfo_builder
|
||||
{
|
||||
public:
|
||||
|
@ -38,14 +37,14 @@ public:
|
|||
// - This must be done before calling `benc()` or `save()`.
|
||||
// - Runs in a worker thread because it can be time-consuming.
|
||||
// - Can be cancelled with `cancelChecksums()` and polled with `checksumStatus()`
|
||||
// - Resolves with a `tr_error*` which is set on failure or nullptr on success.
|
||||
std::future<tr_error*> make_checksums()
|
||||
// - Resolves with a `tr_error` which is set on failure or empty on success.
|
||||
std::future<tr_error> make_checksums()
|
||||
{
|
||||
return std::async(
|
||||
std::launch::async,
|
||||
[this]()
|
||||
{
|
||||
tr_error* error = nullptr;
|
||||
auto error = tr_error{};
|
||||
blocking_make_checksums(&error);
|
||||
return error;
|
||||
});
|
||||
|
@ -65,10 +64,10 @@ public:
|
|||
}
|
||||
|
||||
// generate the metainfo
|
||||
[[nodiscard]] std::string benc(tr_error** error = nullptr) const;
|
||||
[[nodiscard]] std::string benc(tr_error* error = nullptr) const;
|
||||
|
||||
// generate the metainfo and save it to a torrent file
|
||||
bool save(std::string_view filename, tr_error** error = nullptr) const
|
||||
bool save(std::string_view filename, tr_error* error = nullptr) const
|
||||
{
|
||||
return tr_file_save(filename, benc(error), error);
|
||||
}
|
||||
|
@ -193,7 +192,7 @@ public:
|
|||
}
|
||||
|
||||
private:
|
||||
bool blocking_make_checksums(tr_error** error = nullptr);
|
||||
bool blocking_make_checksums(tr_error* error = nullptr);
|
||||
|
||||
std::string top_;
|
||||
tr_torrent_files files_;
|
||||
|
|
|
@ -30,70 +30,75 @@ namespace
|
|||
return fd != TR_BAD_SYS_FILE;
|
||||
}
|
||||
|
||||
bool preallocate_file_sparse(tr_sys_file_t fd, uint64_t length, tr_error** error)
|
||||
bool preallocate_file_sparse(tr_sys_file_t fd, uint64_t length, tr_error* error)
|
||||
{
|
||||
tr_error* my_error = nullptr;
|
||||
|
||||
if (length == 0)
|
||||
{
|
||||
return true;
|
||||
}
|
||||
|
||||
if (tr_sys_file_preallocate(fd, length, TR_SYS_FILE_PREALLOC_SPARSE, &my_error))
|
||||
auto local_error = tr_error{};
|
||||
|
||||
if (tr_sys_file_preallocate(fd, length, TR_SYS_FILE_PREALLOC_SPARSE, &local_error))
|
||||
{
|
||||
return true;
|
||||
}
|
||||
|
||||
tr_logAddDebug(fmt::format("Fast preallocation failed: {} ({})", my_error->message, my_error->code));
|
||||
tr_logAddDebug(fmt::format("Fast preallocation failed: {} ({})", local_error.message(), local_error.code()));
|
||||
|
||||
if (!TR_ERROR_IS_ENOSPC(my_error->code))
|
||||
if (!TR_ERROR_IS_ENOSPC(local_error.code()))
|
||||
{
|
||||
char const zero = '\0';
|
||||
|
||||
tr_error_clear(&my_error);
|
||||
local_error = {};
|
||||
|
||||
/* fallback: the old-style seek-and-write */
|
||||
if (tr_sys_file_write_at(fd, &zero, 1, length - 1, nullptr, &my_error) && tr_sys_file_truncate(fd, length, &my_error))
|
||||
if (tr_sys_file_write_at(fd, &zero, 1, length - 1, nullptr, &local_error) &&
|
||||
tr_sys_file_truncate(fd, length, &local_error))
|
||||
{
|
||||
return true;
|
||||
}
|
||||
|
||||
tr_logAddDebug(fmt::format("Fast prellocation fallback failed: {} ({})", my_error->message, my_error->code));
|
||||
tr_logAddDebug(fmt::format("Fast prellocation fallback failed: {} ({})", local_error.message(), local_error.code()));
|
||||
}
|
||||
|
||||
if (error != nullptr)
|
||||
{
|
||||
*error = std::move(local_error);
|
||||
}
|
||||
|
||||
tr_error_propagate(error, &my_error);
|
||||
return false;
|
||||
}
|
||||
|
||||
bool preallocate_file_full(tr_sys_file_t fd, uint64_t length, tr_error** error)
|
||||
bool preallocate_file_full(tr_sys_file_t fd, uint64_t length, tr_error* error)
|
||||
{
|
||||
tr_error* my_error = nullptr;
|
||||
|
||||
if (length == 0)
|
||||
{
|
||||
return true;
|
||||
}
|
||||
|
||||
if (tr_sys_file_preallocate(fd, length, 0, &my_error))
|
||||
auto local_error = tr_error{};
|
||||
|
||||
if (tr_sys_file_preallocate(fd, length, 0, &local_error))
|
||||
{
|
||||
return true;
|
||||
}
|
||||
|
||||
tr_logAddDebug(fmt::format("Full preallocation failed: {} ({})", my_error->message, my_error->code));
|
||||
tr_logAddDebug(fmt::format("Full preallocation failed: {} ({})", local_error.message(), local_error.code()));
|
||||
|
||||
if (!TR_ERROR_IS_ENOSPC(my_error->code))
|
||||
if (!TR_ERROR_IS_ENOSPC(local_error.code()))
|
||||
{
|
||||
auto buf = std::array<uint8_t, 4096>{};
|
||||
bool success = true;
|
||||
|
||||
tr_error_clear(&my_error);
|
||||
local_error = {};
|
||||
|
||||
/* fallback: the old-fashioned way */
|
||||
while (success && length > 0)
|
||||
{
|
||||
uint64_t const this_pass = std::min(length, uint64_t{ std::size(buf) });
|
||||
uint64_t bytes_written = 0;
|
||||
success = tr_sys_file_write(fd, std::data(buf), this_pass, &bytes_written, &my_error);
|
||||
success = tr_sys_file_write(fd, std::data(buf), this_pass, &bytes_written, &local_error);
|
||||
length -= bytes_written;
|
||||
}
|
||||
|
||||
|
@ -102,10 +107,14 @@ bool preallocate_file_full(tr_sys_file_t fd, uint64_t length, tr_error** error)
|
|||
return true;
|
||||
}
|
||||
|
||||
tr_logAddDebug(fmt::format("Full preallocation fallback failed: {} ({})", my_error->message, my_error->code));
|
||||
tr_logAddDebug(fmt::format("Full preallocation fallback failed: {} ({})", local_error.message(), local_error.code()));
|
||||
}
|
||||
|
||||
if (error != nullptr)
|
||||
{
|
||||
*error = std::move(local_error);
|
||||
}
|
||||
|
||||
tr_error_propagate(error, &my_error);
|
||||
return false;
|
||||
}
|
||||
|
||||
|
@ -150,7 +159,7 @@ std::optional<tr_sys_file_t> tr_open_files::get(
|
|||
|
||||
// create subfolders, if any
|
||||
auto const filename = tr_pathbuf{ filename_in };
|
||||
tr_error* error = nullptr;
|
||||
auto error = tr_error{};
|
||||
if (writable)
|
||||
{
|
||||
auto dir = tr_pathbuf{ filename.sv() };
|
||||
|
@ -160,9 +169,8 @@ std::optional<tr_sys_file_t> tr_open_files::get(
|
|||
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_error_free(error);
|
||||
fmt::arg("error", error.message()),
|
||||
fmt::arg("error_code", error.code())));
|
||||
return {};
|
||||
}
|
||||
}
|
||||
|
@ -183,9 +191,8 @@ std::optional<tr_sys_file_t> tr_open_files::get(
|
|||
tr_logAddError(fmt::format(
|
||||
_("Couldn't open '{path}': {error} ({error_code})"),
|
||||
fmt::arg("path", filename),
|
||||
fmt::arg("error", error->message),
|
||||
fmt::arg("error_code", error->code)));
|
||||
tr_error_free(error);
|
||||
fmt::arg("error", error.message()),
|
||||
fmt::arg("error_code", error.code())));
|
||||
return {};
|
||||
}
|
||||
|
||||
|
@ -212,10 +219,9 @@ std::optional<tr_sys_file_t> tr_open_files::get(
|
|||
tr_logAddError(fmt::format(
|
||||
_("Couldn't preallocate '{path}': {error} ({error_code})"),
|
||||
fmt::arg("path", filename),
|
||||
fmt::arg("error", error->message),
|
||||
fmt::arg("error_code", error->code)));
|
||||
fmt::arg("error", error.message()),
|
||||
fmt::arg("error_code", error.code())));
|
||||
tr_sys_file_close(fd);
|
||||
tr_error_free(error);
|
||||
return {};
|
||||
}
|
||||
|
||||
|
@ -232,10 +238,9 @@ std::optional<tr_sys_file_t> tr_open_files::get(
|
|||
tr_logAddWarn(fmt::format(
|
||||
_("Couldn't truncate '{path}': {error} ({error_code})"),
|
||||
fmt::arg("path", filename),
|
||||
fmt::arg("error", error->message),
|
||||
fmt::arg("error_code", error->code)));
|
||||
fmt::arg("error", error.message()),
|
||||
fmt::arg("error_code", error.code())));
|
||||
tr_sys_file_close(fd);
|
||||
tr_error_free(error);
|
||||
return {};
|
||||
}
|
||||
|
||||
|
|
|
@ -26,7 +26,7 @@
|
|||
|
||||
#include "libtransmission/bandwidth.h"
|
||||
#include "libtransmission/block-info.h" // tr_block_info
|
||||
#include "libtransmission/error.h" // tr_error_clear, tr_error_s...
|
||||
#include "libtransmission/error.h"
|
||||
#include "libtransmission/log.h"
|
||||
#include "libtransmission/net.h"
|
||||
#include "libtransmission/peer-io.h"
|
||||
|
@ -325,22 +325,20 @@ size_t tr_peerIo::try_write(size_t max)
|
|||
return {};
|
||||
}
|
||||
|
||||
tr_error* error = nullptr;
|
||||
auto error = tr_error{};
|
||||
auto const n_written = socket_.try_write(buf, max, &error);
|
||||
// enable further writes if there's more data to write
|
||||
set_enabled(Dir, !std::empty(buf) && (error == nullptr || canRetryFromError(error->code)));
|
||||
set_enabled(Dir, !std::empty(buf) && (!error || canRetryFromError(error.code())));
|
||||
|
||||
if (error != nullptr)
|
||||
if (error)
|
||||
{
|
||||
if (!canRetryFromError(error->code))
|
||||
if (!canRetryFromError(error.code()))
|
||||
{
|
||||
tr_logAddTraceIo(
|
||||
this,
|
||||
fmt::format("try_write err: wrote:{}, errno:{} ({})", n_written, error->code, error->message));
|
||||
call_error_callback(*error);
|
||||
fmt::format("try_write err: wrote:{}, errno:{} ({})", n_written, error.code(), error.message()));
|
||||
call_error_callback(error);
|
||||
}
|
||||
|
||||
tr_error_clear(&error);
|
||||
}
|
||||
else if (n_written > 0U)
|
||||
{
|
||||
|
@ -450,19 +448,17 @@ size_t tr_peerIo::try_read(size_t max)
|
|||
}
|
||||
|
||||
auto& buf = inbuf_;
|
||||
tr_error* error = nullptr;
|
||||
auto error = tr_error{};
|
||||
auto const n_read = socket_.try_read(buf, max, std::empty(buf), &error);
|
||||
set_enabled(Dir, error == nullptr || canRetryFromError(error->code));
|
||||
set_enabled(Dir, !error || canRetryFromError(error.code()));
|
||||
|
||||
if (error != nullptr)
|
||||
if (error)
|
||||
{
|
||||
if (!canRetryFromError(error->code))
|
||||
if (!canRetryFromError(error.code()))
|
||||
{
|
||||
tr_logAddTraceIo(this, fmt::format("try_read err: n_read:{} errno:{} ({})", n_read, error->code, error->message));
|
||||
call_error_callback(*error);
|
||||
tr_logAddTraceIo(this, fmt::format("try_read err: n_read:{} errno:{} ({})", n_read, error.code(), error.message()));
|
||||
call_error_callback(error);
|
||||
}
|
||||
|
||||
tr_error_clear(&error);
|
||||
}
|
||||
else if (!std::empty(buf))
|
||||
{
|
||||
|
@ -672,10 +668,9 @@ void tr_peerIo::on_utp_state_change(int state)
|
|||
}
|
||||
else if (state == UTP_STATE_EOF)
|
||||
{
|
||||
tr_error* error = nullptr;
|
||||
tr_error_set_from_errno(&error, ENOTCONN);
|
||||
call_error_callback(*error);
|
||||
tr_error_clear(&error);
|
||||
auto error = tr_error{};
|
||||
error.set_from_errno(ENOTCONN);
|
||||
call_error_callback(error);
|
||||
}
|
||||
else if (state == UTP_STATE_DESTROYING)
|
||||
{
|
||||
|
@ -696,23 +691,24 @@ void tr_peerIo::on_utp_error(int errcode)
|
|||
return;
|
||||
}
|
||||
|
||||
tr_error* error = nullptr;
|
||||
auto error = tr_error{};
|
||||
switch (errcode)
|
||||
{
|
||||
case UTP_ECONNREFUSED:
|
||||
tr_error_set_from_errno(&error, ECONNREFUSED);
|
||||
error.set_from_errno(ECONNREFUSED);
|
||||
break;
|
||||
case UTP_ECONNRESET:
|
||||
tr_error_set_from_errno(&error, ECONNRESET);
|
||||
error.set_from_errno(ECONNRESET);
|
||||
break;
|
||||
case UTP_ETIMEDOUT:
|
||||
tr_error_set_from_errno(&error, ETIMEDOUT);
|
||||
error.set_from_errno(ETIMEDOUT);
|
||||
break;
|
||||
default:
|
||||
tr_error_set(&error, errcode, utp_error_code_names[errcode]);
|
||||
error.set(errcode, utp_error_code_names[errcode]);
|
||||
break;
|
||||
}
|
||||
call_error_callback(*error);
|
||||
tr_error_clear(&error);
|
||||
|
||||
call_error_callback(error);
|
||||
}
|
||||
|
||||
#endif /* #ifdef WITH_UTP */
|
||||
|
|
|
@ -71,7 +71,7 @@ void tr_peer_socket::close()
|
|||
handle = {};
|
||||
}
|
||||
|
||||
size_t tr_peer_socket::try_write(OutBuf& buf, size_t max, tr_error** error) const
|
||||
size_t tr_peer_socket::try_write(OutBuf& buf, size_t max, tr_error* error) const
|
||||
{
|
||||
if (max == size_t{})
|
||||
{
|
||||
|
@ -98,9 +98,9 @@ size_t tr_peer_socket::try_write(OutBuf& buf, size_t max, tr_error** error) cons
|
|||
return static_cast<size_t>(n_written);
|
||||
}
|
||||
|
||||
if (n_written < 0 && error_code != 0)
|
||||
if (error != nullptr && n_written < 0 && error_code != 0)
|
||||
{
|
||||
tr_error_set_from_errno(error, error_code);
|
||||
error->set_from_errno(error_code);
|
||||
}
|
||||
}
|
||||
#endif
|
||||
|
@ -108,7 +108,7 @@ size_t tr_peer_socket::try_write(OutBuf& buf, size_t max, tr_error** error) cons
|
|||
return {};
|
||||
}
|
||||
|
||||
size_t tr_peer_socket::try_read(InBuf& buf, size_t max, [[maybe_unused]] bool buf_is_empty, tr_error** error) const
|
||||
size_t tr_peer_socket::try_read(InBuf& buf, size_t max, [[maybe_unused]] bool buf_is_empty, tr_error* error) const
|
||||
{
|
||||
if (max == size_t{})
|
||||
{
|
||||
|
|
|
@ -52,8 +52,8 @@ public:
|
|||
}
|
||||
void close();
|
||||
|
||||
size_t try_read(InBuf& buf, size_t max, bool buf_is_empty, tr_error** error) const;
|
||||
size_t try_write(OutBuf& buf, size_t max, tr_error** error) const;
|
||||
size_t try_read(InBuf& buf, size_t max, bool buf_is_empty, tr_error* error) const;
|
||||
size_t try_write(OutBuf& buf, size_t max, tr_error* error) const;
|
||||
|
||||
[[nodiscard]] constexpr auto const& socket_address() const noexcept
|
||||
{
|
||||
|
|
|
@ -641,7 +641,7 @@ tr_resume::fields_t loadFromFile(tr_torrent* tor, tr_resume::fields_t fields_to_
|
|||
auto otop = serde.parse_file(filename);
|
||||
if (!otop)
|
||||
{
|
||||
tr_logAddDebugTor(tor, fmt::format("Couldn't read '{}': {}", filename, serde.error_->message));
|
||||
tr_logAddDebugTor(tor, fmt::format("Couldn't read '{}': {}", filename, serde.error_.message()));
|
||||
return {};
|
||||
}
|
||||
auto& top = *otop;
|
||||
|
@ -919,7 +919,7 @@ void save(tr_torrent* tor)
|
|||
auto serde = tr_variant_serde::benc();
|
||||
if (!serde.to_file(top, tor->resume_file()))
|
||||
{
|
||||
tor->error().set_local_error(fmt::format("Unable to save resume file: {:s}", serde.error_->message));
|
||||
tor->error().set_local_error(fmt::format("Unable to save resume file: {:s}", serde.error_.message()));
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -278,10 +278,9 @@ void serve_file(struct evhttp_request* req, tr_rpc_server const* server, std::st
|
|||
|
||||
auto content = std::vector<char>{};
|
||||
|
||||
if (tr_error* error = nullptr; !tr_file_read(filename, content, &error))
|
||||
if (auto error = tr_error{}; !tr_file_read(filename, content, &error))
|
||||
{
|
||||
send_simple_response(req, HTTP_NOTFOUND, fmt::format("{} ({})", filename, error->message).c_str());
|
||||
tr_error_free(error);
|
||||
send_simple_response(req, HTTP_NOTFOUND, fmt::format("{} ({})", filename, error.message()).c_str());
|
||||
return;
|
||||
}
|
||||
|
||||
|
|
|
@ -1312,16 +1312,15 @@ void onBlocklistFetched(tr_web::FetchResponse const& web_response)
|
|||
// tr_blocklistSetContent needs a source file,
|
||||
// so save content into a tmpfile
|
||||
auto const filename = tr_pathbuf{ session->configDir(), "/blocklist.tmp"sv };
|
||||
if (tr_error* error = nullptr; !tr_file_save(filename, content, &error))
|
||||
if (auto error = tr_error{}; !tr_file_save(filename, content, &error))
|
||||
{
|
||||
tr_idle_function_done(
|
||||
data,
|
||||
fmt::format(
|
||||
_("Couldn't save '{path}': {error} ({error_code})"),
|
||||
fmt::arg("path", filename),
|
||||
fmt::arg("error", error->message),
|
||||
fmt::arg("error_code", error->code)));
|
||||
tr_error_clear(&error);
|
||||
fmt::arg("error", error.message()),
|
||||
fmt::arg("error_code", error.code())));
|
||||
return;
|
||||
}
|
||||
|
||||
|
@ -2262,10 +2261,9 @@ char const* freeSpace(tr_session* /*session*/, tr_variant* args_in, tr_variant*
|
|||
|
||||
/* get the free space */
|
||||
auto const old_errno = errno;
|
||||
tr_error* error = nullptr;
|
||||
auto error = tr_error{};
|
||||
auto const capacity = tr_sys_path_get_capacity(path, &error);
|
||||
char const* const err = error != nullptr ? tr_strerror(error->code) : nullptr;
|
||||
tr_error_clear(&error);
|
||||
char const* const err = error ? tr_strerror(error.code()) : nullptr;
|
||||
errno = old_errno;
|
||||
|
||||
/* response */
|
||||
|
|
|
@ -43,7 +43,7 @@ tr_sys_file_t create_lockfile(std::string_view session_id)
|
|||
auto lockfile_path = tr_pathbuf{};
|
||||
get_lockfile_path(session_id, lockfile_path);
|
||||
|
||||
tr_error* error = nullptr;
|
||||
auto error = tr_error{};
|
||||
auto lockfile_fd = tr_sys_file_open(lockfile_path, TR_SYS_FILE_READ | TR_SYS_FILE_WRITE | TR_SYS_FILE_CREATE, 0600, &error);
|
||||
|
||||
if (lockfile_fd != TR_BAD_SYS_FILE)
|
||||
|
@ -62,14 +62,13 @@ tr_sys_file_t create_lockfile(std::string_view session_id)
|
|||
}
|
||||
}
|
||||
|
||||
if (error != nullptr)
|
||||
if (error)
|
||||
{
|
||||
tr_logAddWarn(fmt::format(
|
||||
_("Couldn't create '{path}': {error} ({error_code})"),
|
||||
fmt::arg("path", lockfile_path),
|
||||
fmt::arg("error", error->message),
|
||||
fmt::arg("error_code", error->code)));
|
||||
tr_error_free(error);
|
||||
fmt::arg("error", error.message()),
|
||||
fmt::arg("error_code", error.code())));
|
||||
}
|
||||
|
||||
return lockfile_fd;
|
||||
|
@ -126,33 +125,32 @@ bool tr_session_id::is_local(std::string_view session_id) noexcept
|
|||
auto is_local = bool{ false };
|
||||
auto lockfile_path = tr_pathbuf{};
|
||||
get_lockfile_path(session_id, lockfile_path);
|
||||
tr_error* error = nullptr;
|
||||
auto error = tr_error{};
|
||||
if (auto lockfile_fd = tr_sys_file_open(lockfile_path, TR_SYS_FILE_READ, 0, &error); lockfile_fd == TR_BAD_SYS_FILE)
|
||||
{
|
||||
if (TR_ERROR_IS_ENOENT(error->code))
|
||||
if (TR_ERROR_IS_ENOENT(error.code()))
|
||||
{
|
||||
tr_error_clear(&error);
|
||||
error = {};
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
if (!tr_sys_file_lock(lockfile_fd, TR_SYS_FILE_LOCK_SH | TR_SYS_FILE_LOCK_NB, &error) && (error->code == WouldBlock))
|
||||
if (!tr_sys_file_lock(lockfile_fd, TR_SYS_FILE_LOCK_SH | TR_SYS_FILE_LOCK_NB, &error) && (error.code() == WouldBlock))
|
||||
{
|
||||
is_local = true;
|
||||
tr_error_clear(&error);
|
||||
error = {};
|
||||
}
|
||||
|
||||
tr_sys_file_close(lockfile_fd);
|
||||
}
|
||||
|
||||
if (error != nullptr)
|
||||
if (error)
|
||||
{
|
||||
tr_logAddWarn(fmt::format(
|
||||
_("Couldn't open session lock file '{path}': {error} ({error_code})"),
|
||||
fmt::arg("path", lockfile_path),
|
||||
fmt::arg("error", error->message),
|
||||
fmt::arg("error_code", error->code)));
|
||||
tr_error_free(error);
|
||||
fmt::arg("error", error.message()),
|
||||
fmt::arg("error_code", error.code())));
|
||||
}
|
||||
|
||||
return is_local;
|
||||
|
|
|
@ -40,14 +40,12 @@ void handle_sigchld(int /*i*/)
|
|||
/* FIXME: Call old handler, if any */
|
||||
}
|
||||
|
||||
void set_system_error(tr_error** error, int code, std::string_view what)
|
||||
void set_system_error(tr_error* error, int code, std::string_view what)
|
||||
{
|
||||
if (error == nullptr)
|
||||
if (error != nullptr)
|
||||
{
|
||||
return;
|
||||
error->set(code, fmt::format(FMT_STRING("{:s} failed: {:s} ({:d})"), what, tr_strerror(code), code));
|
||||
}
|
||||
|
||||
tr_error_set(error, code, fmt::format(FMT_STRING("{:s} failed: {:s} ({:d})"), what, tr_strerror(code), code));
|
||||
}
|
||||
|
||||
[[nodiscard]] bool tr_spawn_async_in_child(
|
||||
|
@ -82,7 +80,7 @@ void set_system_error(tr_error** error, int code, std::string_view what)
|
|||
return true;
|
||||
}
|
||||
|
||||
[[nodiscard]] bool tr_spawn_async_in_parent(int pipe_fd, tr_error** error)
|
||||
[[nodiscard]] bool tr_spawn_async_in_parent(int pipe_fd, tr_error* error)
|
||||
{
|
||||
int child_errno = 0;
|
||||
ssize_t count = 0;
|
||||
|
@ -120,7 +118,7 @@ bool tr_spawn_async(
|
|||
char const* const* cmd,
|
||||
std::map<std::string_view, std::string_view> const& env,
|
||||
std::string_view work_dir,
|
||||
tr_error** error)
|
||||
tr_error* error)
|
||||
{
|
||||
static bool sigchld_handler_set = false;
|
||||
|
||||
|
|
|
@ -35,7 +35,7 @@ enum class tr_app_type
|
|||
BATCH
|
||||
};
|
||||
|
||||
void set_system_error(tr_error** error, DWORD code, std::string_view what)
|
||||
void set_system_error(tr_error* error, DWORD code, std::string_view what)
|
||||
{
|
||||
if (error == nullptr)
|
||||
{
|
||||
|
@ -44,11 +44,11 @@ void set_system_error(tr_error** error, DWORD code, std::string_view what)
|
|||
|
||||
if (auto const message = tr_win32_format_message(code); !std::empty(message))
|
||||
{
|
||||
tr_error_set(error, code, fmt::format(FMT_STRING("{:s} failed: {:s}"), what, message));
|
||||
error->set(code, fmt::format(FMT_STRING("{:s} failed: {:s}"), what, message));
|
||||
}
|
||||
else
|
||||
{
|
||||
tr_error_set(error, code, fmt::format(FMT_STRING("{:s} failed: Unknown error: {:#08x}"), what, code));
|
||||
error->set(code, fmt::format(FMT_STRING("{:s} failed: Unknown error: {:#08x}"), what, code));
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -271,7 +271,7 @@ bool tr_spawn_async(
|
|||
char const* const* cmd,
|
||||
std::map<std::string_view, std::string_view> const& env,
|
||||
std::string_view work_dir,
|
||||
tr_error** error)
|
||||
tr_error* error)
|
||||
{
|
||||
// full_env = current_env + env;
|
||||
auto full_env = get_current_env();
|
||||
|
|
|
@ -14,4 +14,4 @@ bool tr_spawn_async(
|
|||
char const* const* cmd,
|
||||
std::map<std::string_view, std::string_view> const& env,
|
||||
std::string_view work_dir,
|
||||
tr_error** error);
|
||||
tr_error* error);
|
||||
|
|
|
@ -84,11 +84,15 @@ tr_torrent::VerifyDoneCallback tr_ctorStealVerifyDoneCallback(tr_ctor* ctor)
|
|||
|
||||
// ---
|
||||
|
||||
bool tr_ctorSetMetainfoFromFile(tr_ctor* ctor, std::string_view filename, tr_error** error)
|
||||
bool tr_ctorSetMetainfoFromFile(tr_ctor* ctor, std::string_view filename, tr_error* error)
|
||||
{
|
||||
if (std::empty(filename))
|
||||
{
|
||||
tr_error_set(error, EINVAL, "no filename specified"sv);
|
||||
if (error != nullptr)
|
||||
{
|
||||
error->set(EINVAL, "no filename specified"sv);
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
|
@ -102,12 +106,12 @@ bool tr_ctorSetMetainfoFromFile(tr_ctor* ctor, std::string_view filename, tr_err
|
|||
return ctor->metainfo.parse_benc(contents_sv, error);
|
||||
}
|
||||
|
||||
bool tr_ctorSetMetainfoFromFile(tr_ctor* ctor, char const* filename, tr_error** error)
|
||||
bool tr_ctorSetMetainfoFromFile(tr_ctor* ctor, char const* filename, tr_error* error)
|
||||
{
|
||||
return tr_ctorSetMetainfoFromFile(ctor, std::string_view{ filename != nullptr ? filename : "" }, error);
|
||||
}
|
||||
|
||||
bool tr_ctorSetMetainfo(tr_ctor* ctor, char const* metainfo, size_t len, tr_error** error)
|
||||
bool tr_ctorSetMetainfo(tr_ctor* ctor, char const* metainfo, size_t len, tr_error* error)
|
||||
{
|
||||
ctor->torrent_filename.clear();
|
||||
ctor->contents.assign(metainfo, metainfo + len);
|
||||
|
@ -115,14 +119,14 @@ bool tr_ctorSetMetainfo(tr_ctor* ctor, char const* metainfo, size_t len, tr_erro
|
|||
return ctor->metainfo.parse_benc(contents_sv, error);
|
||||
}
|
||||
|
||||
bool tr_ctorSetMetainfoFromMagnetLink(tr_ctor* ctor, std::string_view magnet_link, tr_error** error)
|
||||
bool tr_ctorSetMetainfoFromMagnetLink(tr_ctor* ctor, std::string_view magnet_link, tr_error* error)
|
||||
{
|
||||
ctor->torrent_filename.clear();
|
||||
ctor->metainfo = {};
|
||||
return ctor->metainfo.parseMagnet(magnet_link, error);
|
||||
}
|
||||
|
||||
bool tr_ctorSetMetainfoFromMagnetLink(tr_ctor* ctor, char const* magnet_link, tr_error** error)
|
||||
bool tr_ctorSetMetainfoFromMagnetLink(tr_ctor* ctor, char const* magnet_link, tr_error* error)
|
||||
{
|
||||
return tr_ctorSetMetainfoFromMagnetLink(ctor, std::string_view{ magnet_link != nullptr ? magnet_link : "" }, error);
|
||||
}
|
||||
|
@ -132,14 +136,18 @@ char const* tr_ctorGetSourceFile(tr_ctor const* ctor)
|
|||
return ctor->torrent_filename.c_str();
|
||||
}
|
||||
|
||||
bool tr_ctorSaveContents(tr_ctor const* ctor, std::string_view filename, tr_error** error)
|
||||
bool tr_ctorSaveContents(tr_ctor const* ctor, std::string_view filename, tr_error* error)
|
||||
{
|
||||
TR_ASSERT(ctor != nullptr);
|
||||
TR_ASSERT(!std::empty(filename));
|
||||
|
||||
if (std::empty(ctor->contents))
|
||||
{
|
||||
tr_error_set(error, EINVAL, "torrent ctor has no contents to save"sv);
|
||||
if (error != nullptr)
|
||||
{
|
||||
error->set(EINVAL, "torrent ctor has no contents to save"sv);
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
|
|
|
@ -159,7 +159,7 @@ bool tr_torrent_files::move(
|
|||
std::string_view old_parent_in,
|
||||
std::string_view parent_in,
|
||||
std::string_view parent_name,
|
||||
tr_error** error) const
|
||||
tr_error* error) const
|
||||
{
|
||||
auto const old_parent = tr_pathbuf{ old_parent_in };
|
||||
auto const parent = tr_pathbuf{ parent_in };
|
||||
|
|
|
@ -114,7 +114,7 @@ public:
|
|||
std::string_view old_parent_in,
|
||||
std::string_view parent_in,
|
||||
std::string_view parent_name = "",
|
||||
tr_error** error = nullptr) const;
|
||||
tr_error* error = nullptr) const;
|
||||
|
||||
using FileFunc = std::function<void(char const* filename)>;
|
||||
void remove(std::string_view parent_in, std::string_view tmpdir_prefix, FileFunc const& func) const;
|
||||
|
|
|
@ -128,7 +128,7 @@ bool tr_torrentUseMetainfoFromFile(
|
|||
tr_torrent* tor,
|
||||
tr_torrent_metainfo const* metainfo,
|
||||
char const* filename_in,
|
||||
tr_error** error)
|
||||
tr_error* error)
|
||||
{
|
||||
// add .torrent file
|
||||
if (!tr_sys_path_copy(filename_in, tor->torrent_file().c_str(), error))
|
||||
|
@ -202,7 +202,7 @@ tr_variant build_metainfo_except_info_dict(tr_torrent_metainfo const& tm)
|
|||
return tr_variant{ std::move(top) };
|
||||
}
|
||||
|
||||
bool use_new_metainfo(tr_torrent* tor, tr_error** error)
|
||||
bool use_new_metainfo(tr_torrent* tor, tr_error* error)
|
||||
{
|
||||
auto const& m = tor->incomplete_metadata;
|
||||
TR_ASSERT(m);
|
||||
|
@ -218,7 +218,12 @@ bool use_new_metainfo(tr_torrent* tor, tr_error** error)
|
|||
auto info_dict_v = serde.parse(m->metadata);
|
||||
if (!info_dict_v)
|
||||
{
|
||||
tr_error_propagate(error, &serde.error_);
|
||||
if (error != nullptr)
|
||||
{
|
||||
*error = std::move(serde.error_);
|
||||
serde.error_ = {};
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
|
@ -251,7 +256,7 @@ bool use_new_metainfo(tr_torrent* tor, tr_error** error)
|
|||
|
||||
void on_have_all_metainfo(tr_torrent* tor)
|
||||
{
|
||||
tr_error* error = nullptr;
|
||||
auto error = tr_error{};
|
||||
auto& m = tor->incomplete_metadata;
|
||||
TR_ASSERT(m);
|
||||
if (use_new_metainfo(tor, &error))
|
||||
|
@ -264,7 +269,7 @@ void on_have_all_metainfo(tr_torrent* tor)
|
|||
|
||||
m->pieces_needed = create_all_needed(n);
|
||||
|
||||
char const* const msg = error != nullptr && error->message != nullptr ? error->message : "unknown error";
|
||||
auto msg = std::string_view{ error && !std::empty(error.message()) ? error.message() : "unknown error" };
|
||||
tr_logAddWarnTor(
|
||||
tor,
|
||||
fmt::format(
|
||||
|
@ -274,7 +279,6 @@ void on_have_all_metainfo(tr_torrent* tor)
|
|||
n),
|
||||
fmt::arg("error", msg),
|
||||
fmt::arg("piece_count", n)));
|
||||
tr_error_clear(&error);
|
||||
}
|
||||
}
|
||||
} // namespace set_metadata_piece_helpers
|
||||
|
|
|
@ -55,8 +55,4 @@ double tr_torrentGetMetadataPercent(tr_torrent const* tor);
|
|||
|
||||
void tr_torrentMagnetDoIdleWork(tr_torrent* tor);
|
||||
|
||||
bool tr_torrentUseMetainfoFromFile(
|
||||
tr_torrent* tor,
|
||||
tr_torrent_metainfo const* metainfo,
|
||||
char const* filename,
|
||||
tr_error** error);
|
||||
bool tr_torrentUseMetainfoFromFile(tr_torrent* tor, tr_torrent_metainfo const* metainfo, char const* filename, tr_error* error);
|
||||
|
|
|
@ -51,11 +51,6 @@ std::string tr_torrent_metainfo::fix_webseed_url(tr_torrent_metainfo const& tm,
|
|||
namespace
|
||||
{
|
||||
auto constexpr MaxBencDepth = 32;
|
||||
|
||||
bool tr_error_is_set(tr_error const* const* error)
|
||||
{
|
||||
return (error != nullptr) && (*error != nullptr);
|
||||
}
|
||||
} // namespace
|
||||
|
||||
struct MetainfoHandler final : public transmission::benc::BasicHandler<MaxBencDepth>
|
||||
|
@ -368,7 +363,7 @@ struct MetainfoHandler final : public transmission::benc::BasicHandler<MaxBencDe
|
|||
}
|
||||
else
|
||||
{
|
||||
tr_error_set(context.error, EINVAL, fmt::format("invalid piece size: {}", std::size(value)));
|
||||
context.error.set(EINVAL, fmt::format("invalid piece size: {}", std::size(value)));
|
||||
unhandled = true;
|
||||
}
|
||||
}
|
||||
|
@ -470,7 +465,7 @@ private:
|
|||
// for hybrid torrents with duplicate info between "file tree" and "files"
|
||||
if (std::empty(file_subpath_))
|
||||
{
|
||||
tr_error_set(context.error, EINVAL, fmt::format("invalid path [{:s}]", file_subpath_));
|
||||
context.error.set(EINVAL, fmt::format("invalid path [{:s}]", file_subpath_));
|
||||
ok = false;
|
||||
}
|
||||
else
|
||||
|
@ -489,7 +484,7 @@ private:
|
|||
{
|
||||
if (std::empty(info_dict_begin_))
|
||||
{
|
||||
tr_error_set(context.error, EINVAL, "no info_dict found");
|
||||
context.error.set(EINVAL, "no info_dict found");
|
||||
return false;
|
||||
}
|
||||
|
||||
|
@ -536,18 +531,18 @@ private:
|
|||
// do some sanity checks to make sure the torrent looks sane
|
||||
if (tm_.file_count() == 0)
|
||||
{
|
||||
if (!tr_error_is_set(context.error))
|
||||
if (!context.error)
|
||||
{
|
||||
tr_error_set(context.error, EINVAL, "no files found");
|
||||
context.error.set(EINVAL, "no files found");
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
if (piece_size_ == 0)
|
||||
{
|
||||
if (!tr_error_is_set(context.error))
|
||||
if (!context.error)
|
||||
{
|
||||
tr_error_set(context.error, EINVAL, fmt::format("invalid piece size: {}", piece_size_));
|
||||
context.error.set(EINVAL, fmt::format("invalid piece size: {}", piece_size_));
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
@ -627,26 +622,24 @@ private:
|
|||
static constexpr std::string_view XCrossSeedKey = "x_cross_seed"sv;
|
||||
};
|
||||
|
||||
bool tr_torrent_metainfo::parse_benc(std::string_view benc, tr_error** error)
|
||||
bool tr_torrent_metainfo::parse_benc(std::string_view benc, tr_error* error)
|
||||
{
|
||||
auto stack = transmission::benc::ParserStack<MaxBencDepth>{};
|
||||
auto handler = MetainfoHandler{ *this };
|
||||
|
||||
tr_error* my_error = nullptr;
|
||||
|
||||
auto local_error = tr_error{};
|
||||
if (error == nullptr)
|
||||
{
|
||||
error = &my_error;
|
||||
error = &local_error;
|
||||
}
|
||||
|
||||
auto const ok = transmission::benc::parse(benc, stack, handler, nullptr, error);
|
||||
|
||||
if (tr_error_is_set(error))
|
||||
if (*error)
|
||||
{
|
||||
tr_logAddError(fmt::format("{} ({})", (*error)->message, (*error)->code));
|
||||
tr_logAddError(fmt::format("{} ({})", error->message(), error->code()));
|
||||
}
|
||||
|
||||
tr_error_clear(&my_error);
|
||||
|
||||
if (!ok)
|
||||
{
|
||||
return false;
|
||||
|
@ -660,7 +653,7 @@ bool tr_torrent_metainfo::parse_benc(std::string_view benc, tr_error** error)
|
|||
return true;
|
||||
}
|
||||
|
||||
bool tr_torrent_metainfo::parse_torrent_file(std::string_view filename, std::vector<char>* contents, tr_error** error)
|
||||
bool tr_torrent_metainfo::parse_torrent_file(std::string_view filename, std::vector<char>* contents, tr_error* error)
|
||||
{
|
||||
auto local_contents = std::vector<char>{};
|
||||
|
||||
|
|
|
@ -28,13 +28,13 @@ public:
|
|||
return std::empty(files_);
|
||||
}
|
||||
|
||||
bool parse_benc(std::string_view benc, tr_error** error = nullptr);
|
||||
bool parse_benc(std::string_view benc, tr_error* error = nullptr);
|
||||
|
||||
// Helper function wrapper around parseBenc().
|
||||
// If you're looping through several files, passing in a non-nullptr
|
||||
// `contents` can reduce the number of memory allocations needed to
|
||||
// load multiple files.
|
||||
bool parse_torrent_file(std::string_view benc_filename, std::vector<char>* contents = nullptr, tr_error** error = nullptr);
|
||||
bool parse_torrent_file(std::string_view benc_filename, std::vector<char>* contents = nullptr, tr_error* error = nullptr);
|
||||
|
||||
// FILES
|
||||
|
||||
|
@ -196,7 +196,7 @@ public:
|
|||
|
||||
private:
|
||||
friend struct MetainfoHandler;
|
||||
static bool parse_impl(tr_torrent_metainfo& setme, std::string_view benc, tr_error** error);
|
||||
static bool parse_impl(tr_torrent_metainfo& setme, std::string_view benc, tr_error* error);
|
||||
static std::string fix_webseed_url(tr_torrent_metainfo const& tm, std::string_view url);
|
||||
|
||||
enum class BasenameFormat
|
||||
|
|
|
@ -127,18 +127,16 @@ bool tr_torrentSetMetainfoFromFile(tr_torrent* tor, tr_torrent_metainfo const* m
|
|||
return false;
|
||||
}
|
||||
|
||||
tr_error* error = nullptr;
|
||||
auto error = tr_error{};
|
||||
tr_torrentUseMetainfoFromFile(tor, metainfo, filename, &error);
|
||||
|
||||
if (error != nullptr)
|
||||
if (error)
|
||||
{
|
||||
tor->error().set_local_error(fmt::format(
|
||||
_("Couldn't use metainfo from '{path}' for '{magnet}': {error} ({error_code})"),
|
||||
fmt::arg("path", filename),
|
||||
fmt::arg("magnet", tor->magnet()),
|
||||
fmt::arg("error", error->message),
|
||||
fmt::arg("error_code", error->code)));
|
||||
tr_error_clear(&error);
|
||||
fmt::arg("error", error.message()),
|
||||
fmt::arg("error_code", error.code())));
|
||||
return false;
|
||||
}
|
||||
|
||||
|
@ -402,8 +400,7 @@ void torrentCallScript(tr_torrent const* tor, std::string const& script)
|
|||
|
||||
tr_logAddInfoTor(tor, fmt::format(_("Calling script '{path}'"), fmt::arg("path", script)));
|
||||
|
||||
tr_error* error = nullptr;
|
||||
|
||||
auto error = tr_error{};
|
||||
if (!tr_spawn_async(std::data(cmd), env, TR_IF_WIN32("\\", "/"), &error))
|
||||
{
|
||||
tr_logAddWarnTor(
|
||||
|
@ -411,9 +408,8 @@ void torrentCallScript(tr_torrent const* tor, std::string const& script)
|
|||
fmt::format(
|
||||
_("Couldn't call script '{path}': {error} ({error_code})"),
|
||||
fmt::arg("path", script),
|
||||
fmt::arg("error", error->message),
|
||||
fmt::arg("error_code", error->code)));
|
||||
tr_error_free(error);
|
||||
fmt::arg("error", error.message()),
|
||||
fmt::arg("error_code", error.code())));
|
||||
}
|
||||
}
|
||||
} // namespace script_helpers
|
||||
|
@ -662,7 +658,7 @@ void torrentStartImpl(tr_torrent* const tor)
|
|||
tor->started_.emit(tor);
|
||||
}
|
||||
|
||||
bool removeTorrentFile(char const* filename, void* /*user_data*/, tr_error** error)
|
||||
bool removeTorrentFile(char const* filename, void* /*user_data*/, tr_error* error)
|
||||
{
|
||||
return tr_sys_path_remove(filename, error);
|
||||
}
|
||||
|
@ -1059,7 +1055,7 @@ void tr_torrent::init(tr_ctor const* const ctor)
|
|||
|
||||
if (is_new_torrent)
|
||||
{
|
||||
tr_error* error = nullptr;
|
||||
auto error = tr_error{};
|
||||
|
||||
if (has_metainfo()) // torrent file
|
||||
{
|
||||
|
@ -1071,14 +1067,13 @@ void tr_torrent::init(tr_ctor const* const ctor)
|
|||
tr_file_save(filename, magnet_link, &error);
|
||||
}
|
||||
|
||||
if (error != nullptr)
|
||||
if (error)
|
||||
{
|
||||
this->error().set_local_error(fmt::format(
|
||||
_("Couldn't save '{path}': {error} ({error_code})"),
|
||||
fmt::arg("path", filename),
|
||||
fmt::arg("error", error->message),
|
||||
fmt::arg("error_code", error->code)));
|
||||
tr_error_clear(&error);
|
||||
fmt::arg("error", error.message()),
|
||||
fmt::arg("error_code", error.code())));
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -1173,18 +1168,17 @@ void setLocationInSessionThread(tr_torrent* tor, std::string const& path, bool m
|
|||
tor->session->closeTorrentFiles(tor);
|
||||
tor->session->verify_remove(tor);
|
||||
|
||||
tr_error* error = nullptr;
|
||||
auto error = tr_error{};
|
||||
ok = tor->metainfo_.files().move(tor->current_dir(), path, tor->name(), &error);
|
||||
if (error != nullptr)
|
||||
if (error)
|
||||
{
|
||||
tor->error().set_local_error(fmt::format(
|
||||
_("Couldn't move '{old_path}' to '{path}': {error} ({error_code})"),
|
||||
fmt::arg("old_path", tor->current_dir()),
|
||||
fmt::arg("path", path),
|
||||
fmt::arg("error", error->message),
|
||||
fmt::arg("error_code", error->code)));
|
||||
fmt::arg("error", error.message()),
|
||||
fmt::arg("error_code", error.code())));
|
||||
tr_torrentStop(tor);
|
||||
tr_error_clear(&error);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -2029,15 +2023,14 @@ bool tr_torrent::set_tracker_list(std::string_view text)
|
|||
{
|
||||
auto const magnet_file = this->magnet_file();
|
||||
auto const magnet_link = this->magnet();
|
||||
tr_error* save_error = nullptr;
|
||||
auto save_error = tr_error{};
|
||||
if (!tr_file_save(magnet_file, magnet_link, &save_error))
|
||||
{
|
||||
this->error().set_local_error(fmt::format(
|
||||
_("Couldn't save '{path}': {error} ({error_code})"),
|
||||
fmt::arg("path", magnet_file),
|
||||
fmt::arg("error", save_error->message),
|
||||
fmt::arg("error_code", save_error->code)));
|
||||
tr_error_clear(&save_error);
|
||||
fmt::arg("error", save_error.message()),
|
||||
fmt::arg("error_code", save_error.code())));
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -2194,7 +2187,7 @@ void onFileCompleted(tr_torrent* tor, tr_file_index_t i)
|
|||
{
|
||||
auto const& oldpath = found->filename();
|
||||
auto const newpath = tr_pathbuf{ found->base(), '/', file_subpath };
|
||||
tr_error* error = nullptr;
|
||||
auto error = tr_error{};
|
||||
|
||||
if (!tr_sys_path_rename(oldpath, newpath, &error))
|
||||
{
|
||||
|
@ -2204,9 +2197,8 @@ void onFileCompleted(tr_torrent* tor, tr_file_index_t i)
|
|||
_("Couldn't move '{old_path}' to '{path}': {error} ({error_code})"),
|
||||
fmt::arg("old_path", oldpath),
|
||||
fmt::arg("path", newpath),
|
||||
fmt::arg("error", error->message),
|
||||
fmt::arg("error_code", error->code)));
|
||||
tr_error_free(error);
|
||||
fmt::arg("error", error.message()),
|
||||
fmt::arg("error_code", error.code())));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -2429,14 +2421,11 @@ int renamePath(tr_torrent const* tor, std::string_view oldpath, std::string_view
|
|||
|
||||
if (!tgt_exists)
|
||||
{
|
||||
tr_error* error = nullptr;
|
||||
|
||||
tmp = errno;
|
||||
|
||||
if (!tr_sys_path_rename(src, tgt, &error))
|
||||
if (auto error = tr_error{}; !tr_sys_path_rename(src, tgt, &error))
|
||||
{
|
||||
err = error->code;
|
||||
tr_error_free(error);
|
||||
err = error.code();
|
||||
}
|
||||
|
||||
errno = tmp;
|
||||
|
|
|
@ -54,7 +54,7 @@ void tr_ctorInitTorrentPriorities(tr_ctor const* ctor, tr_torrent* tor);
|
|||
|
||||
void tr_ctorInitTorrentWanted(tr_ctor const* ctor, tr_torrent* tor);
|
||||
|
||||
bool tr_ctorSaveContents(tr_ctor const* ctor, std::string_view filename, tr_error** error);
|
||||
bool tr_ctorSaveContents(tr_ctor const* ctor, std::string_view filename, tr_error* error);
|
||||
|
||||
tr_session* tr_ctorGetSession(tr_ctor const* ctor);
|
||||
|
||||
|
@ -1223,8 +1223,8 @@ void tr_torrentGotBlock(tr_torrent* tor, tr_block_index_t block);
|
|||
|
||||
tr_torrent_metainfo tr_ctorStealMetainfo(tr_ctor* ctor);
|
||||
|
||||
bool tr_ctorSetMetainfoFromFile(tr_ctor* ctor, std::string_view filename, tr_error** error = nullptr);
|
||||
bool tr_ctorSetMetainfoFromMagnetLink(tr_ctor* ctor, std::string_view magnet_link, tr_error** error = nullptr);
|
||||
bool tr_ctorSetMetainfoFromFile(tr_ctor* ctor, std::string_view filename, tr_error* error = nullptr);
|
||||
bool tr_ctorSetMetainfoFromMagnetLink(tr_ctor* ctor, std::string_view magnet_link, tr_error* error = nullptr);
|
||||
void tr_ctorSetLabels(tr_ctor* ctor, tr_torrent::labels_t&& labels);
|
||||
void tr_ctorSetBandwidthPriority(tr_ctor* ctor, tr_priority_t priority);
|
||||
tr_priority_t tr_ctorGetBandwidthPriority(tr_ctor const* ctor);
|
||||
|
|
|
@ -100,7 +100,7 @@ public:
|
|||
}
|
||||
|
||||
// Returns the number of bytes written. Check `error` for error.
|
||||
size_t to_socket(tr_socket_t sockfd, size_t n_bytes, tr_error** error = nullptr)
|
||||
size_t to_socket(tr_socket_t sockfd, size_t n_bytes, tr_error* error = nullptr)
|
||||
{
|
||||
n_bytes = std::min(n_bytes, size());
|
||||
|
||||
|
@ -115,8 +115,12 @@ public:
|
|||
return n_sent;
|
||||
}
|
||||
|
||||
auto const err = sockerrno;
|
||||
tr_error_set(error, err, tr_net_strerror(err));
|
||||
if (error != nullptr)
|
||||
{
|
||||
auto const err = sockerrno;
|
||||
error->set(err, tr_net_strerror(err));
|
||||
}
|
||||
|
||||
return {};
|
||||
}
|
||||
|
||||
|
@ -210,7 +214,7 @@ public:
|
|||
}
|
||||
}
|
||||
|
||||
size_t add_socket(tr_socket_t sockfd, size_t n_bytes, tr_error** error = nullptr)
|
||||
size_t add_socket(tr_socket_t sockfd, size_t n_bytes, tr_error* error = nullptr)
|
||||
{
|
||||
auto const [buf, buflen] = reserve_space(n_bytes);
|
||||
auto const n_read = recv(sockfd, reinterpret_cast<char*>(buf), std::min(n_bytes, buflen), 0);
|
||||
|
@ -224,13 +228,16 @@ public:
|
|||
|
||||
// When a stream socket peer has performed an orderly shutdown,
|
||||
// the return value will be 0 (the traditional "end-of-file" return).
|
||||
if (n_read == 0)
|
||||
if (error != nullptr)
|
||||
{
|
||||
tr_error_set_from_errno(error, ENOTCONN);
|
||||
}
|
||||
else
|
||||
{
|
||||
tr_error_set(error, err, tr_net_strerror(err));
|
||||
if (n_read == 0)
|
||||
{
|
||||
error->set_from_errno(ENOTCONN);
|
||||
}
|
||||
else
|
||||
{
|
||||
error->set(err, tr_net_strerror(err));
|
||||
}
|
||||
}
|
||||
|
||||
return {};
|
||||
|
|
|
@ -764,15 +764,15 @@ bool tr_ctorGetDeleteSource(tr_ctor const* ctor, bool* setme_do_delete);
|
|||
void tr_ctorSetDeleteSource(tr_ctor* ctor, bool delete_source);
|
||||
|
||||
/** @brief Set the constructor's metainfo from a magnet link */
|
||||
bool tr_ctorSetMetainfoFromMagnetLink(tr_ctor* ctor, char const* magnet, tr_error** error);
|
||||
bool tr_ctorSetMetainfoFromMagnetLink(tr_ctor* ctor, char const* magnet, tr_error* error);
|
||||
|
||||
tr_torrent_metainfo const* tr_ctorGetMetainfo(tr_ctor const* ctor);
|
||||
|
||||
/** @brief Set the constructor's metainfo from a raw benc already in memory */
|
||||
bool tr_ctorSetMetainfo(tr_ctor* ctor, char const* metainfo, size_t len, tr_error** error);
|
||||
bool tr_ctorSetMetainfo(tr_ctor* ctor, char const* metainfo, size_t len, tr_error* error);
|
||||
|
||||
/** @brief Set the constructor's metainfo from a local torrent file */
|
||||
bool tr_ctorSetMetainfoFromFile(tr_ctor* ctor, char const* filename, tr_error** error);
|
||||
bool tr_ctorSetMetainfoFromFile(tr_ctor* ctor, char const* filename, tr_error* error);
|
||||
|
||||
/** @brief Get this peer constructor's peer limit */
|
||||
bool tr_ctorGetPeerLimit(tr_ctor const* ctor, tr_ctorMode mode, uint16_t* setme_count);
|
||||
|
@ -841,7 +841,7 @@ tr_torrent* tr_torrentNew(tr_ctor* ctor, tr_torrent** setme_duplicate_of);
|
|||
/** @addtogroup tr_torrent Torrents
|
||||
@{ */
|
||||
|
||||
using tr_fileFunc = bool (*)(char const* filename, void* user_data, struct tr_error** error);
|
||||
using tr_fileFunc = bool (*)(char const* filename, void* user_data, tr_error* error);
|
||||
|
||||
/** @brief Removes our torrent and .resume files for this torrent */
|
||||
void tr_torrentRemove(tr_torrent* torrent, bool delete_flag, tr_fileFunc delete_func, void* user_data);
|
||||
|
|
|
@ -93,54 +93,56 @@ std::optional<std::locale> tr_locale_set_global(std::locale const& locale) noexc
|
|||
|
||||
// ---
|
||||
|
||||
bool tr_file_read(std::string_view filename, std::vector<char>& contents, tr_error** error)
|
||||
bool tr_file_read(std::string_view filename, std::vector<char>& contents, tr_error* error)
|
||||
{
|
||||
auto const szfilename = tr_pathbuf{ filename };
|
||||
|
||||
/* try to stat the file */
|
||||
tr_error* my_error = nullptr;
|
||||
auto const info = tr_sys_path_get_info(szfilename, 0, &my_error);
|
||||
if (my_error != nullptr)
|
||||
auto local_error = tr_error{};
|
||||
if (error == nullptr)
|
||||
{
|
||||
error = &local_error;
|
||||
}
|
||||
|
||||
auto const info = tr_sys_path_get_info(szfilename, 0, error);
|
||||
if (*error)
|
||||
{
|
||||
tr_logAddError(fmt::format(
|
||||
_("Couldn't read '{path}': {error} ({error_code})"),
|
||||
fmt::arg("path", filename),
|
||||
fmt::arg("error", my_error->message),
|
||||
fmt::arg("error_code", my_error->code)));
|
||||
tr_error_propagate(error, &my_error);
|
||||
fmt::arg("error", error->message()),
|
||||
fmt::arg("error_code", error->code())));
|
||||
return false;
|
||||
}
|
||||
|
||||
if (!info || !info->isFile())
|
||||
{
|
||||
tr_logAddError(fmt::format(_("Couldn't read '{path}': Not a regular file"), fmt::arg("path", filename)));
|
||||
tr_error_set(error, TR_ERROR_EISDIR, "Not a regular file"sv);
|
||||
error->set(TR_ERROR_EISDIR, "Not a regular file"sv);
|
||||
return false;
|
||||
}
|
||||
|
||||
/* Load the torrent file into our buffer */
|
||||
auto const fd = tr_sys_file_open(szfilename, TR_SYS_FILE_READ | TR_SYS_FILE_SEQUENTIAL, 0, &my_error);
|
||||
auto const fd = tr_sys_file_open(szfilename, TR_SYS_FILE_READ | TR_SYS_FILE_SEQUENTIAL, 0, error);
|
||||
if (fd == TR_BAD_SYS_FILE)
|
||||
{
|
||||
tr_logAddError(fmt::format(
|
||||
_("Couldn't read '{path}': {error} ({error_code})"),
|
||||
fmt::arg("path", filename),
|
||||
fmt::arg("error", my_error->message),
|
||||
fmt::arg("error_code", my_error->code)));
|
||||
tr_error_propagate(error, &my_error);
|
||||
fmt::arg("error", error->message()),
|
||||
fmt::arg("error_code", error->code())));
|
||||
return false;
|
||||
}
|
||||
|
||||
contents.resize(info->size);
|
||||
if (!tr_sys_file_read(fd, std::data(contents), info->size, nullptr, &my_error))
|
||||
if (!tr_sys_file_read(fd, std::data(contents), info->size, nullptr, error))
|
||||
{
|
||||
tr_logAddError(fmt::format(
|
||||
_("Couldn't read '{path}': {error} ({error_code})"),
|
||||
fmt::arg("path", filename),
|
||||
fmt::arg("error", my_error->message),
|
||||
fmt::arg("error_code", my_error->code)));
|
||||
fmt::arg("error", error->message()),
|
||||
fmt::arg("error_code", error->code())));
|
||||
tr_sys_file_close(fd);
|
||||
tr_error_propagate(error, &my_error);
|
||||
return false;
|
||||
}
|
||||
|
||||
|
@ -148,7 +150,7 @@ bool tr_file_read(std::string_view filename, std::vector<char>& contents, tr_err
|
|||
return true;
|
||||
}
|
||||
|
||||
bool tr_file_save(std::string_view filename, std::string_view contents, tr_error** error)
|
||||
bool tr_file_save(std::string_view filename, std::string_view contents, tr_error* error)
|
||||
{
|
||||
// follow symlinks to find the "real" file, to make sure the temporary
|
||||
// we build with tr_sys_file_open_temp() is created on the right partition
|
||||
|
@ -561,21 +563,27 @@ std::string tr_strratio(double ratio, char const* infinity)
|
|||
|
||||
// ---
|
||||
|
||||
bool tr_file_move(std::string_view oldpath_in, std::string_view newpath_in, tr_error** error)
|
||||
bool tr_file_move(std::string_view oldpath_in, std::string_view newpath_in, tr_error* error)
|
||||
{
|
||||
auto const oldpath = tr_pathbuf{ oldpath_in };
|
||||
auto const newpath = tr_pathbuf{ newpath_in };
|
||||
|
||||
auto local_error = tr_error{};
|
||||
if (error == nullptr)
|
||||
{
|
||||
error = &local_error;
|
||||
}
|
||||
|
||||
// make sure the old file exists
|
||||
auto const info = tr_sys_path_get_info(oldpath, 0, error);
|
||||
if (!info)
|
||||
{
|
||||
tr_error_prefix(error, "Unable to get information on old file: ");
|
||||
error->prefix_message("Unable to get information on old file: ");
|
||||
return false;
|
||||
}
|
||||
if (!info->isFile())
|
||||
{
|
||||
tr_error_set(error, TR_ERROR_EINVAL, "Old path does not point to a file."sv);
|
||||
error->set(TR_ERROR_EINVAL, "Old path does not point to a file."sv);
|
||||
return false;
|
||||
}
|
||||
|
||||
|
@ -584,7 +592,7 @@ bool tr_file_move(std::string_view oldpath_in, std::string_view newpath_in, tr_e
|
|||
newdir.popdir();
|
||||
if (!tr_sys_dir_create(newdir, TR_SYS_DIR_CREATE_PARENTS, 0777, error))
|
||||
{
|
||||
tr_error_prefix(error, "Unable to create directory for new file: ");
|
||||
error->prefix_message("Unable to create directory for new file: ");
|
||||
return false;
|
||||
}
|
||||
|
||||
|
@ -597,18 +605,17 @@ bool tr_file_move(std::string_view oldpath_in, std::string_view newpath_in, tr_e
|
|||
/* Otherwise, copy the file. */
|
||||
if (!tr_sys_path_copy(oldpath, newpath, error))
|
||||
{
|
||||
tr_error_prefix(error, "Unable to copy: ");
|
||||
error->prefix_message("Unable to copy: ");
|
||||
return false;
|
||||
}
|
||||
|
||||
if (tr_error* my_error = nullptr; !tr_sys_path_remove(oldpath, &my_error))
|
||||
if (auto log_error = tr_error{}; !tr_sys_path_remove(oldpath, &log_error))
|
||||
{
|
||||
tr_logAddError(fmt::format(
|
||||
_("Couldn't remove '{path}': {error} ({error_code})"),
|
||||
fmt::arg("path", oldpath),
|
||||
fmt::arg("error", my_error->message),
|
||||
fmt::arg("error_code", my_error->code)));
|
||||
tr_error_free(my_error);
|
||||
fmt::arg("error", log_error.message()),
|
||||
fmt::arg("error_code", log_error.code())));
|
||||
}
|
||||
|
||||
return true;
|
||||
|
|
|
@ -63,14 +63,14 @@ std::optional<std::locale> tr_locale_set_global(std::locale const& locale) noexc
|
|||
|
||||
[[nodiscard]] std::string_view tr_get_mime_type_for_filename(std::string_view filename);
|
||||
|
||||
bool tr_file_read(std::string_view filename, std::vector<char>& contents, tr_error** error = nullptr);
|
||||
bool tr_file_read(std::string_view filename, std::vector<char>& contents, tr_error* error = nullptr);
|
||||
|
||||
bool tr_file_move(std::string_view oldpath, std::string_view newpath, struct tr_error** error = nullptr);
|
||||
bool tr_file_move(std::string_view oldpath, std::string_view newpath, tr_error* error = nullptr);
|
||||
|
||||
bool tr_file_save(std::string_view filename, std::string_view contents, tr_error** error = nullptr);
|
||||
bool tr_file_save(std::string_view filename, std::string_view contents, tr_error* error = nullptr);
|
||||
|
||||
template<typename ContiguousRange>
|
||||
constexpr auto tr_file_save(std::string_view filename, ContiguousRange const& x, tr_error** error = nullptr)
|
||||
constexpr auto tr_file_save(std::string_view filename, ContiguousRange const& x, tr_error* error = nullptr)
|
||||
{
|
||||
return tr_file_save(filename, std::string_view{ std::data(x), std::size(x) }, error);
|
||||
}
|
||||
|
|
|
@ -239,13 +239,12 @@ std::optional<tr_variant> tr_variant_serde::parse_json(std::string_view input)
|
|||
|
||||
if (auto err_code = reader.GetParseErrorCode(); err_code == rapidjson::kParseErrorDocumentEmpty)
|
||||
{
|
||||
tr_error_set(&error_, EINVAL, "No content");
|
||||
error_.set(EINVAL, "No content");
|
||||
}
|
||||
else
|
||||
{
|
||||
auto const err_offset = reader.GetErrorOffset();
|
||||
tr_error_set(
|
||||
&error_,
|
||||
error_.set(
|
||||
EILSEQ,
|
||||
fmt::format(
|
||||
_("Couldn't parse JSON at position {position} '{text}': {error} ({error_code})"),
|
||||
|
|
|
@ -850,14 +850,9 @@ void tr_variantMergeDicts(tr_variant* const tgt, tr_variant const* const src)
|
|||
|
||||
// ---
|
||||
|
||||
tr_variant_serde::~tr_variant_serde()
|
||||
{
|
||||
tr_error_clear(&error_);
|
||||
}
|
||||
|
||||
std::optional<tr_variant> tr_variant_serde::parse(std::string_view input)
|
||||
{
|
||||
tr_error_clear(&error_);
|
||||
error_ = {};
|
||||
return type_ == Type::Json ? parse_json(input) : parse_benc(input);
|
||||
}
|
||||
|
||||
|
@ -883,13 +878,13 @@ bool tr_variant_serde::to_file(tr_variant const& var, std::string_view filename)
|
|||
{
|
||||
tr_file_save(filename, to_string(var), &error_);
|
||||
|
||||
if (error_ != nullptr)
|
||||
if (error_)
|
||||
{
|
||||
tr_logAddError(fmt::format(
|
||||
_("Couldn't save '{path}': {error} ({error_code})"),
|
||||
fmt::arg("path", filename),
|
||||
fmt::arg("error", error_->message),
|
||||
fmt::arg("error_code", error_->code)));
|
||||
fmt::arg("error", error_.message()),
|
||||
fmt::arg("error_code", error_.code())));
|
||||
return false;
|
||||
}
|
||||
|
||||
|
|
|
@ -16,11 +16,10 @@
|
|||
#include <variant>
|
||||
#include <vector>
|
||||
|
||||
#include "libtransmission/error.h"
|
||||
#include "libtransmission/quark.h"
|
||||
#include "libtransmission/tr-macros.h" // TR_CONSTEXPR20
|
||||
|
||||
struct tr_error;
|
||||
|
||||
/**
|
||||
* A variant that holds typical benc/json types: bool, int,
|
||||
* double, string, vectors of variants, and maps of variants.
|
||||
|
@ -274,8 +273,8 @@ public:
|
|||
{
|
||||
if constexpr (std::is_same_v<Val, std::string_view>)
|
||||
{
|
||||
auto const* const str = std::get_if<StringHolder>(&val_);
|
||||
return str != nullptr ? &str->sv_ : nullptr;
|
||||
auto const* const val = std::get_if<StringHolder>(&val_);
|
||||
return val != nullptr ? &val->sv_ : nullptr;
|
||||
}
|
||||
else
|
||||
{
|
||||
|
@ -294,8 +293,8 @@ public:
|
|||
{
|
||||
if constexpr (Index == StringIndex)
|
||||
{
|
||||
auto const* const str = std::get_if<StringIndex>(&val_);
|
||||
return str != nullptr ? &str->sv_ : nullptr;
|
||||
auto const* const val = std::get_if<StringIndex>(&val_);
|
||||
return val != nullptr ? &val->sv_ : nullptr;
|
||||
}
|
||||
else
|
||||
{
|
||||
|
@ -468,8 +467,6 @@ void tr_variantMergeDicts(tr_variant* tgt, tr_variant const* src);
|
|||
class tr_variant_serde
|
||||
{
|
||||
public:
|
||||
~tr_variant_serde();
|
||||
|
||||
[[nodiscard]] static tr_variant_serde benc() noexcept
|
||||
{
|
||||
return tr_variant_serde{ Type::Benc };
|
||||
|
@ -523,7 +520,7 @@ public:
|
|||
// ---
|
||||
|
||||
// Tracks errors when parsing / saving
|
||||
tr_error* error_ = nullptr;
|
||||
tr_error error_ = {};
|
||||
|
||||
private:
|
||||
friend tr_variant;
|
||||
|
|
|
@ -44,20 +44,15 @@ namespace
|
|||
{
|
||||
auto const path = tr_pathbuf{ dir, '/', name };
|
||||
|
||||
tr_error* error = nullptr;
|
||||
auto error = tr_error{};
|
||||
auto const info = tr_sys_path_get_info(path, 0, &error);
|
||||
if (error != nullptr)
|
||||
if (error && !TR_ERROR_IS_ENOENT(error.code()))
|
||||
{
|
||||
if (!TR_ERROR_IS_ENOENT(error->code))
|
||||
{
|
||||
tr_logAddWarn(fmt::format(
|
||||
_("Skipping '{path}': {error} ({error_code})"),
|
||||
fmt::arg("path", path),
|
||||
fmt::arg("error", error->message),
|
||||
fmt::arg("error_code", error->code)));
|
||||
}
|
||||
|
||||
tr_error_free(error);
|
||||
tr_logAddWarn(fmt::format(
|
||||
_("Skipping '{path}': {error} ({error_code})"),
|
||||
fmt::arg("path", path),
|
||||
fmt::arg("error", error.message()),
|
||||
fmt::arg("error_code", error.code())));
|
||||
}
|
||||
|
||||
return info && info->isFile();
|
||||
|
@ -110,21 +105,20 @@ void BaseWatchdir::processFile(std::string_view basename)
|
|||
|
||||
void BaseWatchdir::scan()
|
||||
{
|
||||
tr_error* error = nullptr;
|
||||
auto error = tr_error{};
|
||||
|
||||
for (auto const& file : tr_sys_dir_get_files(dirname_, tr_basename_is_not_dotfile, &error))
|
||||
{
|
||||
processFile(file);
|
||||
}
|
||||
|
||||
if (error != nullptr)
|
||||
if (error)
|
||||
{
|
||||
tr_logAddWarn(fmt::format(
|
||||
_("Couldn't read '{path}': {error} ({error_code})"),
|
||||
fmt::arg("path", dirname()),
|
||||
fmt::arg("error", error->message),
|
||||
fmt::arg("error_code", error->code)));
|
||||
tr_error_free(error);
|
||||
fmt::arg("error", error.message()),
|
||||
fmt::arg("error_code", error.code())));
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -44,7 +44,7 @@ typedef NS_ENUM(NSUInteger, TrackerSegmentTag) {
|
|||
|
||||
@property(nonatomic, readonly) std::shared_ptr<tr_metainfo_builder> fBuilder;
|
||||
@property(nonatomic, readonly) NSURL* fPath;
|
||||
@property(nonatomic) std::shared_future<tr_error*> fFuture;
|
||||
@property(nonatomic) std::shared_future<tr_error> fFuture;
|
||||
@property(nonatomic) NSURL* fLocation; // path to new torrent file
|
||||
@property(nonatomic) NSMutableArray<NSString*>* fTrackers;
|
||||
|
||||
|
@ -667,13 +667,13 @@ NSMutableSet* creatorWindowControllerSet = nil;
|
|||
[self.fTimer invalidate];
|
||||
self.fTimer = nil;
|
||||
|
||||
tr_error* error = self.fFuture.get();
|
||||
if (error == nullptr)
|
||||
auto error = self.fFuture.get();
|
||||
if (!error)
|
||||
{
|
||||
self.fBuilder->save(self.fLocation.path.UTF8String, &error);
|
||||
}
|
||||
|
||||
if (error != nullptr)
|
||||
if (error)
|
||||
{
|
||||
auto* const alert = [[NSAlert alloc] init];
|
||||
[alert addButtonWithTitle:NSLocalizedString(@"OK", "Create torrent -> failed -> button")];
|
||||
|
@ -681,11 +681,11 @@ NSMutableSet* creatorWindowControllerSet = nil;
|
|||
self.fLocation.lastPathComponent];
|
||||
alert.alertStyle = NSAlertStyleWarning;
|
||||
|
||||
alert.informativeText = [NSString stringWithFormat:@"%s (%d)", error->message, error->code];
|
||||
alert.informativeText = [NSString
|
||||
stringWithFormat:@"%.*s (%d)", static_cast<int>(std::size(error.message())), std::data(error.message()), error.code()];
|
||||
[alert beginSheetModalForWindow:self.window completionHandler:^(NSModalResponse /*returnCode*/) {
|
||||
[self.window close];
|
||||
}];
|
||||
tr_error_free(error);
|
||||
}
|
||||
else
|
||||
{
|
||||
|
|
|
@ -76,7 +76,7 @@ void renameCallback(tr_torrent* /*torrent*/, char const* oldPathCharString, char
|
|||
}
|
||||
}
|
||||
|
||||
bool trashDataFile(char const* filename, void* /*user_data*/, tr_error** error)
|
||||
bool trashDataFile(char const* filename, void* /*user_data*/, tr_error* error)
|
||||
{
|
||||
if (filename == NULL)
|
||||
{
|
||||
|
@ -88,7 +88,7 @@ bool trashDataFile(char const* filename, void* /*user_data*/, tr_error** error)
|
|||
NSError* localError;
|
||||
if (![Torrent trashFile:@(filename) error:&localError])
|
||||
{
|
||||
tr_error_set(error, localError.code, localError.description.UTF8String);
|
||||
error->set(localError.code, localError.description.UTF8String);
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
|
|
@ -38,7 +38,7 @@ public:
|
|||
MakeProgressDialog(
|
||||
Session& session,
|
||||
tr_metainfo_builder& builder,
|
||||
std::future<tr_error*> future,
|
||||
std::future<tr_error> future,
|
||||
QString outfile,
|
||||
QWidget* parent = nullptr);
|
||||
|
||||
|
@ -49,7 +49,7 @@ private slots:
|
|||
private:
|
||||
Session& session_;
|
||||
tr_metainfo_builder& builder_;
|
||||
std::future<tr_error*> future_;
|
||||
std::future<tr_error> future_;
|
||||
QString const outfile_;
|
||||
Ui::MakeProgressDialog ui_ = {};
|
||||
QTimer timer_;
|
||||
|
@ -60,7 +60,7 @@ private:
|
|||
MakeProgressDialog::MakeProgressDialog(
|
||||
Session& session,
|
||||
tr_metainfo_builder& builder,
|
||||
std::future<tr_error*> future,
|
||||
std::future<tr_error> future,
|
||||
QString outfile,
|
||||
QWidget* parent)
|
||||
: BaseDialog{ parent }
|
||||
|
@ -128,22 +128,22 @@ void MakeProgressDialog::onProgress()
|
|||
}
|
||||
else
|
||||
{
|
||||
tr_error* error = future_.get();
|
||||
auto error = future_.get();
|
||||
|
||||
if (error == nullptr)
|
||||
if (!error)
|
||||
{
|
||||
builder_.save(outfile_.toStdString(), &error);
|
||||
}
|
||||
|
||||
if (error == nullptr)
|
||||
if (!error)
|
||||
{
|
||||
str = tr("Created \"%1\"!").arg(base);
|
||||
success = true;
|
||||
}
|
||||
else
|
||||
{
|
||||
str = tr("Couldn't create \"%1\": %2 (%3)").arg(base).arg(QString::fromUtf8(error->message)).arg(error->code);
|
||||
tr_error_free(error);
|
||||
auto err_msg = QString::fromUtf8(std::data(error.message()), std::size(error.message()));
|
||||
str = tr("Couldn't create \"%1\": %2 (%3)").arg(base).arg(err_msg).arg(error.code());
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -356,11 +356,11 @@ TEST_F(AnnounceListTest, save)
|
|||
auto constexpr* const OriginalFile = LIBTRANSMISSION_TEST_ASSETS_DIR "/Android-x86 8.1 r6 iso.torrent";
|
||||
auto original_content = std::vector<char>{};
|
||||
auto const test_file = tr_pathbuf{ ::testing::TempDir(), "transmission-announce-list-test.torrent"sv };
|
||||
tr_error* error = nullptr;
|
||||
auto error = tr_error{};
|
||||
EXPECT_TRUE(tr_file_read(OriginalFile, original_content, &error));
|
||||
EXPECT_EQ(nullptr, error) << *error;
|
||||
EXPECT_FALSE(error) << error;
|
||||
EXPECT_TRUE(tr_file_save(test_file.sv(), original_content, &error));
|
||||
EXPECT_EQ(nullptr, error) << *error;
|
||||
EXPECT_FALSE(error) << error;
|
||||
|
||||
// make an announce_list for it
|
||||
auto announce_list = tr_announce_list();
|
||||
|
@ -370,13 +370,13 @@ TEST_F(AnnounceListTest, save)
|
|||
|
||||
// try saving to a nonexistent torrent file
|
||||
EXPECT_FALSE(announce_list.save("/this/path/does/not/exist", &error));
|
||||
EXPECT_NE(nullptr, error);
|
||||
EXPECT_NE(0, error->code);
|
||||
tr_error_clear(&error);
|
||||
EXPECT_TRUE(error);
|
||||
EXPECT_NE(0, error.code());
|
||||
error = {};
|
||||
|
||||
// now save to a real torrent file
|
||||
EXPECT_TRUE(announce_list.save(std::string{ test_file.sv() }, &error));
|
||||
EXPECT_EQ(nullptr, error) << *error;
|
||||
EXPECT_FALSE(error) << error;
|
||||
|
||||
// load the original
|
||||
auto original_tm = tr_torrent_metainfo{};
|
||||
|
|
|
@ -26,14 +26,10 @@ TEST_F(BencTest, MalformedBenc)
|
|||
|
||||
auto stack = transmission::benc::ParserStack<MaxBencDepth>{};
|
||||
auto handler = TestHandler{};
|
||||
tr_error* error = nullptr;
|
||||
auto error = tr_error{};
|
||||
EXPECT_FALSE(transmission::benc::parse(Benc, stack, handler, nullptr, &error));
|
||||
EXPECT_NE(nullptr, error);
|
||||
if (error != nullptr)
|
||||
{
|
||||
EXPECT_NE(nullptr, error->message);
|
||||
}
|
||||
tr_error_clear(&error);
|
||||
EXPECT_TRUE(error);
|
||||
EXPECT_NE(""sv, error.message());
|
||||
}
|
||||
|
||||
TEST_F(BencTest, ContextTokenIsCorrect)
|
||||
|
@ -98,6 +94,7 @@ TEST_F(BencTest, ContextTokenIsCorrect)
|
|||
|
||||
auto stack = transmission::benc::ParserStack<MaxBencDepth>{};
|
||||
auto handler = ContextHandler{};
|
||||
tr_error* error = nullptr;
|
||||
auto error = tr_error{};
|
||||
transmission::benc::parse(Benc, stack, handler, nullptr, &error);
|
||||
EXPECT_FALSE(error);
|
||||
}
|
||||
|
|
|
@ -36,11 +36,10 @@ protected:
|
|||
|
||||
auto const path2 = tr_pathbuf{ sandboxDir(), '/', filename2 };
|
||||
|
||||
tr_error* err = nullptr;
|
||||
/* Copy it. */
|
||||
EXPECT_TRUE(tr_sys_path_copy(path1, path2, &err));
|
||||
EXPECT_EQ(nullptr, err) << ' ' << *err;
|
||||
tr_error_clear(&err);
|
||||
auto error = tr_error{};
|
||||
EXPECT_TRUE(tr_sys_path_copy(path1, path2, &error));
|
||||
EXPECT_FALSE(error) << error;
|
||||
|
||||
EXPECT_TRUE(filesAreIdentical(path1, path2));
|
||||
|
||||
|
|
|
@ -15,40 +15,23 @@ using namespace std::literals;
|
|||
|
||||
TEST(Error, errorSet)
|
||||
{
|
||||
tr_error* err = nullptr;
|
||||
auto error = tr_error{};
|
||||
|
||||
tr_error_prefix(&err, "error: ");
|
||||
EXPECT_EQ(nullptr, err) << *err;
|
||||
EXPECT_FALSE(error) << error;
|
||||
EXPECT_FALSE(error.has_value()) << error;
|
||||
error.set(2, "oops"sv);
|
||||
EXPECT_TRUE(error);
|
||||
EXPECT_TRUE(error.has_value()) << error;
|
||||
EXPECT_EQ(2, error.code());
|
||||
EXPECT_EQ("oops"sv, error.message());
|
||||
|
||||
tr_error_set(&err, 2, "oops"sv);
|
||||
EXPECT_NE(nullptr, err);
|
||||
EXPECT_EQ(2, err->code);
|
||||
EXPECT_STREQ("oops", err->message);
|
||||
error.prefix_message("error: ");
|
||||
EXPECT_TRUE(error);
|
||||
EXPECT_TRUE(error.has_value()) << error;
|
||||
EXPECT_EQ(2, error.code());
|
||||
EXPECT_EQ("error: oops"sv, error.message());
|
||||
|
||||
tr_error_prefix(&err, "error: ");
|
||||
EXPECT_NE(nullptr, err);
|
||||
EXPECT_EQ(2, err->code);
|
||||
EXPECT_STREQ("error: oops", err->message);
|
||||
|
||||
tr_error_free(err);
|
||||
}
|
||||
|
||||
TEST(Error, propagate)
|
||||
{
|
||||
tr_error* err = nullptr;
|
||||
tr_error* err2 = nullptr;
|
||||
auto constexpr Code = int{ 1 };
|
||||
|
||||
tr_error_set(&err, Code, "oops"sv);
|
||||
EXPECT_NE(nullptr, err);
|
||||
EXPECT_EQ(Code, err->code);
|
||||
EXPECT_STREQ("oops", err->message);
|
||||
|
||||
tr_error_propagate(&err2, &err);
|
||||
EXPECT_NE(nullptr, err2);
|
||||
EXPECT_EQ(Code, err2->code);
|
||||
EXPECT_STREQ("oops", err2->message);
|
||||
EXPECT_EQ(nullptr, err) << *err;
|
||||
|
||||
tr_error_clear(&err2);
|
||||
error = {};
|
||||
EXPECT_FALSE(error) << error;
|
||||
EXPECT_FALSE(error.has_value()) << error;
|
||||
}
|
||||
|
|
File diff suppressed because it is too large
Load Diff
|
@ -26,8 +26,6 @@
|
|||
#include "gtest/gtest.h"
|
||||
#include "test-fixtures.h"
|
||||
|
||||
struct tr_error;
|
||||
|
||||
using namespace std::literals;
|
||||
|
||||
namespace libtransmission::test
|
||||
|
@ -69,8 +67,8 @@ protected:
|
|||
|
||||
static auto testBuilder(tr_metainfo_builder& builder)
|
||||
{
|
||||
tr_error* error = builder.make_checksums().get();
|
||||
EXPECT_EQ(error, nullptr) << *error;
|
||||
auto error = builder.make_checksums().get();
|
||||
EXPECT_FALSE(error) << error;
|
||||
|
||||
auto metainfo = tr_torrent_metainfo{};
|
||||
EXPECT_TRUE(metainfo.parse_benc(builder.benc()));
|
||||
|
@ -233,7 +231,7 @@ TEST_F(MakemetaTest, announceSingleTracker)
|
|||
builder.set_announce_list(std::move(trackers));
|
||||
|
||||
// generate the torrent and parse it as a variant
|
||||
EXPECT_EQ(nullptr, builder.make_checksums().get());
|
||||
EXPECT_FALSE(builder.make_checksums().get().has_value());
|
||||
auto top = tr_variant_serde::benc().parse(builder.benc());
|
||||
EXPECT_TRUE(top.has_value());
|
||||
|
||||
|
@ -261,7 +259,7 @@ TEST_F(MakemetaTest, announceMultiTracker)
|
|||
builder.set_announce_list(std::move(trackers));
|
||||
|
||||
// generate the torrent and parse it as a variant
|
||||
EXPECT_EQ(nullptr, builder.make_checksums().get());
|
||||
EXPECT_FALSE(builder.make_checksums().get().has_value());
|
||||
auto top = tr_variant_serde::benc().parse(builder.benc());
|
||||
EXPECT_TRUE(top.has_value());
|
||||
|
||||
|
|
|
@ -104,15 +104,14 @@ TEST_F(OpenFilesTest, opensInReadOnlyUnlessWritableIsRequested)
|
|||
createFileWithContents(filename, Contents);
|
||||
|
||||
// cache a file read-only mode
|
||||
tr_error* error = nullptr;
|
||||
auto fd = session_->openFiles().get(0, 0, false, filename, TR_PREALLOCATE_FULL, std::size(Contents));
|
||||
EXPECT_TRUE(fd.has_value());
|
||||
assert(fd.has_value());
|
||||
|
||||
// confirm that writing to it fails
|
||||
auto error = tr_error{};
|
||||
EXPECT_FALSE(tr_sys_file_write(*fd, std::data(Contents), std::size(Contents), nullptr, &error));
|
||||
EXPECT_NE(0, error->code);
|
||||
tr_error_clear(&error);
|
||||
EXPECT_TRUE(error);
|
||||
}
|
||||
|
||||
TEST_F(OpenFilesTest, createsMissingFileIfWriteRequested)
|
||||
|
|
|
@ -14,6 +14,7 @@
|
|||
#include <libtransmission/transmission.h>
|
||||
|
||||
#include <libtransmission/crypto-utils.h>
|
||||
#include <libtransmission/error.h>
|
||||
#include <libtransmission/file.h>
|
||||
#include <libtransmission/resume.h>
|
||||
#include <libtransmission/torrent.h> // tr_isTorrent()
|
||||
|
@ -24,7 +25,6 @@
|
|||
#include "test-fixtures.h"
|
||||
|
||||
struct tr_ctor;
|
||||
struct tr_error;
|
||||
|
||||
using namespace std::literals;
|
||||
|
||||
|
@ -74,9 +74,9 @@ protected:
|
|||
// create the torrent ctor
|
||||
auto const benc = tr_base64_decode(benc_base64);
|
||||
EXPECT_LT(0U, std::size(benc));
|
||||
tr_error* error = nullptr;
|
||||
auto error = tr_error{};
|
||||
EXPECT_TRUE(tr_ctorSetMetainfo(ctor, std::data(benc), std::size(benc), &error));
|
||||
EXPECT_EQ(nullptr, error) << *error;
|
||||
EXPECT_FALSE(error) << error;
|
||||
tr_ctorSetPaused(ctor, TR_FORCE, true);
|
||||
|
||||
// create the torrent
|
||||
|
|
|
@ -86,14 +86,12 @@ TEST_P(SubprocessTest, SpawnAsyncMissingExec)
|
|||
|
||||
auto args = std::array<char const*, 2>{ missing_exe_path.data(), nullptr };
|
||||
|
||||
tr_error* error = nullptr;
|
||||
auto error = tr_error{};
|
||||
auto const ret = tr_spawn_async(std::data(args), {}, {}, &error);
|
||||
EXPECT_FALSE(ret);
|
||||
EXPECT_NE(nullptr, error);
|
||||
EXPECT_NE(0, error->code);
|
||||
EXPECT_NE(nullptr, error->message);
|
||||
|
||||
tr_error_clear(&error);
|
||||
EXPECT_TRUE(error);
|
||||
EXPECT_NE(0, error.code());
|
||||
EXPECT_NE(""sv, error.message());
|
||||
}
|
||||
|
||||
TEST_P(SubprocessTest, SpawnAsyncArgs)
|
||||
|
@ -115,10 +113,10 @@ TEST_P(SubprocessTest, SpawnAsyncArgs)
|
|||
allow_batch_metachars ? test_arg4.data() : nullptr,
|
||||
nullptr };
|
||||
|
||||
tr_error* error = nullptr;
|
||||
auto error = tr_error{};
|
||||
bool const ret = tr_spawn_async(std::data(args), {}, {}, &error);
|
||||
EXPECT_TRUE(ret) << args[0] << ' ' << args[1];
|
||||
EXPECT_EQ(nullptr, error) << *error;
|
||||
EXPECT_FALSE(error) << error;
|
||||
|
||||
waitForFileToBeReadable(result_path);
|
||||
|
||||
|
@ -184,10 +182,10 @@ TEST_P(SubprocessTest, SpawnAsyncEnv)
|
|||
setenv("FOO", "bar", 1 /*true*/); // inherited
|
||||
setenv("ZOO", "tar", 1 /*true*/); // overridden
|
||||
|
||||
tr_error* error = nullptr;
|
||||
auto error = tr_error{};
|
||||
bool const ret = tr_spawn_async(std::data(args), env, {}, &error);
|
||||
EXPECT_TRUE(ret);
|
||||
EXPECT_EQ(nullptr, error) << *error;
|
||||
EXPECT_FALSE(error) << error;
|
||||
|
||||
waitForFileToBeReadable(result_path);
|
||||
|
||||
|
@ -223,10 +221,10 @@ TEST_P(SubprocessTest, SpawnAsyncCwdExplicit)
|
|||
|
||||
auto const args = std::array<char const*, 4>{ self_path_.c_str(), result_path.c_str(), arg_dump_cwd_.c_str(), nullptr };
|
||||
|
||||
tr_error* error = nullptr;
|
||||
auto error = tr_error{};
|
||||
bool const ret = tr_spawn_async(std::data(args), {}, test_dir, &error);
|
||||
EXPECT_TRUE(ret);
|
||||
EXPECT_EQ(nullptr, error) << *error;
|
||||
EXPECT_FALSE(error) << error;
|
||||
|
||||
waitForFileToBeReadable(result_path);
|
||||
|
||||
|
@ -251,10 +249,10 @@ TEST_P(SubprocessTest, SpawnAsyncCwdInherit)
|
|||
|
||||
auto const args = std::array<char const*, 4>{ self_path_.c_str(), result_path.data(), arg_dump_cwd_.data(), nullptr };
|
||||
|
||||
tr_error* error = nullptr;
|
||||
auto error = tr_error{};
|
||||
auto const ret = tr_spawn_async(std::data(args), {}, {}, &error);
|
||||
EXPECT_TRUE(ret);
|
||||
EXPECT_EQ(nullptr, error) << *error;
|
||||
EXPECT_FALSE(error) << error;
|
||||
|
||||
waitForFileToBeReadable(result_path);
|
||||
|
||||
|
@ -276,13 +274,12 @@ TEST_P(SubprocessTest, SpawnAsyncCwdMissing)
|
|||
|
||||
auto const args = std::array<char const*, 4>{ self_path_.c_str(), result_path.data(), arg_dump_cwd_.data(), nullptr };
|
||||
|
||||
tr_error* error = nullptr;
|
||||
auto error = tr_error{};
|
||||
auto const ret = tr_spawn_async(std::data(args), {}, TR_IF_WIN32("C:\\", "/") "tr-missing-test-work-dir", &error);
|
||||
EXPECT_FALSE(ret);
|
||||
EXPECT_NE(nullptr, error);
|
||||
EXPECT_NE(0, error->code);
|
||||
EXPECT_NE(nullptr, error->message);
|
||||
tr_error_clear(&error);
|
||||
EXPECT_TRUE(error);
|
||||
EXPECT_NE(0, error.code());
|
||||
EXPECT_NE(""sv, error.message());
|
||||
}
|
||||
|
||||
INSTANTIATE_TEST_SUITE_P(
|
||||
|
|
|
@ -33,7 +33,7 @@ using namespace std::literals;
|
|||
|
||||
inline std::ostream& operator<<(std::ostream& os, tr_error const& err)
|
||||
{
|
||||
os << err.message << ' ' << err.code;
|
||||
os << err.message() << ' ' << err.code();
|
||||
return os;
|
||||
}
|
||||
|
||||
|
@ -148,13 +148,8 @@ protected:
|
|||
return path;
|
||||
}
|
||||
|
||||
tr_error* error = nullptr;
|
||||
auto path = tr_sys_dir_get_current(&error);
|
||||
if (error != nullptr)
|
||||
{
|
||||
tr_error_free(error);
|
||||
}
|
||||
return path;
|
||||
auto error = tr_error{};
|
||||
return tr_sys_dir_get_current(&error);
|
||||
}
|
||||
|
||||
static std::string create_sandbox(std::string const& parent_dir, std::string const& tmpl)
|
||||
|
@ -210,29 +205,30 @@ protected:
|
|||
dir.popdir();
|
||||
if (auto const info = tr_sys_path_get_info(path); !info)
|
||||
{
|
||||
tr_error* error = nullptr;
|
||||
auto error = tr_error{};
|
||||
tr_sys_dir_create(dir, TR_SYS_DIR_CREATE_PARENTS, 0700, &error);
|
||||
EXPECT_EQ(nullptr, error) << "path[" << path << "] dir[" << dir << "] " << *error;
|
||||
tr_error_clear(&error);
|
||||
EXPECT_FALSE(error) << "path[" << path << "] dir[" << dir << "] " << error;
|
||||
}
|
||||
|
||||
errno = tmperr;
|
||||
}
|
||||
|
||||
static void blockingFileWrite(tr_sys_file_t fd, void const* data, size_t data_len, tr_error** error = nullptr)
|
||||
static void blockingFileWrite(tr_sys_file_t fd, void const* data, size_t data_len, tr_error* error = nullptr)
|
||||
{
|
||||
auto local_error = tr_error{};
|
||||
if (error == nullptr)
|
||||
{
|
||||
error = &local_error;
|
||||
}
|
||||
|
||||
uint64_t n_left = data_len;
|
||||
auto const* left = static_cast<uint8_t const*>(data);
|
||||
|
||||
while (n_left > 0)
|
||||
{
|
||||
uint64_t n = {};
|
||||
tr_error* local_error = nullptr;
|
||||
if (!tr_sys_file_write(fd, left, n_left, &n, &local_error))
|
||||
if (!tr_sys_file_write(fd, left, n_left, &n, error))
|
||||
{
|
||||
fprintf(stderr, "Error writing file: '%s'\n", local_error->message);
|
||||
tr_error_propagate(error, &local_error);
|
||||
tr_error_free(local_error);
|
||||
fmt::print(stderr, "Error writing file: '{:s}'\n", error->message());
|
||||
break;
|
||||
}
|
||||
|
||||
|
@ -247,20 +243,19 @@ protected:
|
|||
|
||||
buildParentDir(tmpl);
|
||||
|
||||
tr_error* error = nullptr;
|
||||
auto error = tr_error{};
|
||||
auto const fd = tr_sys_file_open_temp(tmpl, &error);
|
||||
blockingFileWrite(fd, payload, n, &error);
|
||||
tr_sys_file_flush(fd, &error);
|
||||
tr_sys_file_flush(fd, &error);
|
||||
tr_sys_file_close(fd, &error);
|
||||
if (error != nullptr)
|
||||
if (error)
|
||||
{
|
||||
fmt::print(
|
||||
"Couldn't create '{path}': {error} ({error_code})\n",
|
||||
fmt::arg("path", tmpl),
|
||||
fmt::arg("error", error->message),
|
||||
fmt::arg("error_code", error->code));
|
||||
tr_error_free(error);
|
||||
fmt::arg("error", error.message()),
|
||||
fmt::arg("error_code", error.code()));
|
||||
}
|
||||
sync();
|
||||
|
||||
|
@ -401,7 +396,7 @@ protected:
|
|||
ctor,
|
||||
[this](tr_torrent* const tor)
|
||||
{
|
||||
auto verified_lock = std::lock_guard{ verified_mutex_ };
|
||||
auto lambda_verified_lock = std::lock_guard{ verified_mutex_ };
|
||||
verified_.emplace_back(tor);
|
||||
verified_cv_.notify_one();
|
||||
});
|
||||
|
@ -446,9 +441,9 @@ protected:
|
|||
auto const benc = tr_base64_decode(benc_base64);
|
||||
EXPECT_LT(0U, std::size(benc));
|
||||
auto* ctor = tr_ctorNew(session_);
|
||||
tr_error* error = nullptr;
|
||||
auto error = tr_error{};
|
||||
EXPECT_TRUE(tr_ctorSetMetainfo(ctor, std::data(benc), std::size(benc), &error));
|
||||
EXPECT_EQ(nullptr, error) << *error;
|
||||
EXPECT_FALSE(error) << error;
|
||||
tr_ctorSetPaused(ctor, TR_FORCE, true);
|
||||
|
||||
// maybe create the files
|
||||
|
|
|
@ -43,10 +43,9 @@ TEST_F(TorrentMagnetTest, getMetadataPiece)
|
|||
EXPECT_EQ(tor->info_dict_size(), info_dict_size);
|
||||
|
||||
auto torrent_metainfo = tr_torrent_metainfo{};
|
||||
tr_error* error = nullptr;
|
||||
auto error = tr_error{};
|
||||
EXPECT_TRUE(torrent_metainfo.parse_benc(benc, &error));
|
||||
EXPECT_EQ(nullptr, error) << error->message;
|
||||
tr_error_clear(&error);
|
||||
EXPECT_FALSE(error) << error.message();
|
||||
|
||||
EXPECT_EQ(tor->piece_hash(0), torrent_metainfo.piece_hash(0));
|
||||
}
|
||||
|
|
|
@ -178,9 +178,9 @@ TEST_F(TorrentMetainfoTest, AndroidTorrent)
|
|||
auto const filename = tr_pathbuf{ LIBTRANSMISSION_TEST_ASSETS_DIR, "/Android-x86 8.1 r6 iso.torrent"sv };
|
||||
|
||||
auto* ctor = tr_ctorNew(session_);
|
||||
tr_error* error = nullptr;
|
||||
auto error = tr_error{};
|
||||
EXPECT_TRUE(tr_ctorSetMetainfoFromFile(ctor, filename.c_str(), &error));
|
||||
EXPECT_EQ(nullptr, error) << *error;
|
||||
EXPECT_FALSE(error) << error;
|
||||
auto const* const metainfo = tr_ctorGetMetainfo(ctor);
|
||||
EXPECT_NE(nullptr, metainfo);
|
||||
EXPECT_EQ(336, metainfo->info_dict_offset());
|
||||
|
@ -196,20 +196,17 @@ TEST_F(TorrentMetainfoTest, ctorSaveContents)
|
|||
|
||||
// try saving without passing any metainfo.
|
||||
auto* ctor = tr_ctorNew(session_);
|
||||
tr_error* error = nullptr;
|
||||
auto error = tr_error{};
|
||||
EXPECT_FALSE(tr_ctorSaveContents(ctor, tgt_filename.sv(), &error));
|
||||
EXPECT_NE(nullptr, error);
|
||||
if (error != nullptr)
|
||||
{
|
||||
EXPECT_EQ(EINVAL, error->code);
|
||||
tr_error_clear(&error);
|
||||
}
|
||||
EXPECT_TRUE(error);
|
||||
EXPECT_EQ(EINVAL, error.code());
|
||||
error = {};
|
||||
|
||||
// now try saving _with_ metainfo
|
||||
EXPECT_TRUE(tr_ctorSetMetainfoFromFile(ctor, src_filename.c_str(), &error));
|
||||
EXPECT_EQ(nullptr, error) << *error;
|
||||
EXPECT_FALSE(error) << error;
|
||||
EXPECT_TRUE(tr_ctorSaveContents(ctor, tgt_filename.sv(), &error));
|
||||
EXPECT_EQ(nullptr, error) << *error;
|
||||
EXPECT_FALSE(error) << error;
|
||||
|
||||
// the saved contents should match the source file's contents
|
||||
auto src_contents = std::vector<char>{};
|
||||
|
@ -220,8 +217,7 @@ TEST_F(TorrentMetainfoTest, ctorSaveContents)
|
|||
|
||||
// cleanup
|
||||
EXPECT_TRUE(tr_sys_path_remove(tgt_filename, &error));
|
||||
EXPECT_EQ(nullptr, error) << *error;
|
||||
tr_error_clear(&error);
|
||||
EXPECT_FALSE(error) << error;
|
||||
tr_ctorFree(ctor);
|
||||
}
|
||||
|
||||
|
|
|
@ -319,27 +319,26 @@ TEST_F(UtilsTest, saveFile)
|
|||
// save a file to GoogleTest's temp dir
|
||||
filename.assign(::testing::TempDir(), "filename.txt"sv);
|
||||
auto contents = "these are the contents"sv;
|
||||
tr_error* error = nullptr;
|
||||
auto error = tr_error{};
|
||||
EXPECT_TRUE(tr_file_save(filename.sv(), contents, &error));
|
||||
EXPECT_EQ(nullptr, error) << *error;
|
||||
EXPECT_FALSE(error) << error;
|
||||
|
||||
// now read the file back in and confirm the contents are the same
|
||||
auto buf = std::vector<char>{};
|
||||
EXPECT_TRUE(tr_file_read(filename.sv(), buf, &error));
|
||||
EXPECT_EQ(nullptr, error) << *error;
|
||||
EXPECT_FALSE(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, &error));
|
||||
EXPECT_EQ(nullptr, error) << *error;
|
||||
EXPECT_FALSE(error) << error;
|
||||
|
||||
// try saving a file to a path that doesn't exist
|
||||
filename = "/this/path/does/not/exist/foo.txt";
|
||||
EXPECT_FALSE(tr_file_save(filename.sv(), contents, &error));
|
||||
ASSERT_NE(nullptr, error);
|
||||
EXPECT_NE(0, error->code);
|
||||
tr_error_clear(&error);
|
||||
ASSERT_TRUE(error);
|
||||
EXPECT_NE(0, error.code());
|
||||
}
|
||||
|
||||
TEST_F(UtilsTest, ratioToString)
|
||||
|
|
|
@ -420,8 +420,8 @@ TEST_F(VariantTest, stackSmash)
|
|||
auto serde = tr_variant_serde::benc();
|
||||
auto var = serde.inplace().parse(in);
|
||||
EXPECT_FALSE(var.has_value());
|
||||
EXPECT_NE(nullptr, serde.error_);
|
||||
EXPECT_EQ(E2BIG, serde.error_ != nullptr ? serde.error_->code : 0);
|
||||
EXPECT_TRUE(serde.error_);
|
||||
EXPECT_EQ(E2BIG, serde.error_.code());
|
||||
}
|
||||
|
||||
TEST_F(VariantTest, boolAndIntRecast)
|
||||
|
|
|
@ -132,19 +132,6 @@ int parseCommandLine(app_options& options, int argc, char const* const* argv)
|
|||
|
||||
return 0;
|
||||
}
|
||||
|
||||
std::string tr_getcwd()
|
||||
{
|
||||
tr_error* error = nullptr;
|
||||
auto cur = tr_sys_dir_get_current(&error);
|
||||
if (error != nullptr)
|
||||
{
|
||||
fprintf(stderr, "getcwd error: \"%s\"", error->message);
|
||||
tr_error_free(error);
|
||||
}
|
||||
return cur;
|
||||
}
|
||||
|
||||
} // namespace
|
||||
|
||||
int tr_main(int argc, char* argv[])
|
||||
|
@ -178,16 +165,32 @@ int tr_main(int argc, char* argv[])
|
|||
|
||||
if (std::empty(options.outfile))
|
||||
{
|
||||
tr_error* error = nullptr;
|
||||
auto error = tr_error{};
|
||||
auto const base = tr_sys_path_basename(options.infile, &error);
|
||||
|
||||
if (std::empty(base))
|
||||
if (error)
|
||||
{
|
||||
fprintf(stderr, "ERROR: Cannot deduce output path from input path: %s\n", error->message);
|
||||
auto const errmsg = fmt::format(
|
||||
"Couldn't use '{path}': {error} ({error_code})",
|
||||
fmt::arg("path", options.infile),
|
||||
fmt::arg("error", error.message()),
|
||||
fmt::arg("error_code", error.code()));
|
||||
fmt::print(stderr, "{:s}\n", errmsg);
|
||||
return EXIT_FAILURE;
|
||||
}
|
||||
|
||||
options.outfile = fmt::format("{:s}/{:s}.torrent"sv, tr_getcwd(), base);
|
||||
auto const cur = tr_sys_dir_get_current(&error);
|
||||
if (error)
|
||||
{
|
||||
auto const errmsg = fmt::format(
|
||||
"Couldn't create '{path}': {error} ({error_code})",
|
||||
fmt::arg("path", base),
|
||||
fmt::arg("error", error.message()),
|
||||
fmt::arg("error_code", error.code()));
|
||||
fmt::print(stderr, "{:s}\n", errmsg);
|
||||
return EXIT_FAILURE;
|
||||
}
|
||||
|
||||
options.outfile = fmt::format("{:s}/{:s}.torrent"sv, cur, base);
|
||||
}
|
||||
|
||||
if (std::empty(options.trackers))
|
||||
|
@ -274,17 +277,20 @@ int tr_main(int argc, char* argv[])
|
|||
|
||||
fmt::print(" ");
|
||||
|
||||
if (tr_error* error = future.get(); error != nullptr)
|
||||
if (auto error = future.get(); error)
|
||||
{
|
||||
fmt::print("ERROR: {:s} {:d}\n", error->message, error->code);
|
||||
tr_error_free(error);
|
||||
fmt::print("ERROR: {:s} {:d}\n", error.message(), error.code());
|
||||
return EXIT_FAILURE;
|
||||
}
|
||||
|
||||
if (tr_error* error = nullptr; !builder.save(options.outfile, &error))
|
||||
if (auto error = tr_error{}; !builder.save(options.outfile, &error))
|
||||
{
|
||||
fmt::print("ERROR: could not save \"{:s}\": {:s} {:d}\n", options.outfile, error->message, error->code);
|
||||
tr_error_free(error);
|
||||
auto const errmsg = fmt::format(
|
||||
"Couldn't save '{path}': {error} ({error_code})",
|
||||
fmt::arg("path", options.outfile),
|
||||
fmt::arg("error", error.message()),
|
||||
fmt::arg("error_code", error.code()));
|
||||
fmt::print(stderr, "{:s}\n", errmsg);
|
||||
return EXIT_FAILURE;
|
||||
}
|
||||
|
||||
|
|
|
@ -366,7 +366,7 @@ int tr_main(int argc, char* argv[])
|
|||
auto otop = serde.parse_file(filename);
|
||||
if (!otop)
|
||||
{
|
||||
fmt::print("\tError reading file: {:s}\n", serde.error_->message);
|
||||
fmt::print("\tError reading file: {:s}\n", serde.error_.message());
|
||||
continue;
|
||||
}
|
||||
auto& top = *otop;
|
||||
|
|
|
@ -436,12 +436,11 @@ int tr_main(int argc, char* argv[])
|
|||
|
||||
/* try to parse the torrent file */
|
||||
auto metainfo = tr_torrent_metainfo{};
|
||||
tr_error* error = nullptr;
|
||||
auto error = tr_error{};
|
||||
auto const parsed = metainfo.parse_torrent_file(opts.filename, nullptr, &error);
|
||||
if (error != nullptr)
|
||||
if (error)
|
||||
{
|
||||
fmt::print(stderr, "Error parsing torrent file '{:s}': {:s} ({:d})\n", opts.filename, error->message, error->code);
|
||||
tr_error_clear(&error);
|
||||
fmt::print(stderr, "Error parsing torrent file '{:s}': {:s} ({:d})\n", opts.filename, error.message(), error.code());
|
||||
}
|
||||
if (!parsed)
|
||||
{
|
||||
|
|
Loading…
Reference in New Issue
Block a user