1
0
mirror of https://github.com/Zygo/bees.git synced 2025-05-17 13:25:45 +02:00
bees/lib/process.cc
2016-11-17 12:12:13 -05:00

122 lines
1.8 KiB
C++

#include "crucible/process.h"
#include "crucible/chatter.h"
#include "crucible/error.h"
#include <utility>
// for gettid()
#ifndef _GNU_SOURCE
#define _GNU_SOURCE
#endif
#include <unistd.h>
#include <sys/syscall.h>
namespace crucible {
using namespace std;
bool
Process::joinable()
{
return !!m_pid;
}
Process::~Process()
{
if (joinable()) {
// because it's just not the same without the word "zombie"...
CHATTER("ZOMBIE WARNING: joinable Process pid " << m_pid << " abandoned");
}
}
Process::Process() :
m_pid(0)
{
}
Process::Process(Process &&move_from) :
m_pid(0)
{
swap(m_pid, move_from.m_pid);
}
void
Process::do_fork(function<int()> child_func)
{
int rv = fork();
if (rv < 0) {
THROW_ERRNO("fork failed");
}
m_pid = rv;
if (rv == 0) {
// child
catch_all([&]() {
int rv = child_func();
exit(rv);
});
terminate();
}
}
Process::status_type
Process::join()
{
if (m_pid == 0) {
THROW_ERROR(invalid_argument, "Process not created");
}
int status = 0;
pid_t rv = waitpid(m_pid, &status, 0);
if (rv == -1) {
THROW_ERRNO("waitpid failed, pid = " << m_pid);
}
if (rv != m_pid) {
THROW_ERROR(runtime_error, "waitpid failed, wanted pid = " << m_pid << ", got rv = " << rv << ", status = " << status);
}
m_pid = 0;
return status;
}
void
Process::detach()
{
m_pid = 0;
}
Process::native_handle_type
Process::native_handle()
{
return m_pid;
}
Process::id
Process::get_id()
{
return m_pid;
}
void
Process::kill(int sig)
{
if (!m_pid) {
THROW_ERROR(invalid_argument, "Process not created");
}
int rv = ::kill(m_pid, sig);
if (rv) {
THROW_ERRNO("killing process " << m_pid << " with signal " << sig);
}
}
template<>
struct ResourceHandle<Process::id, Process>;
pid_t
gettid()
{
return syscall(SYS_gettid);
}
}