diff --git a/libtransmission/announcer-udp.cc b/libtransmission/announcer-udp.cc index 79118c16d..b1ffef8d5 100644 --- a/libtransmission/announcer-udp.cc +++ b/libtransmission/announcer-udp.cc @@ -374,6 +374,12 @@ struct tau_tracker void sendto(void const* buf, size_t buflen) { + TR_ASSERT(addr_); + if (!addr_) + { + return; + } + auto [ss, sslen] = *addr_; if (ss.ss_family == AF_INET) diff --git a/libtransmission/blocklist.cc b/libtransmission/blocklist.cc index 1fc51bc81..f80ef4cec 100644 --- a/libtransmission/blocklist.cc +++ b/libtransmission/blocklist.cc @@ -250,11 +250,11 @@ auto parseFile(std::string_view filename) } // safeguard against some joker swapping the begin & end ranges - for (auto& range : ranges) + for (auto& [low, high] : ranges) { - if (range.first > range.second) + if (low > high) { - std::swap(range.first, range.second); + std::swap(low, high); } } @@ -279,9 +279,9 @@ auto parseFile(std::string_view filename) ranges.resize(keep + 1); #ifdef TR_ENABLE_ASSERTS - for (auto const& range : ranges) + for (auto const& [low, high] : ranges) { - TR_ASSERT(range.first <= range.second); + TR_ASSERT(low <= high); } for (size_t i = 1, n = std::size(ranges); i < n; ++i) { @@ -336,6 +336,9 @@ void Blocklist::ensureLoaded() const fmt::arg("error", error->message), fmt::arg("error_code", error->code))); tr_error_clear(&error); + } + if (!file_info) + { return; } @@ -372,8 +375,8 @@ void Blocklist::ensureLoaded() const { // bad binary file; try to rebuild it in.close(); - auto const sz_src_file = std::string{ std::data(bin_file_), std::size(bin_file_) - std::size(BinFileSuffix) }; - if (tr_sys_path_exists(sz_src_file)) + if (auto const sz_src_file = std::string{ std::data(bin_file_), std::size(bin_file_) - std::size(BinFileSuffix) }; + tr_sys_path_exists(sz_src_file)) { rules_ = parseFile(sz_src_file); if (!std::empty(rules_)) @@ -387,7 +390,7 @@ void Blocklist::ensureLoaded() const } auto range = address_range_t{}; - rules_.reserve((file_info->size - std::size(BinContentsPrefix) / sizeof(address_range_t))); + rules_.reserve(file_info->size - std::size(BinContentsPrefix) / sizeof(address_range_t)); while (in.read(reinterpret_cast(&range), sizeof(range))) { rules_.emplace_back(range); @@ -492,17 +495,18 @@ std::optional Blocklist::saveNew(std::string_view external_file, std: 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; - if (!tr_sys_path_copy(tr_pathbuf{ external_file }, src_file.c_str(), &error)) + auto const copied = tr_sys_path_copy(tr_pathbuf{ external_file }, src_file.c_str(), &error); + if (error != nullptr) + { + 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); + } + if (!copied) { - if (error != nullptr) - { - 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); - } return {}; } diff --git a/libtransmission/handshake.cc b/libtransmission/handshake.cc index f959b1b0a..24ab2fc7e 100644 --- a/libtransmission/handshake.cc +++ b/libtransmission/handshake.cc @@ -219,8 +219,10 @@ static void setReadState(tr_handshake* handshake, handshake_state_t state) static bool buildHandshakeMessage(tr_handshake const* const handshake, uint8_t* buf) { - auto const info_hash = handshake->io->torrentHash(); - auto const info = info_hash ? handshake->mediator->torrentInfo(*info_hash) : std::nullopt; + auto const& info_hash = handshake->io->torrentHash(); + TR_ASSERT_MSG(info_hash != tr_sha1_digest_t{}, "buildHandshakeMessage requires an info_hash"); + + auto const info = handshake->mediator->torrentInfo(info_hash); if (!info) { return false; @@ -242,7 +244,7 @@ static bool buildHandshakeMessage(tr_handshake const* const handshake, uint8_t* } walk += HandshakeFlagsLen; - walk = std::copy_n(reinterpret_cast(std::data(*info_hash)), std::size(*info_hash), walk); + walk = std::copy_n(reinterpret_cast(std::data(info_hash)), std::size(info_hash), walk); [[maybe_unused]] auto const* const walk_end = std::copy( std::begin(info->client_peer_id), std::end(info->client_peer_id), @@ -283,10 +285,10 @@ static handshake_parse_err_t parseHandshake(tr_handshake* handshake, tr_peerIo* auto reserved = std::array{}; peer_io->readBytes(std::data(reserved), std::size(reserved)); - /* torrent hash */ - auto hash = tr_sha1_digest_t{}; - peer_io->readBytes(std::data(hash), std::size(hash)); - if (auto const torrent_hash = peer_io->torrentHash(); !torrent_hash || *torrent_hash != hash) + // torrent hash + auto info_hash = tr_sha1_digest_t{}; + peer_io->readBytes(std::data(info_hash), std::size(info_hash)); + if (info_hash == tr_sha1_digest_t{} || info_hash != peer_io->torrentHash()) { tr_logAddTraceHand(handshake, "peer returned the wrong hash. wtf?"); return HANDSHAKE_BAD_TORRENT; @@ -301,7 +303,7 @@ static handshake_parse_err_t parseHandshake(tr_handshake* handshake, tr_peerIo* auto const peer_id_sv = std::string_view{ std::data(peer_id), std::size(peer_id) }; tr_logAddTraceHand(handshake, fmt::format("peer-id is '{}'", peer_id_sv)); - if (auto const info = handshake->mediator->torrentInfo(hash); info && info->client_peer_id == peer_id) + if (auto const info = handshake->mediator->torrentInfo(info_hash); info && info->client_peer_id == peer_id) { tr_logAddTraceHand(handshake, "streuth! we've connected to ourselves."); return HANDSHAKE_PEER_IS_SELF; @@ -411,16 +413,12 @@ static ReadState readYb(tr_handshake* handshake, tr_peerIo* peer_io) /* HASH('req1', S) */ outbuf.add(tr_sha1::digest("req1"sv, handshake->dh.secret())); - auto const info_hash = peer_io->torrentHash(); - if (!info_hash) - { - tr_logAddTraceHand(handshake, "error while computing req2/req3 hash after Yb"); - return tr_handshakeDone(handshake, false); - } + auto const& info_hash = peer_io->torrentHash(); + TR_ASSERT_MSG(info_hash != tr_sha1_digest_t{}, "readYb requires an info_hash"); /* HASH('req2', SKEY) xor HASH('req3', S) */ { - auto const req2 = tr_sha1::digest("req2"sv, *info_hash); + auto const req2 = tr_sha1::digest("req2"sv, info_hash); auto const req3 = tr_sha1::digest("req3"sv, handshake->dh.secret()); auto x_or = tr_sha1_digest_t{}; for (size_t i = 0, n = std::size(x_or); i < n; ++i) @@ -435,7 +433,7 @@ static ReadState readYb(tr_handshake* handshake, tr_peerIo* peer_io) * PadC is reserved for future extensions to the handshake... * standard practice at this time is for it to be zero-length */ peer_io->write(outbuf, false); - peer_io->encryptInit(peer_io->isIncoming(), handshake->dh, *info_hash); + peer_io->encryptInit(peer_io->isIncoming(), handshake->dh, info_hash); outbuf.add(VC); outbuf.addUint32(handshake->cryptoProvide()); outbuf.addUint16(0); @@ -462,10 +460,13 @@ static ReadState readYb(tr_handshake* handshake, tr_peerIo* peer_io) // A will be able to resynchronize on ENCRYPT(VC)" static ReadState readVC(tr_handshake* handshake, tr_peerIo* peer_io) { + auto const info_hash = peer_io->torrentHash(); + TR_ASSERT_MSG(info_hash != tr_sha1_digest_t{}, "readVC requires an info_hash"); + // find the end of PadB by looking for `ENCRYPT(VC)` auto needle = VC; auto filter = tr_message_stream_encryption::Filter{}; - filter.encryptInit(true, handshake->dh, *peer_io->torrentHash()); + filter.encryptInit(true, handshake->dh, info_hash); filter.encrypt(std::size(needle), std::data(needle)); for (size_t i = 0; i < PadbMaxlen; ++i) @@ -481,7 +482,7 @@ static ReadState readVC(tr_handshake* handshake, tr_peerIo* peer_io) tr_logAddTraceHand(handshake, "got it!"); // We already know it's a match; now we just need to // consume it from the read buffer. - peer_io->decryptInit(peer_io->isIncoming(), handshake->dh, *peer_io->torrentHash()); + peer_io->decryptInit(peer_io->isIncoming(), handshake->dh, info_hash); peer_io->readBytes(std::data(needle), std::size(needle)); setState(handshake, AWAITING_CRYPTO_SELECT); return READ_NOW; @@ -615,11 +616,9 @@ static ReadState readHandshake(tr_handshake* handshake, tr_peerIo* peer_io) peer_io->setTorrentHash(hash); } - else /* outgoing */ + else // outgoing { - auto const torrent_hash = peer_io->torrentHash(); - - if (!torrent_hash || *torrent_hash != hash) + if (peer_io->torrentHash() != hash) { tr_logAddTraceHand(handshake, "peer returned the wrong hash. wtf?"); return tr_handshakeDone(handshake, false); @@ -665,8 +664,8 @@ static ReadState readPeerId(tr_handshake* handshake, tr_peerIo* peer_io) fmt::format("peer-id is '{}' ... isIncoming is {}", std::data(client), handshake->isIncoming())); // if we've somehow connected to ourselves, don't keep the connection - auto const hash = peer_io->torrentHash(); - auto const info = hash ? handshake->mediator->torrentInfo(*hash) : std::nullopt; + auto const info_hash = peer_io->torrentHash(); + auto const info = handshake->mediator->torrentInfo(info_hash); auto const connected_to_self = info && info->client_peer_id == peer_id; return tr_handshakeDone(handshake, !connected_to_self); @@ -773,7 +772,9 @@ static ReadState readCryptoProvide(tr_handshake* handshake, tr_peerIo* peer_io) /* next part: ENCRYPT(VC, crypto_provide, len(PadC), */ - peer_io->decryptInit(peer_io->isIncoming(), handshake->dh, *peer_io->torrentHash()); + auto const& info_hash = peer_io->torrentHash(); + TR_ASSERT_MSG(info_hash != tr_sha1_digest_t{}, "readCryptoProvide requires an info_hash"); + peer_io->decryptInit(peer_io->isIncoming(), handshake->dh, info_hash); auto vc_in = vc_t{}; peer_io->readBytes(std::data(vc_in), std::size(vc_in)); @@ -830,7 +831,9 @@ static ReadState readIA(tr_handshake* handshake, tr_peerIo* peer_io) *** B->A: ENCRYPT(VC, crypto_select, len(padD), padD), ENCRYPT2(Payload Stream) **/ - peer_io->encryptInit(peer_io->isIncoming(), handshake->dh, *peer_io->torrentHash()); + auto const& info_hash = peer_io->torrentHash(); + TR_ASSERT_MSG(info_hash != tr_sha1_digest_t{}, "readIA requires an info_hash"); + peer_io->encryptInit(peer_io->isIncoming(), handshake->dh, info_hash); auto outbuf = libtransmission::Buffer{}; // send VC @@ -1054,13 +1057,13 @@ static void gotError(tr_peerIo* io, short what, void* vhandshake) { // the peer probably doesn't speak µTP. - auto const hash = io->torrentHash(); - auto const info = hash ? handshake->mediator->torrentInfo(*hash) : std::nullopt; + auto const info_hash = io->torrentHash(); + auto const info = handshake->mediator->torrentInfo(info_hash); /* Don't mark a peer as non-µTP unless it's really a connect failure. */ if ((errcode == ETIMEDOUT || errcode == ECONNREFUSED) && info) { - handshake->mediator->setUTPFailed(*hash, io->address()); + handshake->mediator->setUTPFailed(info_hash, io->address()); } if (handshake->mediator->allowsTCP() && handshake->io->reconnect() == 0) diff --git a/libtransmission/peer-io.cc b/libtransmission/peer-io.cc index 62a267efa..ab6b9ad47 100644 --- a/libtransmission/peer-io.cc +++ b/libtransmission/peer-io.cc @@ -301,7 +301,7 @@ static void event_write_cb(evutil_socket_t fd, short /*event*/, void* vio) } else { - auto const what = BEV_EVENT_WRITING | (n_written == 0 ? BEV_EVENT_EOF : BEV_EVENT_ERROR); + auto const what = BEV_EVENT_WRITING | (error != nullptr ? BEV_EVENT_ERROR : BEV_EVENT_EOF); tr_logAddDebugIo( io, diff --git a/libtransmission/peer-io.h b/libtransmission/peer-io.h index be9be9bcf..f11b42d3b 100644 --- a/libtransmission/peer-io.h +++ b/libtransmission/peer-io.h @@ -18,7 +18,6 @@ #include #include #include -#include #include #include // std::make_pair @@ -308,15 +307,12 @@ private: : session{ session_in } , time_created{ current_time } , bandwidth_{ parent_bandwidth } + , torrent_hash_{ torrent_hash != nullptr ? *torrent_hash : tr_sha1_digest_t{} } , addr_{ addr } , port_{ port } , is_seed_{ is_seed } , is_incoming_{ is_incoming } { - if (torrent_hash != nullptr) - { - torrent_hash_ = *torrent_hash; - } } Filter& filter() @@ -333,7 +329,7 @@ private: std::unique_ptr filter_; - std::optional torrent_hash_; + tr_sha1_digest_t torrent_hash_; tr_address const addr_; tr_port const port_; diff --git a/libtransmission/peer-mgr.cc b/libtransmission/peer-mgr.cc index a77a4366d..7e17a13cc 100644 --- a/libtransmission/peer-mgr.cc +++ b/libtransmission/peer-mgr.cc @@ -1142,8 +1142,7 @@ static bool on_handshake_done(tr_handshake_result const& result) bool success = false; auto* manager = static_cast(result.userData); - auto const hash = result.io->torrentHash(); - tr_swarm* const s = hash ? getExistingSwarm(manager, *hash) : nullptr; + tr_swarm* const s = getExistingSwarm(manager, result.io->torrentHash()); auto const [addr, port] = result.io->socketAddress(); diff --git a/libtransmission/session-thread.cc b/libtransmission/session-thread.cc index bcd2792c8..53cd0fb5e 100644 --- a/libtransmission/session-thread.cc +++ b/libtransmission/session-thread.cc @@ -110,8 +110,6 @@ unsigned long thread_current_id() return std::hash()(std::this_thread::get_id()); } -auto evthread_flag = std::once_flag{}; - void initEvthreadsOnce() { tr_net_init(); @@ -147,6 +145,8 @@ auto makeEventBase() void tr_session_thread::tr_evthread_init() { using namespace tr_evthread_init_helpers; + + static auto evthread_flag = std::once_flag{}; std::call_once(evthread_flag, initEvthreadsOnce); } diff --git a/libtransmission/session.cc b/libtransmission/session.cc index 33bb27939..c4ac33db9 100644 --- a/libtransmission/session.cc +++ b/libtransmission/session.cc @@ -593,7 +593,7 @@ void tr_session::setSettings(tr_variant* settings_dict, bool force) rpc_server_->load(settings_dict); } -void tr_session::setSettings(tr_session_settings settings_in, bool force) +void tr_session::setSettings(tr_session_settings&& settings_in, bool force) { auto const lock = unique_lock(); @@ -1317,10 +1317,8 @@ static void sessionLoadTorrents(tr_session* session, tr_ctor* ctor, std::promise continue; } - auto const path = tr_pathbuf{ dirname, '/', name }; - // is a magnet link? - if (!tr_ctorSetMetainfoFromFile(ctor, path.sv(), nullptr)) + if (auto const path = tr_pathbuf{ dirname, '/', name }; !tr_ctorSetMetainfoFromFile(ctor, path.sv(), nullptr)) { if (auto buf = std::vector{}; tr_loadFile(path, buf)) { @@ -1328,7 +1326,7 @@ static void sessionLoadTorrents(tr_session* session, tr_ctor* ctor, std::promise } } - if (tr_torrent* const tor = tr_torrentNew(ctor, nullptr); tor != nullptr) + if (tr_torrentNew(ctor, nullptr) != nullptr) { ++n_torrents; } diff --git a/libtransmission/session.h b/libtransmission/session.h index 3094a1f48..813a5fcb5 100644 --- a/libtransmission/session.h +++ b/libtransmission/session.h @@ -323,7 +323,7 @@ public: return *timer_maker_; } - [[nodiscard]] auto amInSessionThread() noexcept + [[nodiscard]] auto amInSessionThread() const noexcept { return session_thread_->amInSessionThread(); } @@ -870,7 +870,7 @@ public: } } - void fetch(tr_web::FetchOptions options) const + void fetch(tr_web::FetchOptions&& options) const { web_->fetch(std::move(options)); } @@ -930,7 +930,7 @@ private: struct init_data; void initImpl(init_data&); void setSettings(tr_variant* settings_dict, bool force); - void setSettings(tr_session_settings settings, bool force); + void setSettings(tr_session_settings&& settings, bool force); void closeImplPart1(std::promise* closed_promise); void closeImplPart2(std::promise* closed_promise); diff --git a/libtransmission/utils-ev.h b/libtransmission/utils-ev.h index 495b703ba..41c9cbb80 100644 --- a/libtransmission/utils-ev.h +++ b/libtransmission/utils-ev.h @@ -45,7 +45,7 @@ using evbase_unique_ptr = std::unique_ptr; struct EventDeleter { - void operator()(struct event* event) + void operator()(struct event* event) const { if (event != nullptr) { diff --git a/libtransmission/utils.cc b/libtransmission/utils.cc index d30cc3ec6..84087f1d2 100644 --- a/libtransmission/utils.cc +++ b/libtransmission/utils.cc @@ -616,7 +616,12 @@ double tr_truncd(double x, int decimal_places) pt[decimal_places != 0 ? decimal_places + 1 : 0] = '\0'; } - return *tr_parseNum(std::data(buf)); + if (auto parsed = tr_parseNum(std::data(buf)); parsed) + { + return *parsed; + } + + return {}; } std::string tr_strpercent(double x) diff --git a/qt/MakeDialog.cc b/qt/MakeDialog.cc index dccfe561f..d9e1f5b7b 100644 --- a/qt/MakeDialog.cc +++ b/qt/MakeDialog.cc @@ -322,6 +322,11 @@ void MakeDialog::updatePiecesLabel() void MakeDialog::onPieceSizeUpdated(int value) { auto new_size = static_cast(pow(2, value)); - builder_->setPieceSize(new_size); + + if (builder_) + { + builder_->setPieceSize(new_size); + } + updatePiecesLabel(); } diff --git a/tests/libtransmission/dht-test.cc b/tests/libtransmission/dht-test.cc index 68d10f561..1f3b01696 100644 --- a/tests/libtransmission/dht-test.cc +++ b/tests/libtransmission/dht-test.cc @@ -637,7 +637,7 @@ TEST_F(DhtTest, callsPeriodicPeriodically) auto const baseline = mock_dht.n_periodic_calls_; static auto constexpr Periods = 10; waitFor(event_base_, std::chrono::duration_cast(MockTimerInterval * Periods)); - EXPECT_NEAR(mock_dht.n_periodic_calls_, baseline + Periods, Periods / 2); + EXPECT_NEAR(mock_dht.n_periodic_calls_, baseline + Periods, Periods / 2.0); } } // namespace libtransmission::test diff --git a/tests/libtransmission/handshake-test.cc b/tests/libtransmission/handshake-test.cc index 4f7d4828c..56649ab5a 100644 --- a/tests/libtransmission/handshake-test.cc +++ b/tests/libtransmission/handshake-test.cc @@ -256,8 +256,7 @@ TEST_F(HandshakeTest, incomingPlaintext) EXPECT_EQ(io, res->io); EXPECT_TRUE(res->peer_id); EXPECT_EQ(peer_id, res->peer_id); - EXPECT_TRUE(io->torrentHash()); - EXPECT_EQ(TorrentWeAreSeeding.info_hash, *io->torrentHash()); + EXPECT_EQ(TorrentWeAreSeeding.info_hash, io->torrentHash()); evutil_closesocket(sock); } @@ -283,7 +282,7 @@ TEST_F(HandshakeTest, incomingPlaintextUnknownInfoHash) EXPECT_TRUE(res->readAnythingFromPeer); EXPECT_EQ(io, res->io); EXPECT_FALSE(res->peer_id); - EXPECT_FALSE(io->torrentHash()); + EXPECT_EQ(tr_sha1_digest_t{}, io->torrentHash()); evutil_closesocket(sock); } @@ -309,9 +308,8 @@ TEST_F(HandshakeTest, outgoingPlaintext) EXPECT_EQ(io, res->io); EXPECT_TRUE(res->peer_id); EXPECT_EQ(peer_id, res->peer_id); - EXPECT_TRUE(io->torrentHash()); - EXPECT_EQ(UbuntuTorrent.info_hash, *io->torrentHash()); - EXPECT_EQ(tr_sha1_to_string(UbuntuTorrent.info_hash), tr_sha1_to_string(*io->torrentHash())); + EXPECT_EQ(UbuntuTorrent.info_hash, io->torrentHash()); + EXPECT_EQ(tr_sha1_to_string(UbuntuTorrent.info_hash), tr_sha1_to_string(io->torrentHash())); evutil_closesocket(sock); } @@ -348,9 +346,8 @@ TEST_F(HandshakeTest, incomingEncrypted) EXPECT_EQ(io, res->io); EXPECT_TRUE(res->peer_id); EXPECT_EQ(ExpectedPeerId, res->peer_id); - EXPECT_TRUE(io->torrentHash()); - EXPECT_EQ(UbuntuTorrent.info_hash, *io->torrentHash()); - EXPECT_EQ(tr_sha1_to_string(UbuntuTorrent.info_hash), tr_sha1_to_string(*io->torrentHash())); + EXPECT_EQ(UbuntuTorrent.info_hash, io->torrentHash()); + EXPECT_EQ(tr_sha1_to_string(UbuntuTorrent.info_hash), tr_sha1_to_string(io->torrentHash())); evutil_closesocket(sock); } @@ -383,7 +380,7 @@ TEST_F(HandshakeTest, incomingEncryptedUnknownInfoHash) EXPECT_TRUE(res); EXPECT_FALSE(res->isConnected); EXPECT_TRUE(res->readAnythingFromPeer); - EXPECT_FALSE(io->torrentHash()); + EXPECT_EQ(tr_sha1_digest_t{}, io->torrentHash()); evutil_closesocket(sock); } @@ -425,9 +422,8 @@ TEST_F(HandshakeTest, outgoingEncrypted) EXPECT_EQ(io, res->io); EXPECT_TRUE(res->peer_id); EXPECT_EQ(ExpectedPeerId, res->peer_id); - EXPECT_TRUE(io->torrentHash()); - EXPECT_EQ(UbuntuTorrent.info_hash, *io->torrentHash()); - EXPECT_EQ(tr_sha1_to_string(UbuntuTorrent.info_hash), tr_sha1_to_string(*io->torrentHash())); + EXPECT_EQ(UbuntuTorrent.info_hash, io->torrentHash()); + EXPECT_EQ(tr_sha1_to_string(UbuntuTorrent.info_hash), tr_sha1_to_string(io->torrentHash())); evutil_closesocket(sock); } diff --git a/tests/libtransmission/watchdir-test.cc b/tests/libtransmission/watchdir-test.cc index e308d43e9..3ac371532 100644 --- a/tests/libtransmission/watchdir-test.cc +++ b/tests/libtransmission/watchdir-test.cc @@ -181,7 +181,7 @@ TEST_P(WatchDirTest, watch) auto names = std::vector{}; auto callback = [&names](std::string_view /*dirname*/, std::string_view basename) { - names.emplace_back(std::string{ basename }); + names.emplace_back(basename); return Watchdir::Action::Done; }; auto watchdir = createWatchDir(dirname, callback); @@ -229,7 +229,7 @@ TEST_P(WatchDirTest, retry) auto names = std::vector{}; auto callback = [&names](std::string_view /*dirname*/, std::string_view basename) { - names.emplace_back(std::string{ basename }); + names.emplace_back(basename); return Watchdir::Action::Retry; }; auto watchdir = createWatchDir(path, callback);