wiringPi/wiringPiD/daemonise.c

83 lines
1.6 KiB
C

/*
* daemonise.c:
* Fairly generic "Turn the current process into a daemon" code.
*
* Copyright (c) 2016-2017 Gordon Henderson.
*********************************************************************************
*/
#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <syslog.h>
#include <signal.h>
#include <sys/stat.h>
#include "daemonise.h"
void daemonise (const char *pidFile)
{
pid_t pid ;
int i ;
FILE *fd ;
syslog (LOG_DAEMON | LOG_INFO, "Becoming daemon") ;
// Fork from the parent
if ((pid = fork ()) < 0)
{
syslog (LOG_DAEMON | LOG_ALERT, "Fork no. 1 failed: %m") ;
exit (EXIT_FAILURE) ;
}
if (pid > 0) // Parent - terminate
exit (EXIT_SUCCESS) ;
// Now running on the child - become session leader
if (setsid() < 0)
{
syslog (LOG_DAEMON | LOG_ALERT, "setsid failed: %m") ;
exit (EXIT_FAILURE) ;
}
// Ignore a few signals
signal (SIGCHLD, SIG_IGN) ;
signal (SIGHUP, SIG_IGN) ;
// Fork again
if ((pid = fork ()) < 0)
{
syslog (LOG_DAEMON | LOG_ALERT, "Fork no. 2 failed: %m") ;
exit (EXIT_FAILURE) ;
}
if (pid > 0) // parent - terminate
exit (EXIT_SUCCESS) ;
// Tidying up - reset umask, change to / and close all files
umask (0) ;
chdir ("/") ;
for (i = 0 ; i < sysconf (_SC_OPEN_MAX) ; ++i)
close (i) ;
// Write PID into /var/run
if (pidFile != NULL)
{
if ((fd = fopen (pidFile, "w")) == NULL)
{
syslog (LOG_DAEMON | LOG_ALERT, "Unable to write PID file: %m") ;
exit (EXIT_FAILURE) ;
}
fprintf (fd, "%d\n", getpid ()) ;
fclose (fd) ;
}
}