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:
parent
ebcccbd358
commit
c15f544356
6 changed files with 138 additions and 16 deletions
|
@ -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
|
||||
}
|
||||
|
||||
|
||||
//////////////////////////////////////////////////////////////////////
|
||||
|
||||
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue