summary refs log tree commit diff
path: root/src
diff options
context:
space:
mode:
authorEelco Dolstra <e.dolstra@tudelft.nl>2008-11-14 15:46:45 +0000
committerEelco Dolstra <e.dolstra@tudelft.nl>2008-11-14 15:46:45 +0000
commit6fedb7aa0f76c34bccedd14095bcc7824006489d (patch)
tree48ea0a4c1951e828eab315e7664dd1b164ac1148 /src
parenta519bb063505a8d39e6b1e12f130d66771676e23 (diff)
downloadguix-6fedb7aa0f76c34bccedd14095bcc7824006489d.tar.gz
* Restore SIGPIPE to SIG_DFL when running the builder. This prevents
  subtle and often hard-to-reproduce bugs where programs in pipes
  either barf with a "Broken pipe" message or not, depending on the
  exact timing conditions.  This particularly happened in GNU M4 (and
  Bison, which uses M4).

Diffstat (limited to 'src')
-rw-r--r--src/libstore/build.cc13
1 files changed, 13 insertions, 0 deletions
diff --git a/src/libstore/build.cc b/src/libstore/build.cc
index 436cf4762d..a1c99cddd0 100644
--- a/src/libstore/build.cc
+++ b/src/libstore/build.cc
@@ -361,6 +361,15 @@ const char * * strings2CharPtrs(const Strings & ss)
 }
 
 
+/* Restore default handling of SIGPIPE, otherwise some programs will
+   randomly say "Broken pipe". */
+static void restoreSIGPIPE() 
+{
+    struct sigaction act, oact;
+    act.sa_handler = SIG_DFL;
+    act.sa_flags = 0;
+    if (sigaction(SIGPIPE, &act, &oact)) throw SysError("resetting SIGPIPE");
+}
 
 
 //////////////////////////////////////////////////////////////////////
@@ -514,6 +523,8 @@ static void runSetuidHelper(const string & command,
             args.push_back(arg.c_str());
             args.push_back(0);
 
+            restoreSIGPIPE();
+            
             execve(program.c_str(), (char * *) &args[0], 0);
             throw SysError(format("executing `%1%'") % program);
         }
@@ -1878,6 +1889,8 @@ void DerivationGoal::startBuilder()
                 args.push_back(i->c_str());
             args.push_back(0);
 
+            restoreSIGPIPE();
+
             /* Execute the program.  This should not return. */
             execve(program.c_str(), (char * *) &args[0], (char * *) envArr);