* 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
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
//////////////////////////////////////////////////////////////////////
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -185,6 +185,11 @@ void readFull(int fd, unsigned char * buf, size_t count);
 | 
			
		|||
void writeFull(int fd, const unsigned char * buf, size_t count);
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
/* Read a file descriptor until EOF occurs. */
 | 
			
		||||
string drainFD(int fd);
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
/* Automatic cleanup of resources. */
 | 
			
		||||
 | 
			
		||||
class AutoDelete
 | 
			
		||||
| 
						 | 
				
			
			@ -249,6 +254,15 @@ public:
 | 
			
		|||
};
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
/* Run a program and return its stdout in a string (i.e., like the
 | 
			
		||||
   shell backtick operator). */
 | 
			
		||||
string runProgram(Path program);
 | 
			
		||||
 | 
			
		||||
/* Wrapper around _exit() on Unix and ExitProcess() on Windows.  (On
 | 
			
		||||
   Cygwin, _exit() doesn't seem to do the right thing.) */
 | 
			
		||||
void quickExit(int status);
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
/* User interruption. */
 | 
			
		||||
 | 
			
		||||
extern volatile sig_atomic_t _isInterrupted;
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
		Loading…
	
	Add table
		Add a link
		
	
		Reference in a new issue