Skip to content

Instantly share code, notes, and snippets.

@twogood
Created July 11, 2012 15:08
Show Gist options
  • Save twogood/3091020 to your computer and use it in GitHub Desktop.
Save twogood/3091020 to your computer and use it in GitHub Desktop.
From a project I worked on back in 2004
#include "double_fork.hh"
#include <cstdlib>
#include <cerrno>
#include <sys/stat.h>
#include <sys/types.h>
#include <sys/wait.h>
#include <unistd.h>
#include <fcntl.h>
int double_fork()/*{{{*/
{
pid_t pid;
// First fork
pid = fork();
if (pid == 0)
{
// Child: second fork
pid = fork();
if (pid == 0)
{
// Child
return 0;
}
else if (pid > 0)
{
// Parent
exit(0);
}
else
{
// Error
exit(1);
}
}
else if (pid > 0)
{
// Parent: wait for child to exit
int status;
for (;;)
{
int result = waitpid(pid, &status, 0);
if (result < 0)
{
// Error
if (errno != EINTR)
return result;
}
else
break;
}
if (WIFEXITED(status) && WEXITSTATUS(status) == 0)
// The child exited with status 0 -- success!
return 1;
else
return -1;
}
else
{
// Error
return pid;
}
}/*}}}*/
bool double_fork_daemon()
{
bool success = false;
int result = double_fork();
if (result > 0)
{
// Parent
exit(0);
}
else if (result == 0)
{
// Child
success = true;
umask(0);
setsid();
chdir("/");
// Open these first, so they don't get STD(IN|OUT|ERR)_FILENO
int in = open("/dev/null", O_RDONLY, 0);
int out = open("/dev/null", O_WRONLY, 0);
// Close these
close(STDIN_FILENO);
close(STDOUT_FILENO);
close(STDERR_FILENO);
// Replace with /dev/null
dup2(in , STDIN_FILENO);
dup2(out, STDOUT_FILENO);
dup2(out, STDERR_FILENO);
close(in);
close(out);
}
// Error: fall through
return success;
}
#ifndef double_fork_hh
#define double_fork_hh
int double_fork();
bool double_fork_daemon();
#endif
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment