Creating a daemon in Linux
In Linux I want to add a daemon that cannot be stopped and which monitors filesystem changes. If any changes are detected, it should write the path to the console where it was started plus a newline. I already have the filesystem changing code almost ready but I cannot figure out how to create a daemon. My code is from here: http://www.yolinux.com/TUTORIALS/ForkExecProcesses.html What to do after the fork?
int main (int argc, char **argv) < pid_t pID = fork(); if (pID == 0) < // child // Code only executed by child process sIdentifier = "Child Process: "; >else if (pID < 0) < cerr else // parent < // Code only executed by parent process sIdentifier = "Parent Process:"; >return 0; >
possible duplicate of: stackoverflow.com/questions/5384168/… for the daemonize part, stackoverflow.com/questions/931093/… for the filesystem watch
If you don’t need POSIX compliance you may be interested in inotify API. See: inotify_init , inotify_add_watch , inotify_rm_watch .
9 Answers 9
In Linux i want to add a daemon that cannot be stopped and which monitors filesystem changes. If any changes would be detected it should write the path to the console where it was started + a newline.
Daemons work in the background and (usually. ) don’t belong to a TTY that’s why you can’t use stdout/stderr in the way you probably want. Usually a syslog daemon (syslogd) is used for logging messages to files (debug, error. ).
Besides that, there are a few required steps to daemonize a process.
If I remember correctly these steps are:
- fork off the parent process & let it terminate if forking was successful. -> Because the parent process has terminated, the child process now runs in the background.
- setsid — Create a new session. The calling process becomes the leader of the new session and the process group leader of the new process group. The process is now detached from its controlling terminal (CTTY).
- Catch signals — Ignore and/or handle signals.
- fork again & let the parent process terminate to ensure that you get rid of the session leading process. (Only session leaders may get a TTY again.)
- chdir — Change the working directory of the daemon.
- umask — Change the file mode mask according to the needs of the daemon.
- close — Close all open file descriptors that may be inherited from the parent process.
To give you a starting point: Look at this skeleton code that shows the basic steps. This code can now also be forked on GitHub: Basic skeleton of a linux daemon
/* * daemonize.c * This example daemonizes a process, writes a few log messages, * sleeps 20 seconds and terminates afterwards. */ #include #include #include #include #include #include #include static void skeleton_daemon() < pid_t pid; /* Fork off the parent 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 */ if (setsid() < 0) exit(EXIT_FAILURE); /* Catch, ignore and handle signals */ //TODO: Implement a working signal handler */ signal(SIGCHLD, SIG_IGN); signal(SIGHUP, SIG_IGN); /* Fork off for the second time*/ 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 */ umask(0); /* Change the working directory to the root directory */ /* or another appropriated directory */ chdir("/"); /* Close all open file descriptors */ int x; for (x = sysconf(_SC_OPEN_MAX); x>=0; x--) < close (x); >/* Open the log file */ openlog ("firstdaemon", LOG_PID, LOG_DAEMON); >
int main() < skeleton_daemon(); while (1) < //TODO: Insert daemon code here. syslog (LOG_NOTICE, "First daemon started."); sleep (20); break; >syslog (LOG_NOTICE, "First daemon terminated."); closelog(); return EXIT_SUCCESS; >
- Compile the code: gcc -o firstdaemon daemonize.c
- Start the daemon: ./firstdaemon
- Check if everything is working properly: ps -xj | grep firstdaemon
- The output should be similar to this one:
+------+------+------+------+-----+-------+------+------+------+-----+ | PPID | PID | PGID | SID | TTY | TPGID | STAT | UID | TIME | CMD | +------+------+------+------+-----+-------+------+------+------+-----+ | 1 | 3387 | 3386 | 3386 | ? | -1 | S | 1000 | 0:00 | ./ | +------+------+------+------+-----+-------+------+------+------+-----+
What you should see here is:
- The daemon has no controlling terminal (TTY = ?)
- The parent process ID (PPID) is 1 (The init process)
- The PID != SID which means that our process is NOT the session leader
(because of the second fork()) - Because PID != SID our process can’t take control of a TTY again
Reading the syslog:
- Locate your syslog file. Mine is here: /var/log/syslog
- Do a: grep firstdaemon /var/log/syslog
- The output should be similar to this one:
firstdaemon[3387]: First daemon started. firstdaemon[3387]: First daemon terminated.
A note: In reality you would also want to implement a signal handler and set up the logging properly (Files, log levels. ).
Further reading:
How to Create a Daemon on Linux
Daemons are processes that silently run in the background on your machine. Here’s how you can code your own daemons on Linux.
Readers like you help support MUO. When you make a purchase using links on our site, we may earn an affiliate commission. Read More.
Daemons are processes that do not run directly under the control of the user but serve in the background. Usually, they start on system startup and run continuously until the system shuts down. The only difference between these and normal processes is that they do not send messages to the console or screen in any way.
Here’s how you can create a daemon on a Linux machine.
A Brief Introduction to How Daemons Are Created
A lot of daemons run on the system and some familiar daemon examples are as follows:
- crond: Makes commands run at the specified time
- sshd: Allows login to the system from remote machines
- httpd: Serves web pages
- nfsd: Allows file sharing over the network
Also, daemon processes are usually named to end with the letter d, although it’s not mandatory.
For a process to run as a daemon, the following path is followed:
- Initial operations, such as reading configuration files or obtaining necessary system resources, must be performed before the process becomes a daemon. This way, the system can report the received errors to the user and the process will be terminated with an appropriate error code.
- A background running process is created with init as its parent process. For this purpose, a sub-process is forked from the init process first, and then the upper process is terminated with exit.
- A new session should open by calling the setsid function, and the process should be disconnected from the terminal.
- All open file descriptors inherited from the parent process are closed.
- Standard input, output, and error messages are redirected to /dev/null.
- The working directory of the process must change.
What Are Daemon Sessions?
After logging into the system via a terminal, users can run many applications through the shell program. These processes should close when the user exits the system. The operating system groups these processes into session and process groups.
Each session consists of process groups. You can describe this situation as follows:
The terminal where the processes receive their inputs and send their outputs is called the controlling terminal. A controlling terminal is associated with only one session at a time.
A session and the process groups in it have identification (ID) numbers; these identification numbers are the process identification numbers (PID) of the session and process group leaders. A child process shares the same group as its parent process. When multiple processes are communicating with the pipe mechanism, the first process becomes the process group leader.
Creating a Daemon Process on Linux
Here you will see how you can create a daemon function. For this purpose, you will create a function named _daemon. You can start by naming the application code that will run as a daemon as test.c, and the code that you will create the daemon function as daemon.c.
//test.c
#include stdio.h>
int _daemon(int, int);
int main()
getchar();
_daemon(0, 0);
getchar();
return 0;
>
//daemon.c
#include
#include
#include stdlib.h>
#include stdio.h>
#include fcntl.h>
#include unistd.h>
#include
#include
int _daemon(int nochdir, int noclose) pid_t pid;
pid = fork(); // Fork off the parent process
if (pid < 0) exit(EXIT_FAILURE);
>
if (pid > 0) exit(EXIT_SUCCESS);
>
return 0;
>
To create a daemon, you need a background process whose parent process is init. In the code above, _daemon creates a child process and then kills the parent process. In this case, your new process will be a subprocess of init and will continue to run in the background.
Now compile the application with the following command and examine the status of the process before and after _deamon is called:
Run the application and switch to a different terminal without pressing any other keys:
You can see that the values related to your process are as follows. Here, you’ll have to use the ps command to get process-related information. In this case, the _daemon function has not been called yet.
ps -C test -o "pid ppid pgid sid tty stat command"
# Output
PID PPID PGID SID TT STAT COMMAND
10296 5119 10296 5117 pts/2 S+ ./test
When you look at the STAT field, you see that your process is running but waiting for an off-schedule event to occur which will cause it to run in the foreground.