You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
82 lines
1.6 KiB
82 lines
1.6 KiB
/* |
|
* 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) ; |
|
} |
|
}
|
|
|