1
0
Fork 0
mirror of https://github.com/NixOS/nix synced 2025-06-26 20:01:15 +02:00

* Call find-runtime-roots.pl from the garbage collector to prevent

running applications etc. from being garbage collected.
This commit is contained in:
Eelco Dolstra 2006-07-20 12:17:25 +00:00
parent ebcccbd358
commit c15f544356
6 changed files with 138 additions and 16 deletions

View file

@ -13,6 +13,10 @@
#include <fcntl.h>
#include <signal.h>
#ifdef __CYGWIN__
#include <windows.h>
#endif
#include "util.hh"
@ -434,6 +438,23 @@ void writeFull(int fd, const unsigned char * buf, size_t count)
}
string drainFD(int fd)
{
string result;
unsigned char buffer[4096];
while (1) {
ssize_t rd = read(fd, buffer, sizeof buffer);
if (rd == -1) {
if (errno != EINTR)
throw SysError("reading from file");
}
else if (rd == 0) break;
else result.append((char *) buffer, rd);
}
return result;
}
//////////////////////////////////////////////////////////////////////
@ -643,6 +664,69 @@ void Pid::setSeparatePG(bool separatePG)
//////////////////////////////////////////////////////////////////////
string runProgram(Path program)
{
/* Create a pipe. */
Pipe pipe;
pipe.create();
/* Fork. */
Pid pid;
pid = fork();
switch (pid) {
case -1:
throw SysError("unable to fork");
case 0: /* child */
try {
pipe.readSide.close();
if (dup2(pipe.writeSide, STDOUT_FILENO) == -1)
throw SysError("dupping from-hook write side");
execl(program.c_str(), program.c_str(), (char *) 0);
throw SysError(format("executing `%1%'") % program);
} catch (exception & e) {
cerr << "error: " << e.what() << endl;
}
quickExit(1);
}
/* Parent. */
pipe.writeSide.close();
string result = drainFD(pipe.readSide);
/* Wait for the child to finish. */
int status = pid.wait(true);
if (!statusOk(status))
throw Error(format("program `%1% %2%")
% program % statusToString(status));
return result;
}
void quickExit(int status)
{
#ifdef __CYGWIN__
/* Hack for Cygwin: _exit() doesn't seem to work quite right,
since some Berkeley DB code appears to be called when a child
exits through _exit() (e.g., because execve() failed). So call
the Windows API directly. */
ExitProcess(status);
#else
_exit(status);
#endif
}
//////////////////////////////////////////////////////////////////////