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

* Wrapper class around pids.

This commit is contained in:
Eelco Dolstra 2004-06-22 09:51:44 +00:00
parent 155d7c8dfa
commit c9fbd2dfd5
4 changed files with 162 additions and 87 deletions

View file

@ -7,9 +7,11 @@
#include <sys/types.h>
#include <sys/stat.h>
#include <sys/wait.h>
#include <unistd.h>
#include <dirent.h>
#include <fcntl.h>
#include <signal.h>
#include "util.hh"
@ -337,6 +339,10 @@ void writeFull(int fd, const unsigned char * buf, size_t count)
}
//////////////////////////////////////////////////////////////////////
AutoDelete::AutoDelete(const string & p) : path(p)
{
del = true;
@ -353,16 +359,22 @@ void AutoDelete::cancel()
}
//////////////////////////////////////////////////////////////////////
AutoCloseFD::AutoCloseFD()
{
fd = -1;
}
AutoCloseFD::AutoCloseFD(int fd)
{
this->fd = fd;
}
AutoCloseFD::~AutoCloseFD()
{
try {
@ -372,17 +384,20 @@ AutoCloseFD::~AutoCloseFD()
}
}
void AutoCloseFD::operator =(int fd)
{
if (this->fd != fd) close();
this->fd = fd;
}
AutoCloseFD::operator int()
{
return fd;
}
void AutoCloseFD::close()
{
if (fd != -1) {
@ -393,6 +408,7 @@ void AutoCloseFD::close()
}
}
bool AutoCloseFD::isOpen()
{
return fd != -1;
@ -408,32 +424,119 @@ void Pipe::create()
}
//////////////////////////////////////////////////////////////////////
AutoCloseDir::AutoCloseDir()
{
dir = 0;
}
AutoCloseDir::AutoCloseDir(DIR * dir)
{
this->dir = dir;
}
AutoCloseDir::~AutoCloseDir()
{
if (dir) closedir(dir);
}
void AutoCloseDir::operator =(DIR * dir)
{
this->dir = dir;
}
AutoCloseDir::operator DIR *()
{
return dir;
}
//////////////////////////////////////////////////////////////////////
Pid::Pid()
{
pid = -1;
separatePG = false;
}
Pid::~Pid()
{
kill();
}
void Pid::operator =(pid_t pid)
{
if (this->pid != pid) kill();
this->pid = pid;
}
Pid::operator pid_t()
{
return pid;
}
void Pid::kill()
{
if (pid == -1) return;
printMsg(lvlError, format("killing child process %1%") % pid);
/* Send a KILL signal to the child. If it has its own process
group, send the signal to every process in the child process
group (which hopefully includes *all* its children). */
if (::kill(separatePG ? -pid : pid, SIGKILL) != 0)
printMsg(lvlError, format("killing process %1%") % pid);
else {
/* Wait until the child dies, disregarding the exit status. */
int status;
while (waitpid(pid, &status, 0) == -1)
if (errno != EINTR) printMsg(lvlError,
format("waiting for process %1%") % pid);
}
pid = -1;
}
int Pid::wait(bool block)
{
while (1) {
int status;
int res = waitpid(pid, &status, block ? 0 : WNOHANG);
if (res == pid) {
pid = -1;
return status;
}
if (res == 0 && !block) return -1;
if (errno != EINTR)
throw SysError("cannot get child exit status");
}
}
void Pid::setSeparatePG(bool separatePG)
{
this->separatePG = separatePG;
}
//////////////////////////////////////////////////////////////////////
volatile sig_atomic_t _isInterrupted = 0;
void _interrupted()
@ -448,6 +551,10 @@ void _interrupted()
}
//////////////////////////////////////////////////////////////////////
string packStrings(const Strings & strings)
{
string d;