From: Joel Rosdahl Date: Tue, 28 Jul 2020 14:46:26 +0000 (+0200) Subject: C++-ify {copy,write}_fd X-Git-Tag: v4.0~270 X-Git-Url: http://git.ipfire.org/?a=commitdiff_plain;h=5cc1f31ac348597b7ca9d163f4eb306d6f62e12a;p=thirdparty%2Fccache.git C++-ify {copy,write}_fd --- diff --git a/src/ResultExtractor.cpp b/src/ResultExtractor.cpp index 61349b05e..531f0b4c8 100644 --- a/src/ResultExtractor.cpp +++ b/src/ResultExtractor.cpp @@ -18,8 +18,7 @@ #include "ResultExtractor.hpp" -#include "Context.hpp" -#include "logging.hpp" +#include "Util.hpp" #include "third_party/nonstd/string_view.hpp" @@ -73,8 +72,11 @@ ResultExtractor::on_entry_data(const uint8_t* data, size_t size) { assert(m_dest_fd); - if (!write_fd(*m_dest_fd, data, size)) { - throw Error(fmt::format("Failed to write to {}", m_dest_path)); + try { + Util::write_fd(*m_dest_fd, data, size); + } catch (Error& e) { + throw Error( + fmt::format("Failed to write to {}: {}", m_dest_path, e.what())); } } diff --git a/src/ResultRetriever.cpp b/src/ResultRetriever.cpp index bbdbc4d9a..b0a6b5f00 100644 --- a/src/ResultRetriever.cpp +++ b/src/ResultRetriever.cpp @@ -127,8 +127,13 @@ ResultRetriever::on_entry_data(const uint8_t* data, size_t size) if (m_dest_file_type == FileType::stderr_output || (m_dest_file_type == FileType::dependency && !m_dest_path.empty())) { m_dest_data.append(reinterpret_cast(data), size); - } else if (!write_fd(*m_dest_fd, data, size)) { - throw Error(fmt::format("Failed to write to {}", m_dest_path)); + } else { + try { + Util::write_fd(*m_dest_fd, data, size); + } catch (Error& e) { + throw Error( + fmt::format("Failed to write to {}: {}", m_dest_path, e.what())); + } } } @@ -153,22 +158,22 @@ ResultRetriever::write_dependency_file() { size_t start_pos = 0; - if (m_rewrite_dependency_target) { - size_t colon_pos = m_dest_data.find(':'); - if (colon_pos != std::string::npos) { - if (!write_fd(*m_dest_fd, - m_ctx.args_info.output_obj.data(), - m_ctx.args_info.output_obj.length())) { - throw Error(fmt::format("Failed to write to {}", m_dest_path)); + try { + if (m_rewrite_dependency_target) { + size_t colon_pos = m_dest_data.find(':'); + if (colon_pos != std::string::npos) { + Util::write_fd(*m_dest_fd, + m_ctx.args_info.output_obj.data(), + m_ctx.args_info.output_obj.length()); + start_pos = colon_pos; } - - start_pos = colon_pos; } - } - if (!write_fd(*m_dest_fd, - m_dest_data.data() + start_pos, - m_dest_data.length() - start_pos)) { - throw Error(fmt::format("Failed to write to {}", m_dest_path)); + Util::write_fd(*m_dest_fd, + m_dest_data.data() + start_pos, + m_dest_data.length() - start_pos); + } catch (Error& e) { + throw Error( + fmt::format("Failed to write to {}: {}", m_dest_path, e.what())); } } diff --git a/src/Util.cpp b/src/Util.cpp index 91a88e30c..d82a5fa11 100644 --- a/src/Util.cpp +++ b/src/Util.cpp @@ -281,6 +281,21 @@ common_dir_prefix_length(string_view dir, string_view path) return i; } +void +copy_fd(int fd_in, int fd_out) +{ + ssize_t n; + char buf[READ_BUFFER_SIZE]; + while ((n = read(fd_in, buf, sizeof(buf))) != 0) { + if (n == -1 && errno != EINTR) { + break; + } + if (n > 0) { + write_fd(fd_out, buf, n); + } + } +} + void copy_file(const std::string& src, const std::string& dest, bool via_tmp_file) { @@ -303,10 +318,7 @@ copy_file(const std::string& src, const std::string& dest, bool via_tmp_file) } } - if (!copy_fd(*src_fd, *dest_fd)) { - throw Error(strerror(errno)); - } - + copy_fd(*src_fd, *dest_fd); dest_fd.close(); src_fd.close(); @@ -432,7 +444,9 @@ fallocate(int fd, long new_size) return ENOMEM; } int err = 0; - if (!write_fd(fd, buf, bytes_to_write)) { + try { + write_fd(fd, buf, bytes_to_write); + } catch (Error& e) { err = errno; } lseek(fd, saved_pos, SEEK_SET); @@ -1059,8 +1073,10 @@ send_to_stderr(const std::string& text, bool strip_colors) } } - if (!write_fd(STDERR_FILENO, text_to_send->data(), text_to_send->length())) { - throw Error("Failed to write to stderr"); + try { + write_fd(STDERR_FILENO, text_to_send->data(), text_to_send->length()); + } catch (Error& e) { + throw Error(fmt::format("Failed to write to stderr: {}", e.what())); } } @@ -1237,6 +1253,23 @@ wipe_path(const std::string& path) }); } +void +write_fd(int fd, const void* data, size_t size) +{ + ssize_t written = 0; + do { + ssize_t count = + write(fd, static_cast(data) + written, size - written); + if (count == -1) { + if (errno != EAGAIN && errno != EINTR) { + throw Error(strerror(errno)); + } + } else { + written += count; + } + } while (static_cast(written) < size); +} + void write_file(const std::string& path, const std::string& data, diff --git a/src/Util.hpp b/src/Util.hpp index 480276f40..f48fc96e7 100644 --- a/src/Util.hpp +++ b/src/Util.hpp @@ -102,6 +102,9 @@ void clone_hard_link_or_copy_file(const Context& ctx, size_t common_dir_prefix_length(nonstd::string_view dir, nonstd::string_view path); +// Copy all data from `fd_in` to `fd_out`. Throws `Error` on error. +void copy_fd(int fd_in, int fd_out); + // Copy a file from `src` to `dest`. If via_tmp_file is true, `src` is copied to // a temporary file and then renamed to dest. Throws `Error` on error. void copy_file(const std::string& src, @@ -380,6 +383,9 @@ bool unlink_tmp(const std::string& path, // Throws Error on error. void wipe_path(const std::string& path); +// Write `size` bytes from `data` to `fd`. Throws `Error` on error. +void write_fd(int fd, const void* data, size_t size); + // Write `data` to `path`. The file will be opened according to `open_mode`, // which always will include `std::ios::out` even if not specified at the call // site. diff --git a/src/execute.cpp b/src/execute.cpp index 6f317d8df..cb5c93acf 100644 --- a/src/execute.cpp +++ b/src/execute.cpp @@ -197,9 +197,7 @@ win32execute(const char* path, BOOL ret = FALSE; if (length > 8192) { TemporaryFile tmp_file(path); - if (!write_fd(*tmp_file.fd, args, length)) { - cc_log("Error writing @file; this command will probably fail: %s", args); - } + Util::write_fd(*tmp_file.fd, args, length); std::string atfile = fmt::format("\"@{}\"", tmp_file.path); ret = CreateProcess(nullptr, const_cast(atfile.c_str()), diff --git a/src/legacy_util.cpp b/src/legacy_util.cpp index 797265370..4bc607648 100644 --- a/src/legacy_util.cpp +++ b/src/legacy_util.cpp @@ -47,43 +47,6 @@ fatal(const char* format, ...) throw FatalError(msg); } -bool -write_fd(int fd, const void* buf, size_t size) -{ - ssize_t written = 0; - do { - ssize_t count = - write(fd, static_cast(buf) + written, size - written); - if (count == -1) { - if (errno != EAGAIN && errno != EINTR) { - return false; - } - } else { - written += count; - } - } while (static_cast(written) < size); - - return true; -} - -// Copy all data from fd_in to fd_out. -bool -copy_fd(int fd_in, int fd_out) -{ - ssize_t n; - char buf[READ_BUFFER_SIZE]; - while ((n = read(fd_in, buf, sizeof(buf))) != 0) { - if (n == -1 && errno != EINTR) { - break; - } - if (n > 0 && !write_fd(fd_out, buf, n)) { - return false; - } - } - - return true; -} - // Return a static string with the current hostname. const char* get_hostname() diff --git a/src/legacy_util.hpp b/src/legacy_util.hpp index cee484d6e..0720d5bf1 100644 --- a/src/legacy_util.hpp +++ b/src/legacy_util.hpp @@ -24,8 +24,6 @@ void fatal(const char* format, ...) ATTR_FORMAT(printf, 1, 2) ATTR_NORETURN; -bool write_fd(int fd, const void* buf, size_t size); -bool copy_fd(int fd_in, int fd_out); const char* get_hostname(); void x_setenv(const char* name, const char* value); void x_unsetenv(const char* name);