* 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).
This commit is contained in:
Eelco Dolstra 2008-11-14 15:46:45 +00:00
parent a519bb0635
commit 6fedb7aa0f

View file

@ -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(arg.c_str());
args.push_back(0); args.push_back(0);
restoreSIGPIPE();
execve(program.c_str(), (char * *) &args[0], 0); execve(program.c_str(), (char * *) &args[0], 0);
throw SysError(format("executing `%1%'") % program); throw SysError(format("executing `%1%'") % program);
} }
@ -1878,6 +1889,8 @@ void DerivationGoal::startBuilder()
args.push_back(i->c_str()); args.push_back(i->c_str());
args.push_back(0); args.push_back(0);
restoreSIGPIPE();
/* Execute the program. This should not return. */ /* Execute the program. This should not return. */
execve(program.c_str(), (char * *) &args[0], (char * *) envArr); execve(program.c_str(), (char * *) &args[0], (char * *) envArr);