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:
parent
155d7c8dfa
commit
c9fbd2dfd5
4 changed files with 162 additions and 87 deletions
|
@ -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;
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue