From 8541d27fce95f1f6a4a6c89bcbc09503ff7ea092 Mon Sep 17 00:00:00 2001 From: Eelco Dolstra Date: Thu, 15 Nov 2012 15:01:02 +0100 Subject: [PATCH] Don't use std::cerr in a few places Slightly scared of using std::cerr in a vforked process... --- src/libstore/build.cc | 18 ++++++++---------- src/libstore/remote-store.cc | 2 +- src/libutil/util.cc | 35 ++++++++++++++++++++--------------- src/libutil/util.hh | 4 +++- src/nix-daemon/nix-daemon.cc | 5 ++--- 5 files changed, 34 insertions(+), 30 deletions(-) diff --git a/src/libstore/build.cc b/src/libstore/build.cc index 3e67e55d4..2fd071eba 100644 --- a/src/libstore/build.cc +++ b/src/libstore/build.cc @@ -10,7 +10,6 @@ #include "immutable.hh" #include -#include #include #include #include @@ -565,7 +564,7 @@ static void runSetuidHelper(const string & command, throw SysError(format("executing `%1%'") % program); } catch (std::exception & e) { - std::cerr << "error: " << e.what() << std::endl; + writeToStderr("error: " + string(e.what()) + "\n"); } _exit(1); } @@ -695,7 +694,7 @@ HookInstance::HookInstance() throw SysError(format("executing `%1%'") % buildHook); } catch (std::exception & e) { - std::cerr << format("build hook error: %1%") % e.what() << std::endl; + writeToStderr("build hook error: " + string(e.what()) + "\n"); } _exit(1); } @@ -1547,7 +1546,7 @@ HookReply DerivationGoal::tryBuildHook() break; } s += "\n"; - writeToStderr((unsigned char *) s.data(), s.size()); + writeToStderr(s); } debug(format("hook reply is `%1%'") % reply); @@ -2141,7 +2140,7 @@ void DerivationGoal::initChild() throw SysError(format("executing `%1%'") % drv.builder); } catch (std::exception & e) { - std::cerr << format("build error: %1%") % e.what() << std::endl; + writeToStderr("build error: " + string(e.what()) + "\n"); _exit(inSetup ? childSetupFailed : 1); } @@ -2362,7 +2361,7 @@ void DerivationGoal::handleChildOutput(int fd, const string & data) (!hook && fd == builderOut.readSide)) { if (verbosity >= settings.buildVerbosity) - writeToStderr((unsigned char *) data.data(), data.size()); + writeToStderr(data); if (bzLogFile) { int err; BZ2_bzWrite(&err, bzLogFile, (unsigned char *) data.data(), data.size()); @@ -2372,7 +2371,7 @@ void DerivationGoal::handleChildOutput(int fd, const string & data) } if (hook && fd == hook->fromHook.readSide) - writeToStderr((unsigned char *) data.data(), data.size()); + writeToStderr(data); } @@ -2693,7 +2692,7 @@ void SubstitutionGoal::tryToRun() throw SysError(format("executing `%1%'") % sub); } catch (std::exception & e) { - std::cerr << format("substitute error: %1%") % e.what() << std::endl; + writeToStderr("substitute error: " + string(e.what()) + "\n"); } _exit(1); } @@ -2809,8 +2808,7 @@ void SubstitutionGoal::finished() void SubstitutionGoal::handleChildOutput(int fd, const string & data) { assert(fd == logPipe.readSide); - if (verbosity >= settings.buildVerbosity) - writeToStderr((unsigned char *) data.data(), data.size()); + if (verbosity >= settings.buildVerbosity) writeToStderr(data); /* Don't write substitution output to a log file for now. We probably should, though. */ } diff --git a/src/libstore/remote-store.cc b/src/libstore/remote-store.cc index 16b5db808..c97c5fbf0 100644 --- a/src/libstore/remote-store.cc +++ b/src/libstore/remote-store.cc @@ -556,7 +556,7 @@ void RemoteStore::processStderr(Sink * sink, Source * source) } else { string s = readString(from); - writeToStderr((const unsigned char *) s.data(), s.size()); + writeToStderr(s); } } if (msg == STDERR_ERROR) { diff --git a/src/libutil/util.cc b/src/libutil/util.cc index f311b1ae3..e208701ce 100644 --- a/src/libutil/util.cc +++ b/src/libutil/util.cc @@ -483,16 +483,7 @@ void printMsg_(Verbosity level, const format & f) else if (logType == ltEscapes && level != lvlInfo) prefix = "\033[" + escVerbosity(level) + "s"; string s = (format("%1%%2%\n") % prefix % f.str()).str(); - try { - writeToStderr((const unsigned char *) s.data(), s.size()); - } catch (SysError & e) { - /* Ignore failing writes to stderr if we're in an exception - handler, otherwise throw an exception. We need to ignore - write errors in exception handlers to ensure that cleanup - code runs to completion if the other side of stderr has - been closed unexpectedly. */ - if (!std::uncaught_exception()) throw; - } + writeToStderr(s); } @@ -505,13 +496,28 @@ void warnOnce(bool & haveWarned, const format & f) } +void writeToStderr(const string & s) +{ + try { + _writeToStderr((const unsigned char *) s.data(), s.size()); + } catch (SysError & e) { + /* Ignore failing writes to stderr if we're in an exception + handler, otherwise throw an exception. We need to ignore + write errors in exception handlers to ensure that cleanup + code runs to completion if the other side of stderr has + been closed unexpectedly. */ + if (!std::uncaught_exception()) throw; + } +} + + static void defaultWriteToStderr(const unsigned char * buf, size_t count) { writeFull(STDERR_FILENO, buf, count); } -void (*writeToStderr) (const unsigned char * buf, size_t count) = defaultWriteToStderr; +void (*_writeToStderr) (const unsigned char * buf, size_t count) = defaultWriteToStderr; void readFull(int fd, unsigned char * buf, size_t count) @@ -845,8 +851,7 @@ void killUser(uid_t uid) } } catch (std::exception & e) { - std::cerr << format("killing processes belonging to uid `%1%': %2%") - % uid % e.what() << std::endl; + writeToStderr((format("killing processes belonging to uid `%1%': %2%\n") % uid % e.what()).str()); _exit(1); } _exit(0); @@ -902,7 +907,7 @@ string runProgram(Path program, bool searchPath, const Strings & args) throw SysError(format("executing `%1%'") % program); } catch (std::exception & e) { - std::cerr << "error: " << e.what() << std::endl; + writeToStderr("error: " + string(e.what()) + "\n"); } _exit(1); } @@ -1125,5 +1130,5 @@ void ignoreException() } } - + } diff --git a/src/libutil/util.hh b/src/libutil/util.hh index 90413b0ef..87b63f6e9 100644 --- a/src/libutil/util.hh +++ b/src/libutil/util.hh @@ -148,7 +148,9 @@ void printMsg_(Verbosity level, const format & f); void warnOnce(bool & haveWarned, const format & f); -extern void (*writeToStderr) (const unsigned char * buf, size_t count); +void writeToStderr(const string & s); + +extern void (*_writeToStderr) (const unsigned char * buf, size_t count); /* Wrappers arount read()/write() that read/write exactly the diff --git a/src/nix-daemon/nix-daemon.cc b/src/nix-daemon/nix-daemon.cc index 6256258ec..9b3c5bda1 100644 --- a/src/nix-daemon/nix-daemon.cc +++ b/src/nix-daemon/nix-daemon.cc @@ -6,7 +6,6 @@ #include "archive.hh" #include "globals.hh" -#include #include #include #include @@ -642,7 +641,7 @@ static void processConnection() { canSendStderr = false; myPid = getpid(); - writeToStderr = tunnelStderr; + _writeToStderr = tunnelStderr; #ifdef HAVE_HUP_NOTIFICATION /* Allow us to receive SIGPOLL for events on the client socket. */ @@ -877,7 +876,7 @@ static void daemonLoop() processConnection(); } catch (std::exception & e) { - std::cerr << format("child error: %1%\n") % e.what(); + writeToStderr("child error: " + string(e.what()) + "\n"); } exit(0); }