From: Luboš Luňák Date: Mon, 1 Nov 2021 12:37:11 +0000 (+0000) Subject: fix: handle newlines on Windows properly X-Git-Tag: v4.6~75^2 X-Git-Url: http://git.ipfire.org/cgi-bin/gitweb.cgi?a=commitdiff_plain;h=refs%2Fpull%2F968%2Fhead;p=thirdparty%2Fccache.git fix: handle newlines on Windows properly --- diff --git a/src/Util.cpp b/src/Util.cpp index 24ce1bbd9..1f812fe37 100644 --- a/src/Util.cpp +++ b/src/Util.cpp @@ -1174,12 +1174,36 @@ same_program_name(nonstd::string_view program_name, #endif } +#ifdef _WIN32 +// Stdout/stderr are normally opened in text mode, which would convert newlines +// a second time, since we treat outputs as binary data. +// Make sure to switch to binary mode. +namespace { +struct BinaryModeHelper +{ + BinaryModeHelper(int fd_) : fd(fd_), oldmode(_setmode(fd, _O_BINARY)) + { + } + ~BinaryModeHelper() + { + _setmode(fd, oldmode); + } + int fd; + int oldmode; +}; +} // namespace +#endif + void -send_to_stderr(const Context& ctx, const std::string& text) +send_to_fd(const Context& ctx, const std::string& text, int fd) { const std::string* text_to_send = &text; std::string modified_text; +#ifdef _WIN32 + BinaryModeHelper helper(fd); +#endif + if (ctx.args_info.strip_diagnostics_colors) { try { modified_text = strip_ansi_csi_seqs(text); @@ -1195,7 +1219,7 @@ send_to_stderr(const Context& ctx, const std::string& text) } try { - write_fd(STDERR_FILENO, text_to_send->data(), text_to_send->length()); + write_fd(fd, text_to_send->data(), text_to_send->length()); } catch (core::Error& e) { throw core::Error("Failed to write to stderr: {}", e.what()); } diff --git a/src/Util.hpp b/src/Util.hpp index 7a3d116e2..ef05852ed 100644 --- a/src/Util.hpp +++ b/src/Util.hpp @@ -33,6 +33,10 @@ #include #include +#ifdef HAVE_UNISTD_H +# include +#endif + class Context; namespace Util { @@ -318,11 +322,16 @@ void rename(const std::string& oldpath, const std::string& newpath); bool same_program_name(nonstd::string_view program_name, nonstd::string_view canonical_program_name); -// Send `text` to STDERR_FILENO, optionally stripping ANSI color sequences if -// `ctx.args_info.strip_diagnostics_colors` is true and rewriting paths to -// absolute if `ctx.config.absolute_paths_in_stderr` is true. Throws +// Send `text` to file descriptor 'fd', optionally stripping ANSI color +// sequences if `ctx.args_info.strip_diagnostics_colors` is true and rewriting +// paths to absolute if `ctx.config.absolute_paths_in_stderr` is true. Throws // `core::Error` on error. -void send_to_stderr(const Context& ctx, const std::string& text); +void send_to_fd(const Context& ctx, const std::string& text, int fd); +inline void +send_to_stderr(const Context& ctx, const std::string& text) +{ + send_to_fd(ctx, text, STDERR_FILENO); +} // Set the FD_CLOEXEC on file descriptor `fd`. This is a NOP on Windows. void set_cloexec_flag(int fd);