Last active
September 2, 2020 05:21
-
-
Save aryamansharda/1f1565bdeda9f1fd111db43745abae17 to your computer and use it in GitHub Desktop.
Basic implementation of a daemon in C
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
#include <stdio.h> | |
#include <stdlib.h> | |
#include <unistd.h> | |
#include <signal.h> | |
#include <sys/types.h> | |
#include <sys/stat.h> | |
#include <syslog.h> | |
static void create_daemon() | |
{ | |
pid_t pid; | |
/* Fork off the parent process */ | |
/* Remember fork() returns the child's PID in the parent */ | |
/* and return 0 as the PID to the child process */ | |
pid = fork(); | |
/* An error occurred */ | |
if (pid < 0) | |
exit(EXIT_FAILURE); | |
/* Success: Let the parent terminate */ | |
if (pid > 0) | |
exit(EXIT_SUCCESS); | |
/* On success: The child process becomes session leader */ | |
/* setsid() creates a session and returns the (new) session ID of the calling process */ | |
/* A session is a group of processes running under control of a single user */ | |
/* We use setsid() because if we just kill the parent the child will be killed too */ | |
/* Creating a session in the child process allows it to live even when the parent dies */ | |
if (setsid() < 0) | |
exit(EXIT_FAILURE); | |
/* Catch, ignore and handle signals */ | |
/* A signal is an asynchronous notification sent to a process or to a */ | |
/* specific thread within the same process in order to notify it of an event */ | |
/* that occurred. In the following 2 lines, we are intentionally ignoring the */ | |
/* SIGCHILD and SIGHUP signals */ | |
/* When a child process stops or terminates, SIGCHLD is sent to the parent process. */ | |
signal(SIGCHLD, SIG_IGN); | |
/* SIGHUP ("signal hang up") is a signal sent to a process when its controlling | |
/* terminal is closed. */ | |
signal(SIGHUP, SIG_IGN); | |
/* Fork off for the second time (more details about this after the code)*/ | |
pid = fork(); | |
/* An error occurred */ | |
if (pid < 0) | |
exit(EXIT_FAILURE); | |
/* Success: Let the parent terminate */ | |
if (pid > 0) | |
exit(EXIT_SUCCESS); | |
/* Set new file permissions */ | |
/* unmask() is used to control the file-creation mode mask, which determines */ | |
/* the initial value of file permission bits for newly created files. */ | |
/* ******************************************************************** */ | |
/* unmask(0) means that newly created files or directories created will have no | |
/* privileges initially revoked. In other words, a umask of zero will cause all */ | |
/* files to be created as 0666 or world-writable. Directories created while umask is | |
/* 0 will be 0777 */ | |
umask(0); | |
/* Change the working directory to the root directory */ | |
/* or another appropriated directory */ | |
chdir("/"); | |
/* Close all open file descriptors */ | |
/* sysconf() returns configuration information at run time */ | |
int x; | |
for (x = sysconf(_SC_OPEN_MAX); x>=0; x--) | |
{ | |
close (x); | |
} | |
} | |
int main() | |
{ | |
create_daemon(); | |
while (1) | |
{ | |
/* Respond to HTTP requests */ | |
/* Run time based operations (cron jobs) */ | |
/* Monitor disk health */ | |
/* Clean up unused resources */ | |
/* Any other process you want to run in the background */ | |
/* You could also introduce a delay between iterations */ | |
// sleep (20); | |
/* Or terminate the daeom when some other condition is met */ | |
// if (...) { | |
// break; | |
// } | |
} | |
return EXIT_SUCCESS; | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment