diff --git a/td/telegram/SecureStorage.cpp b/td/telegram/SecureStorage.cpp index 04dca610..34e13c60 100644 --- a/td/telegram/SecureStorage.cpp +++ b/td/telegram/SecureStorage.cpp @@ -352,7 +352,7 @@ Result decrypt_value(const Secret &secret, const ValueHash &hash, S Result encrypt_file(const Secret &secret, std::string src, std::string dest) { TRY_RESULT(src_file, FileFd::open(src, FileFd::Flags::Read)); TRY_RESULT(dest_file, FileFd::open(dest, FileFd::Flags::Truncate | FileFd::Flags::Write | FileFd::Create)); - auto src_file_size = src_file.get_size(); + TRY_RESULT(src_file_size, src_file.get_size()); BufferSliceDataView random_prefix_view(gen_random_prefix(src_file_size)); FileDataView data_view(src_file, src_file_size); @@ -370,7 +370,7 @@ Result encrypt_file(const Secret &secret, std::string src, std::strin Status decrypt_file(const Secret &secret, const ValueHash &hash, std::string src, std::string dest) { TRY_RESULT(src_file, FileFd::open(src, FileFd::Flags::Read)); TRY_RESULT(dest_file, FileFd::open(dest, FileFd::Flags::Truncate | FileFd::Flags::Write | FileFd::Create)); - auto src_file_size = src_file.get_size(); + TRY_RESULT(src_file_size, src_file.get_size()); FileDataView src_file_view(src_file, src_file_size); diff --git a/td/telegram/cli.cpp b/td/telegram/cli.cpp index 858e9bd0..f7cf2aa3 100644 --- a/td/telegram/cli.cpp +++ b/td/telegram/cli.cpp @@ -3630,7 +3630,7 @@ class CliClient final : public Actor { } auto fd = r_fd.move_as_ok(); - auto size = fd.get_size(); + auto size = fd.get_size().move_as_ok(); fd.seek(size).ignore(); fd.write("a").ignore(); fd.seek(size).ignore(); diff --git a/td/telegram/files/FileHashUploader.cpp b/td/telegram/files/FileHashUploader.cpp index 1a24ad67..7407fe05 100644 --- a/td/telegram/files/FileHashUploader.cpp +++ b/td/telegram/files/FileHashUploader.cpp @@ -37,7 +37,8 @@ void FileHashUploader::start_up() { Status FileHashUploader::init() { TRY_RESULT(fd, FileFd::open(local_.path_, FileFd::Read)); - if (fd.get_size() != size_) { + TRY_RESULT(file_size, fd.get_size()); + if (file_size != size_) { return Status::Error("size mismatch"); } fd_ = BufferedFd(std::move(fd)); diff --git a/td/telegram/files/FileLoaderUtils.cpp b/td/telegram/files/FileLoaderUtils.cpp index 8acb3444..92a14d98 100644 --- a/td/telegram/files/FileLoaderUtils.cpp +++ b/td/telegram/files/FileLoaderUtils.cpp @@ -130,7 +130,8 @@ Result search_file(CSlice dir, CSlice name, int64 expected_size) { FileFd fd; std::string path; std::tie(fd, path) = r_pair.move_as_ok(); - if (fd.stat().size_ != expected_size) { + auto r_size = fd.get_size(); + if (r_size.is_error() || r_size.ok() != expected_size) { return true; } fd.close(); diff --git a/td/telegram/files/FileUploader.cpp b/td/telegram/files/FileUploader.cpp index 0bcc044b..d4611019 100644 --- a/td/telegram/files/FileUploader.cpp +++ b/td/telegram/files/FileUploader.cpp @@ -164,13 +164,13 @@ Result FileUploader::on_update_local_location(const Loca if (local_is_ready) { CHECK(!fd_.empty()); - local_size = fd_.get_size(); + TRY_RESULT(local_size, fd_.get_size()); LOG(INFO) << "Set file local_size to " << local_size; if (local_size == 0) { return Status::Error("Can't upload empty file"); } } else if (!fd_.empty()) { - auto real_local_size = fd_.get_size(); + TRY_RESULT(real_local_size, fd_.get_size()); if (real_local_size < local_size) { LOG(ERROR) << tag("real_local_size", real_local_size) << " < " << tag("local_size", local_size); PrefixInfo info; diff --git a/tddb/td/db/binlog/Binlog.cpp b/tddb/td/db/binlog/Binlog.cpp index f5361620..29904acd 100644 --- a/tddb/td/db/binlog/Binlog.cpp +++ b/tddb/td/db/binlog/Binlog.cpp @@ -445,7 +445,9 @@ void Binlog::update_read_encryption() { CHECK(binlog_reader_ptr_); switch (encryption_type_) { case EncryptionType::None: { - binlog_reader_ptr_->set_input(&buffer_reader_, false, fd_.get_size()); + auto r_file_size = fd_.get_size(); + r_file_size.ensure(); + binlog_reader_ptr_->set_input(&buffer_reader_, false, r_file_size.ok()); byte_flow_flag_ = false; break; } @@ -456,7 +458,9 @@ void Binlog::update_read_encryption() { byte_flow_sink_ = ByteFlowSink(); byte_flow_source_ >> aes_xcode_byte_flow_ >> byte_flow_sink_; byte_flow_flag_ = true; - binlog_reader_ptr_->set_input(byte_flow_sink_.get_output(), true, fd_.get_size()); + auto r_file_size = fd_.get_size(); + r_file_size.ensure(); + binlog_reader_ptr_->set_input(byte_flow_sink_.get_output(), true, r_file_size.ok()); break; } } @@ -549,7 +553,7 @@ Status Binlog::load_binlog(const Callback &callback, const Callback &debug_callb } }); - auto fd_size = fd_.get_size(); + TRY_RESULT(fd_size, fd_.get_size()); if (offset != fd_size) { LOG(ERROR) << "Truncate " << tag("path", path_) << tag("old_size", fd_size) << tag("new_size", offset); fd_.seek(offset).ensure(); diff --git a/tdutils/td/utils/FileLog.cpp b/tdutils/td/utils/FileLog.cpp index 7c107a57..3e892d25 100644 --- a/tdutils/td/utils/FileLog.cpp +++ b/tdutils/td/utils/FileLog.cpp @@ -40,7 +40,8 @@ Status FileLog::init(string path, int64 rotate_threshold) { } else { path_ = r_path.move_as_ok(); } - size_ = fd_.get_size(); + TRY_RESULT(size, fd_.get_size()); + size_ = size; rotate_threshold_ = rotate_threshold; return Status::OK(); } diff --git a/tdutils/td/utils/filesystem.cpp b/tdutils/td/utils/filesystem.cpp index 57502ef9..e7f89a98 100644 --- a/tdutils/td/utils/filesystem.cpp +++ b/tdutils/td/utils/filesystem.cpp @@ -37,7 +37,8 @@ template Result read_file_impl(CSlice path, int64 size, int64 offset) { TRY_RESULT(from_file, FileFd::open(path, FileFd::Read)); if (size == -1) { - size = from_file.get_size(); + TRY_RESULT(file_size, from_file.get_size()); + size = file_size; } if (size < 0) { return Status::Error("Failed to read file: invalid size"); diff --git a/tdutils/td/utils/port/FileFd.cpp b/tdutils/td/utils/port/FileFd.cpp index d504039a..f978d111 100644 --- a/tdutils/td/utils/port/FileFd.cpp +++ b/tdutils/td/utils/port/FileFd.cpp @@ -424,8 +424,9 @@ NativeFd FileFd::move_as_native_fd() { return res; } -int64 FileFd::get_size() { - return stat().size_; +Result FileFd::get_size() { + TRY_RESULT(s, stat()); + return s.size_; } #if TD_PORT_WINDOWS @@ -435,7 +436,7 @@ static uint64 filetime_to_unix_time_nsec(LONGLONG filetime) { } #endif -Stat FileFd::stat() { +Result FileFd::stat() { CHECK(!empty()); #if TD_PORT_POSIX return detail::fstat(get_native_fd().fd()); diff --git a/tdutils/td/utils/port/FileFd.h b/tdutils/td/utils/port/FileFd.h index bd187fca..8c6b1f63 100644 --- a/tdutils/td/utils/port/FileFd.h +++ b/tdutils/td/utils/port/FileFd.h @@ -49,9 +49,9 @@ class FileFd { void close(); bool empty() const; - int64 get_size(); + Result get_size(); - Stat stat(); + Result stat(); Status sync() TD_WARN_UNUSED_RESULT; diff --git a/tdutils/td/utils/port/Stat.cpp b/tdutils/td/utils/port/Stat.cpp index d22e0795..56d4228c 100644 --- a/tdutils/td/utils/port/Stat.cpp +++ b/tdutils/td/utils/port/Stat.cpp @@ -111,11 +111,13 @@ Stat from_native_stat(const struct ::stat &buf) { return res; } -Stat fstat(int native_fd) { +Result fstat(int native_fd) { struct ::stat buf; int err = detail::skip_eintr([&] { return ::fstat(native_fd, &buf); }); auto fstat_errno = errno; - LOG_IF(FATAL, err < 0) << Status::PosixError(fstat_errno, PSLICE() << "Stat for fd " << native_fd << " failed"); + if (err < 0) { + return Status::PosixError(fstat_errno, PSLICE() << "Stat for fd " << native_fd << " failed"); + } return detail::from_native_stat(buf); } @@ -135,7 +137,7 @@ Status update_atime(int native_fd) { } return Status::OK(); #elif TD_DARWIN - auto info = fstat(native_fd); + TRY_RESULT(info, fstat(native_fd)); timeval upd[2]; auto now = Clocks::system(); // access time diff --git a/tdutils/td/utils/port/Stat.h b/tdutils/td/utils/port/Stat.h index 0e01b0e8..01072715 100644 --- a/tdutils/td/utils/port/Stat.h +++ b/tdutils/td/utils/port/Stat.h @@ -34,7 +34,7 @@ Result cpu_stat() TD_WARN_UNUSED_RESULT; #if TD_PORT_POSIX namespace detail { -Stat fstat(int native_fd); // TODO return Result +Result fstat(int native_fd); } // namespace detail Status update_atime(CSlice path) TD_WARN_UNUSED_RESULT; diff --git a/tdutils/td/utils/port/path.cpp b/tdutils/td/utils/port/path.cpp index 6d9d9ee8..8dcbc54f 100644 --- a/tdutils/td/utils/port/path.cpp +++ b/tdutils/td/utils/port/path.cpp @@ -359,7 +359,8 @@ Result walk_path_file(string &path, const WalkFunction &func) { Result walk_path(string &path, const WalkFunction &func) { TRY_RESULT(fd, FileFd::open(path, FileFd::Read)); - auto stat = fd.stat(); + TRY_RESULT(stat, fd.stat()); + bool is_dir = stat.is_dir_; bool is_reg = stat.is_reg_; if (is_dir) { diff --git a/tdutils/test/port.cpp b/tdutils/test/port.cpp index 5c71914b..57375d96 100644 --- a/tdutils/test/port.cpp +++ b/tdutils/test/port.cpp @@ -35,47 +35,41 @@ TEST(Port, files) { int cnt = 0; const int ITER_COUNT = 1000; for (int i = 0; i < ITER_COUNT; i++) { - walk_path(main_dir, - [&](CSlice name, WalkPath::Type type) { - if (type == WalkPath::Type::NotDir) { - ASSERT_TRUE(name == fd_path || name == fd2_path); - } - cnt++; - }) - .ensure(); + walk_path(main_dir, [&](CSlice name, WalkPath::Type type) { + if (type == WalkPath::Type::NotDir) { + ASSERT_TRUE(name == fd_path || name == fd2_path); + } + cnt++; + }).ensure(); } ASSERT_EQ((5 * 2 + 2) * ITER_COUNT, cnt); bool was_abort = false; - walk_path(main_dir, - [&](CSlice name, WalkPath::Type type) { - CHECK(!was_abort); - if (type == WalkPath::Type::EnterDir && ends_with(name, PSLICE() << TD_DIR_SLASH << "B")) { - was_abort = true; - return WalkPath::Action::Abort; - } - return WalkPath::Action::Continue; - }) - .ensure(); + walk_path(main_dir, [&](CSlice name, WalkPath::Type type) { + CHECK(!was_abort); + if (type == WalkPath::Type::EnterDir && ends_with(name, PSLICE() << TD_DIR_SLASH << "B")) { + was_abort = true; + return WalkPath::Action::Abort; + } + return WalkPath::Action::Continue; + }).ensure(); CHECK(was_abort); cnt = 0; bool is_first_dir = true; - walk_path(main_dir, - [&](CSlice name, WalkPath::Type type) { - cnt++; - if (type == WalkPath::Type::EnterDir) { - if (is_first_dir) { - is_first_dir = false; - } else { - return WalkPath::Action::SkipDir; - } - } - return WalkPath::Action::Continue; - }) - .ensure(); + walk_path(main_dir, [&](CSlice name, WalkPath::Type type) { + cnt++; + if (type == WalkPath::Type::EnterDir) { + if (is_first_dir) { + is_first_dir = false; + } else { + return WalkPath::Action::SkipDir; + } + } + return WalkPath::Action::Continue; + }).ensure(); ASSERT_EQ(6, cnt); - ASSERT_EQ(0u, fd.get_size()); + ASSERT_EQ(0u, fd.get_size().move_as_ok()); ASSERT_EQ(12u, fd.write("Hello world!").move_as_ok()); ASSERT_EQ(4u, fd.pwrite("abcd", 1).move_as_ok()); char buf[100]; @@ -86,7 +80,7 @@ TEST(Port, files) { ASSERT_TRUE(FileFd::open(main_dir, FileFd::Read | FileFd::CreateNew).is_error()); fd = FileFd::open(fd_path, FileFd::Read | FileFd::Create).move_as_ok(); - ASSERT_EQ(13u, fd.get_size()); + ASSERT_EQ(13u, fd.get_size().move_as_ok()); ASSERT_EQ(4u, fd.pread(buf_slice.substr(0, 4), 1).move_as_ok()); ASSERT_STREQ("abcd", buf_slice.substr(0, 4));