| /* |
| * 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) ; |
| } |
| } |