Creating a Unix Daemon
To quote Wikipedia,
In multitasking computer operating systems, a daemon (/ˈdiːmən/ or /ˈdeɪmən/)[1] is a computer program that runs as a background process, rather than being under the direct control of an interactive user.
In practice daemons are used any time a service needs to be accessible at a moment's notice. A good example would be a server applicaion. A server spends most of it's time sitting, waiting, for a request or connection that could come at any time; then honoring that request as quickly as possible.
Recently I created my first daemon, a TCP server for uploading gps data to the computer on a robot. So I wanted to document what I learned.
Here's how to create a minimal Unix daemon in C.
#include <sys/stat.h>
#include <stdio.h>
#include <unistd.h>
#include <errno.h>
int main()
{
// When you start the daemon initially the process that is spawned
// is attached to the user's current session. So the first a child
// process is spawned. fork() accomplishes this. From this point on you
// can think of your program now existing as two processes, both of which
// just finished executing the line below. One of these processes is the
// parent, the other is the child
pid_t pid = fork();
if(pid > 0){
printf("parent: the daemon's pid is %d\n", pid);
return -1; // the parent has nothing else to do, simply exit
}
else if(pid < 0){
// if the pid returned is -1, then the fork() failed.
printf("parent: and the daemon failed to start (%d).\n", errno);
return -2;
}
// if the pid is 0 then this process is the child
// setsid() makes the process the leader of a new session. This is the
// reason we had to fork() above. Since the parent was already the process
// group leader creating another session would fail.
if(setsid() < 0){
printf("daemon: I failed to create a new session.\n");
return -3;
}
// when the child is spawned all its' properties are inherited from
// the parent including the working directory as shown below
char workingDirectory[256];
char* wd = getwd(workingDirectory);
printf("daemon: current working directory is '%s'\n", wd);
// change the working directory appropriately. (to root for example)
chdir("/");
wd = getwd(workingDirectory);
printf("daemon: new current working directory is '%s'\n", wd);
// close whatever file descriptors might have been
// inherited from the parent, such as stdin stdout
for(int i = sysconf(_SC_OPEN_MAX); i--;){
close(i);
}
// stdio is closed, you won't hear anything more from the daemon
printf("daemon: now I'm silent!\n");
// like everything else, file permissions are also inherited from the
// parent process. This is an octal number which follows the chmod
// pattern. The default value is 022. (write access for owner only)
umask(022);
// keep the daemon alive for 10 seconds.
// here is where you would actually do some work :)
sleep(10);
return 0;
}