]> git.ipfire.org Git - thirdparty/ccache.git/commitdiff
fix: handle newlines on Windows properly 968/head
authorLuboš Luňák <l.lunak@centrum.cz>
Mon, 1 Nov 2021 12:37:11 +0000 (12:37 +0000)
committerR. Voggenauer <rvogg@users.noreply.github.com>
Tue, 23 Nov 2021 21:09:13 +0000 (22:09 +0100)
src/Util.cpp
src/Util.hpp

index 24ce1bbd921a50cc5cfd33353e42710ae8f2b706..1f812fe37d827b4e46e3c101d851ee93193f98be 100644 (file)
@@ -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());
   }
index 7a3d116e27f90decb775866062aa9e034bcecb02..ef05852ed4af9039237d791b31a657020c7fab99 100644 (file)
 #include <utility>
 #include <vector>
 
+#ifdef HAVE_UNISTD_H
+#  include <unistd.h>
+#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);