SlideShare a Scribd company logo
Linux Daemon Writing HOWTO
Devin Watson <mailto:dmwatson@comcast.net>                                                            v1.0, May 2004


This document shows how to write a daemon in Linux using GCC. Knowledge of Linux and a familiarity with C
are necessary to use this document. This HOWTO is Copyright by Devin Watson, under the terms of the BSD
License.



Contents

1 Introduction: What is a Daemon?                                                                                    1

2 Getting Started                                                                                                    2

3 Planning Your Daemon                                                                                               2
    3.1   What Is It Going To Do? . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .        2
    3.2   How Much Interaction? . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .        2

4 Basic Daemon Structure                                                                                             2
    4.1   Forking The Parent Process . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .       3
    4.2   Changing The File Mode Mask (Umask) . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .            3
    4.3   Opening Logs For Writing . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .       4
    4.4   Creating a Unique Session ID (SID) . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .         4
    4.5   Changing The Working Directory . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .         4
    4.6   Closing Standard File Descriptors . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .      5

5 Writing the Daemon Code                                                                                            6
    5.1   Initialization . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .   6
    5.2   The Big Loop . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .     6

6 Putting It All Together                                                                                            7
    6.1   Complete Sample . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .      7



1     Introduction: What is a Daemon?
A daemon (or service) is a background process is designed to run autonomously,with little or no user in-
tervention. The Apache web server http daemon (httpd) is one such example of a daemon. It waits in the
background listening on specific ports and serves up pages, or processes scripts, based on the type of request.
Creating a daemon in Linux uses a specific set of rules in a given order. Knowing how they work will help you
understand how daemons operate in userland Linux, but can also operate with calls to the kernel. In fact,
a few daemons interface with kernel modules that work with hardware devices, such as external controller
2. Getting Started                                                                                         2



boards, printers, and PDAs. They are one of the fundamental building blocks in Linux that give it incredible
flexibility and power.
Throughout this HOWTO, a very simple daemon will be built in C. As we go along, more code will be
added, showing the proper order of execution required to get a daemon up and running.



2     Getting Started
First off, you’ll need the following packages installed on your Linux machine to develop daemons, specifically:

    • GCC 3.2.2 or higher

    • Linux Development headers and libraries

If your system does not already have these installed (not likely, but check anyway), you’ll need them to
develop the examples in this HOWTO. To find out what version of GCC you have installed, use:

              gcc --version



3     Planning Your Daemon

3.1    What Is It Going To Do?

A daemon should do one thing, and do it well. That one thing may be as complex as managing hundreds of
mailboxes on multiple domains, or as simple as writing a report and calling sendmail to mail it out.
In any case, you should have a good plan as to what the daemon should do. If it is going to interoperate
with other daemons (which you may or may not be writing), this is something else to consider as well.


3.2    How Much Interaction?

Daemons should never have direct communication with a user through a terminal. In fact, a daemon
shouldn’t communicate directly with a user at all. All communication should pass through some sort of
interface (which you may or may not have to write), which can be as complex as a GTK+ GUI, or as simple
as a signal set.



4     Basic Daemon Structure
When a daemon starts up, it has to do some low-level housework to get itself ready for its real job. This
involves a few steps:

    • Fork off the parent process

    • Change file mode mask (umask)

    • Open logs for writing

    • Create a unique Session ID (SID)

    • Change the current working directory to a safe place
4. Basic Daemon Structure                                                                               3



   • Close standard file descriptors

   • Enter actual daemon code


4.1   Forking The Parent Process

A daemon is started either by the system itself or a user in a terminal or script. When it does start, the
process is just like any other executable on the system. To make it truly autonomous, a child process must
be created where the actual code is executed. This is known as forking, and it uses the fork() function:

              pid_t pid;

              /* Fork off the parent process */
              pid = fork();
              if (pid < 0) {
                      exit(EXIT_FAILURE);
              }
              /* If we got a good PID, then
                 we can exit the parent process. */
              if (pid > 0) {
                      exit(EXIT_SUCCESS);
              }


Notice the error check right after the call to fork(). When writing a daemon, you will have to code as
defensively as possible. In fact, a good percentage of the total code in a daemon consists of nothing but
error checking.
The fork() function returns either the process id (PID) of the child process (not equal to zero), or -1 on
failure. If the process cannot fork a child, then the daemon should terminate right here.
If fork() did succeed, the parent process must exit gracefully. This may seem strange to anyone who hasn’t
seen it, but by forking, the child process continues the execution from here on out in the code.


4.2   Changing The File Mode Mask (Umask)

In order to write to any files (including logs) created by the daemon, the file mode mask (umask) must be
changed to ensure that they can be written to or read from properly. This is similar to running umask from
the command line, but we do it programmatically here. We can use the umask() function to accomplish this:

              pid_t pid, sid;

              /* Fork off the parent process */
              pid = fork();
              if (pid < 0) {
                      /* Log failure (use syslog if possible) */
                      exit(EXIT_FAILURE);
              }
              /* If we got a good PID, then
                 we can exit the parent process. */
              if (pid > 0) {
                      exit(EXIT_SUCCESS);
              }
4. Basic Daemon Structure                                                                                   4



              /* Change the file mode mask */
              umask(0);



By setting the umask to 0, we will have full access to the files generated by the daemon. Even if you aren’t
planning on using any files, it is a good idea to set the umask here anyway, just in case you will be accessing
files on the filesystem.


4.3    Opening Logs For Writing

This part is optional, but it is recommended that you open a log file somewhere in the system for writing.
This may be the only place you can look for debug information about your daemon.


4.4    Creating a Unique Session ID (SID)

From here, the child process must get a unique SID from the kernel in order to operate. Otherwise, the child
process becomes an orphan in the system. The pid t type, declared in the previous section, is also used to
create a new SID for the child process:

              pid_t pid, sid;

              /* Fork off the parent process */
              pid = fork();
              if (pid < 0) {
                      exit(EXIT_FAILURE);
              }
              /* If we got a good PID, then
                 we can exit the parent process. */
              if (pid > 0) {
                      exit(EXIT_SUCCESS);
              }

              /* Change the file mode mask */
              umask(0);

              /* Open any logs here */

              /* Create a new SID for the child process */
              sid = setsid();
              if (sid < 0) {
                      /* Log any failure */
                      exit(EXIT_FAILURE);
              }

Again, the setsid() function has the same return type as fork(). We can apply the same error-checking
routine here to see if the function created the SID for the child process.


4.5    Changing The Working Directory

The current working directory should be changed to some place that is guaranteed to always be there.
Since many Linux distributions do not completely follow the Linux Filesystem Hierarchy standard, the only
directory that is guaranteed to be there is the root directory (/). We can do this using the chdir() function:
4. Basic Daemon Structure                                                                                 5



              pid_t pid, sid;

              /* Fork off the parent process */
              pid = fork();
              if (pid < 0) {
                      exit(EXIT_FAILURE);
              }
              /* If we got a good PID, then
                 we can exit the parent process. */
              if (pid > 0) {
                      exit(EXIT_SUCCESS);
              }

              /* Change the file mode mask */
              umask(0);

              /* Open any logs here */

              /* Create a new SID for the child process */
              sid = setsid();
              if (sid < 0) {
                      /* Log any failure here */
                      exit(EXIT_FAILURE);
              }

              /* Change the current working directory */
              if ((chdir(quot;/quot;)) < 0) {
                      /* Log any failure here */
                      exit(EXIT_FAILURE);
              }



Once again, you can see the defensive coding taking place. The chdir() function returns -1 on failure, so be
sure to check for that after changing to the root directory within the daemon.


4.6    Closing Standard File Descriptors

One of the last steps in setting up a daemon is closing out the standard file descriptors (STDIN, STDOUT,
STDERR). Since a daemon must not use the terminal, these file descriptors are both redundant and a
potential security hazard.
The close() function can handle this for us:

              pid_t pid, sid;

              /* Fork off the parent process */
              pid = fork();
              if (pid < 0) {
                      exit(EXIT_FAILURE);
              }
              /* If we got a good PID, then
                 we can exit the parent process. */
              if (pid > 0) {
                      exit(EXIT_SUCCESS);
5. Writing the Daemon Code                                                                                     6



               }

               /* Change the file mode mask */
               umask(0);

               /* Open any logs here */

               /* Create a new SID for the child process */
               sid = setsid();
               if (sid < 0) {
                       /* Log any failure here */
                       exit(EXIT_FAILURE);
               }

               /* Change the current working directory */
               if ((chdir(quot;/quot;)) < 0) {
                       /* Log any failure here */
                       exit(EXIT_FAILURE);
               }



               /* Close out the standard file descriptors */
               close(STDIN_FILENO);
               close(STDOUT_FILENO);
               close(STDERR_FILENO);


It’s a good idea to stick with the constants defined for the file descriptors, for the greatest portability between
system versions.



5     Writing the Daemon Code

5.1    Initialization

At this point, you have basically told Linux that you’re a daemon, so now it’s time to write the actual
daemon code. Initialization is the first step here. Since there can be a multitude of different functions that
can be called here to set up your daemon’s task, I won’t go too deep into them here.
The big point here is, when initializing anything in a daemon, the same defensive coding guidelines apply.
Be as verbose as possible when writing either to the syslog or your own logs. Debugging a daemon can be
quite difficult when there isn’t enough information available as to the status of the daemon.


5.2    The Big Loop

A daemon’s main code is typically inside an infinite loop. Technically, it isn’t an infinite loop, but it is
structured as one:

               pid_t pid, sid;

               /* Fork off the parent process */
               pid = fork();
               if (pid < 0) {
                       exit(EXIT_FAILURE);
6. Putting It All Together                                                                                7



              }
              /* If we got a good PID, then
                 we can exit the parent process. */
              if (pid > 0) {
                      exit(EXIT_SUCCESS);
              }

              /* Change the file mode mask */
              umask(0);

              /* Open any logs here */

              /* Create a new SID for the child process */
              sid = setsid();
              if (sid < 0) {
                      /* Log any failures here */
                      exit(EXIT_FAILURE);
              }



              /* Change the current working directory */
              if ((chdir(quot;/quot;)) < 0) {
                      /* Log any failures here */
                      exit(EXIT_FAILURE);
              }

              /* Close out the standard file descriptors */
              close(STDIN_FILENO);
              close(STDOUT_FILENO);
              close(STDERR_FILENO);

              /* Daemon-specific initialization goes here */

              /* The Big Loop */
              while (1) {
                 /* Do some task here ... */
                 sleep(30); /* wait 30 seconds */
              }


This typical loop is usually a while loop that has an infinite terminating condition, with a call to sleep in
there to make it run at specified intervals.
Think of it like a heartbeat: when your heart beats, it performs a few tasks, then waits until the next beat
takes place. Many daemons follow this same methodology.



6     Putting It All Together

6.1    Complete Sample

Listed below is a complete sample daemon that shows all of the steps necessary for setup and execution. To
run this, simply compile using gcc, and start execution from the command line. To terminate, use the kill
command after finding its PID.
I’ve also put in the include statements for interfacing with the syslog, recommended (at the very
6. Putting It All Together                                                                       8



least) for sending start/stop/pause/die log statements, in addition to using your own logs with the
fopen()/fwrite()/fclose() function calls.

     #include   <sys/types.h>
     #include   <sys/stat.h>
     #include   <stdio.h>
     #include   <stdlib.h>
     #include   <fcntl.h>
     #include   <errno.h>
     #include   <unistd.h>
     #include   <syslog.h>
     #include   <string.h>

     int main(void) {

                /* Our process ID and Session ID */
                pid_t pid, sid;

                /* Fork off the parent process */
                pid = fork();
                if (pid < 0) {
                        exit(EXIT_FAILURE);
                }
                /* If we got a good PID, then
                   we can exit the parent process. */
                if (pid > 0) {
                        exit(EXIT_SUCCESS);
                }

                /* Change the file mode mask */
                umask(0);

                /* Open any logs here */

                /* Create a new SID for the child process */
                sid = setsid();
                if (sid < 0) {
                        /* Log the failure */
                        exit(EXIT_FAILURE);
                }

                /* Change the current working directory */
                if ((chdir(quot;/quot;)) < 0) {
                        /* Log the failure */
                        exit(EXIT_FAILURE);
                }

                /* Close out the standard file descriptors */
                close(STDIN_FILENO);
                close(STDOUT_FILENO);
                close(STDERR_FILENO);

                /* Daemon-specific initialization goes here */

                /* The Big Loop */
6. Putting It All Together                                                                            9



             while (1) {
                /* Do some task here ... */

                sleep(30); /* wait 30 seconds */
             }
             exit(EXIT_SUCCESS);
     }


From here, you should be able to use this skeleton to write your own daemons. Be sure to add in your own
logging (or use the syslog facility). Finally, code defensively, code defensively, code defensively!

More Related Content

What's hot

Docker security
Docker securityDocker security
Docker security
Janos Suto
 
PuppetConf 2016: Nano Server, Puppet, and DSC
PuppetConf 2016: Nano Server, Puppet, and DSCPuppetConf 2016: Nano Server, Puppet, and DSC
PuppetConf 2016: Nano Server, Puppet, and DSC
Michael Smith
 
Component pack 6006 install guide
Component pack 6006 install guideComponent pack 6006 install guide
Component pack 6006 install guide
Roberto Boccadoro
 
Linux con europe_2014_f
Linux con europe_2014_fLinux con europe_2014_f
Linux con europe_2014_f
sprdd
 
Thinking outside the box, learning a little about a lot
Thinking outside the box, learning a little about a lotThinking outside the box, learning a little about a lot
Thinking outside the box, learning a little about a lot
Mark Broadbent
 
Kdump-FUDcon-2015-Workshop
Kdump-FUDcon-2015-WorkshopKdump-FUDcon-2015-Workshop
Kdump-FUDcon-2015-WorkshopBuland Singh
 
Add a bit of ACID to Cassandra. Cassandra Summit EU 2014
Add a bit of ACID to Cassandra. Cassandra Summit EU 2014Add a bit of ACID to Cassandra. Cassandra Summit EU 2014
Add a bit of ACID to Cassandra. Cassandra Summit EU 2014
odnoklassniki.ru
 
Ex200
Ex200Ex200
Automated master failover
Automated master failoverAutomated master failover
Automated master failover
Yoshinori Matsunobu
 
Comparação entre XenServer 6.2 e VMware VSphere 5.1 - Comparison of Citrix Xe...
Comparação entre XenServer 6.2 e VMware VSphere 5.1 - Comparison of Citrix Xe...Comparação entre XenServer 6.2 e VMware VSphere 5.1 - Comparison of Citrix Xe...
Comparação entre XenServer 6.2 e VMware VSphere 5.1 - Comparison of Citrix Xe...Lorscheider Santiago
 
Containers with systemd-nspawn
Containers with systemd-nspawnContainers with systemd-nspawn
Containers with systemd-nspawn
Gábor Nyers
 
Anatomy of a Container: Namespaces, cgroups & Some Filesystem Magic - LinuxCon
Anatomy of a Container: Namespaces, cgroups & Some Filesystem Magic - LinuxConAnatomy of a Container: Namespaces, cgroups & Some Filesystem Magic - LinuxCon
Anatomy of a Container: Namespaces, cgroups & Some Filesystem Magic - LinuxCon
Jérôme Petazzoni
 
Installation of Subversion on Ubuntu,...
Installation of Subversion on Ubuntu,...Installation of Subversion on Ubuntu,...
Installation of Subversion on Ubuntu,...wensheng wei
 
rgpv 7th sem for it & cs Cloud computing lab record
rgpv 7th sem for it & cs Cloud computing lab recordrgpv 7th sem for it & cs Cloud computing lab record
rgpv 7th sem for it & cs Cloud computing lab recordnaaaaz
 

What's hot (17)

Docker security
Docker securityDocker security
Docker security
 
PuppetConf 2016: Nano Server, Puppet, and DSC
PuppetConf 2016: Nano Server, Puppet, and DSCPuppetConf 2016: Nano Server, Puppet, and DSC
PuppetConf 2016: Nano Server, Puppet, and DSC
 
Component pack 6006 install guide
Component pack 6006 install guideComponent pack 6006 install guide
Component pack 6006 install guide
 
Lab docker
Lab dockerLab docker
Lab docker
 
Linux con europe_2014_f
Linux con europe_2014_fLinux con europe_2014_f
Linux con europe_2014_f
 
Thinking outside the box, learning a little about a lot
Thinking outside the box, learning a little about a lotThinking outside the box, learning a little about a lot
Thinking outside the box, learning a little about a lot
 
Kdump-FUDcon-2015-Workshop
Kdump-FUDcon-2015-WorkshopKdump-FUDcon-2015-Workshop
Kdump-FUDcon-2015-Workshop
 
Add a bit of ACID to Cassandra. Cassandra Summit EU 2014
Add a bit of ACID to Cassandra. Cassandra Summit EU 2014Add a bit of ACID to Cassandra. Cassandra Summit EU 2014
Add a bit of ACID to Cassandra. Cassandra Summit EU 2014
 
Ex200
Ex200Ex200
Ex200
 
Automated master failover
Automated master failoverAutomated master failover
Automated master failover
 
Comparação entre XenServer 6.2 e VMware VSphere 5.1 - Comparison of Citrix Xe...
Comparação entre XenServer 6.2 e VMware VSphere 5.1 - Comparison of Citrix Xe...Comparação entre XenServer 6.2 e VMware VSphere 5.1 - Comparison of Citrix Xe...
Comparação entre XenServer 6.2 e VMware VSphere 5.1 - Comparison of Citrix Xe...
 
Containers with systemd-nspawn
Containers with systemd-nspawnContainers with systemd-nspawn
Containers with systemd-nspawn
 
Corba 2
Corba 2Corba 2
Corba 2
 
Freeradius edir
Freeradius edirFreeradius edir
Freeradius edir
 
Anatomy of a Container: Namespaces, cgroups & Some Filesystem Magic - LinuxCon
Anatomy of a Container: Namespaces, cgroups & Some Filesystem Magic - LinuxConAnatomy of a Container: Namespaces, cgroups & Some Filesystem Magic - LinuxCon
Anatomy of a Container: Namespaces, cgroups & Some Filesystem Magic - LinuxCon
 
Installation of Subversion on Ubuntu,...
Installation of Subversion on Ubuntu,...Installation of Subversion on Ubuntu,...
Installation of Subversion on Ubuntu,...
 
rgpv 7th sem for it & cs Cloud computing lab record
rgpv 7th sem for it & cs Cloud computing lab recordrgpv 7th sem for it & cs Cloud computing lab record
rgpv 7th sem for it & cs Cloud computing lab record
 

Viewers also liked

Web Feeds
Web FeedsWeb Feeds
Web Feedsakshat
 
intro unix/linux 08
intro unix/linux 08intro unix/linux 08
intro unix/linux 08
duquoi
 
1. Scaling PHP/MySQL...Presentation from Flickr
	
1.	
Scaling PHP/MySQL...Presentation from Flickr	
1.	
Scaling PHP/MySQL...Presentation from Flickr
1. Scaling PHP/MySQL...Presentation from Flickrakshat
 
Process creation and termination In Operating System
Process creation and termination In Operating SystemProcess creation and termination In Operating System
Process creation and termination In Operating System
Farhan Aslam
 
System call (Fork +Exec)
System call (Fork +Exec)System call (Fork +Exec)
System call (Fork +Exec)
Amit Ghosh
 
Linux Programming
Linux ProgrammingLinux Programming
Linux process management
Linux process managementLinux process management
Linux process managementRaghu nath
 
Linux sever building
Linux sever buildingLinux sever building
Linux sever buildingEdmond Yu
 

Viewers also liked (8)

Web Feeds
Web FeedsWeb Feeds
Web Feeds
 
intro unix/linux 08
intro unix/linux 08intro unix/linux 08
intro unix/linux 08
 
1. Scaling PHP/MySQL...Presentation from Flickr
	
1.	
Scaling PHP/MySQL...Presentation from Flickr	
1.	
Scaling PHP/MySQL...Presentation from Flickr
1. Scaling PHP/MySQL...Presentation from Flickr
 
Process creation and termination In Operating System
Process creation and termination In Operating SystemProcess creation and termination In Operating System
Process creation and termination In Operating System
 
System call (Fork +Exec)
System call (Fork +Exec)System call (Fork +Exec)
System call (Fork +Exec)
 
Linux Programming
Linux ProgrammingLinux Programming
Linux Programming
 
Linux process management
Linux process managementLinux process management
Linux process management
 
Linux sever building
Linux sever buildingLinux sever building
Linux sever building
 

Similar to Linux Daemon Writting

Apache Web server Complete Guide
Apache Web server Complete GuideApache Web server Complete Guide
Apache Web server Complete Guidewebhostingguy
 
Apache Web server Complete Guide
Apache Web server Complete GuideApache Web server Complete Guide
Apache Web server Complete Guidewebhostingguy
 
Installing & Configuring IBM Domino 9 on CentOS
Installing & Configuring IBM Domino 9 on CentOSInstalling & Configuring IBM Domino 9 on CentOS
Installing & Configuring IBM Domino 9 on CentOS
Devin Olson
 
OS_lab_file.pdf
OS_lab_file.pdfOS_lab_file.pdf
OS_lab_file.pdf
KarthickS942388
 
Install nagios
Install nagiosInstall nagios
Install nagioshassandb
 
Install nagios
Install nagiosInstall nagios
Install nagioshassandb
 
Joxean Koret - Database Security Paradise [Rooted CON 2011]
Joxean Koret - Database Security Paradise [Rooted CON 2011]Joxean Koret - Database Security Paradise [Rooted CON 2011]
Joxean Koret - Database Security Paradise [Rooted CON 2011]RootedCON
 
Joanna Rutkowska Subverting Vista Kernel
Joanna Rutkowska   Subverting Vista KernelJoanna Rutkowska   Subverting Vista Kernel
Joanna Rutkowska Subverting Vista Kernelguestf1a032
 
Real-World Docker: 10 Things We've Learned
Real-World Docker: 10 Things We've Learned  Real-World Docker: 10 Things We've Learned
Real-World Docker: 10 Things We've Learned
RightScale
 
Integrating ibm tivoli workload scheduler and content manager on demand to pr...
Integrating ibm tivoli workload scheduler and content manager on demand to pr...Integrating ibm tivoli workload scheduler and content manager on demand to pr...
Integrating ibm tivoli workload scheduler and content manager on demand to pr...Banking at Ho Chi Minh city
 
Integrating ibm tivoli workload scheduler and content manager on demand to pr...
Integrating ibm tivoli workload scheduler and content manager on demand to pr...Integrating ibm tivoli workload scheduler and content manager on demand to pr...
Integrating ibm tivoli workload scheduler and content manager on demand to pr...Banking at Ho Chi Minh city
 
Us 17-krug-hacking-severless-runtimes
Us 17-krug-hacking-severless-runtimesUs 17-krug-hacking-severless-runtimes
Us 17-krug-hacking-severless-runtimes
Ravishankar Somasundaram
 
Big Data: Explore Hadoop and BigInsights self-study lab
Big Data:  Explore Hadoop and BigInsights self-study labBig Data:  Explore Hadoop and BigInsights self-study lab
Big Data: Explore Hadoop and BigInsights self-study lab
Cynthia Saracco
 
Ecc6 sr3 ora_win_instguide
Ecc6 sr3 ora_win_instguideEcc6 sr3 ora_win_instguide
Ecc6 sr3 ora_win_instguide
yashkr571
 
Percona Cluster Installation with High Availability
Percona Cluster Installation with High AvailabilityPercona Cluster Installation with High Availability
Percona Cluster Installation with High AvailabilityRam Gautam
 
Dependencies Managers in C/C++. Using stdcpp 2014
Dependencies Managers in C/C++. Using stdcpp 2014Dependencies Managers in C/C++. Using stdcpp 2014
Dependencies Managers in C/C++. Using stdcpp 2014
biicode
 
Crash dump analysis - experience sharing
Crash dump analysis - experience sharingCrash dump analysis - experience sharing
Crash dump analysis - experience sharingJames Hsieh
 
Check Your Privilege (Escalation)
Check Your Privilege (Escalation) Check Your Privilege (Escalation)
Check Your Privilege (Escalation)
Bishop Fox
 

Similar to Linux Daemon Writting (20)

Apache Web server Complete Guide
Apache Web server Complete GuideApache Web server Complete Guide
Apache Web server Complete Guide
 
Apache Web server Complete Guide
Apache Web server Complete GuideApache Web server Complete Guide
Apache Web server Complete Guide
 
Installing & Configuring IBM Domino 9 on CentOS
Installing & Configuring IBM Domino 9 on CentOSInstalling & Configuring IBM Domino 9 on CentOS
Installing & Configuring IBM Domino 9 on CentOS
 
OS_lab_file.pdf
OS_lab_file.pdfOS_lab_file.pdf
OS_lab_file.pdf
 
Install nagios
Install nagiosInstall nagios
Install nagios
 
Install nagios
Install nagiosInstall nagios
Install nagios
 
Joxean Koret - Database Security Paradise [Rooted CON 2011]
Joxean Koret - Database Security Paradise [Rooted CON 2011]Joxean Koret - Database Security Paradise [Rooted CON 2011]
Joxean Koret - Database Security Paradise [Rooted CON 2011]
 
Joanna Rutkowska Subverting Vista Kernel
Joanna Rutkowska   Subverting Vista KernelJoanna Rutkowska   Subverting Vista Kernel
Joanna Rutkowska Subverting Vista Kernel
 
Real-World Docker: 10 Things We've Learned
Real-World Docker: 10 Things We've Learned  Real-World Docker: 10 Things We've Learned
Real-World Docker: 10 Things We've Learned
 
Network Manual
Network ManualNetwork Manual
Network Manual
 
Integrating ibm tivoli workload scheduler and content manager on demand to pr...
Integrating ibm tivoli workload scheduler and content manager on demand to pr...Integrating ibm tivoli workload scheduler and content manager on demand to pr...
Integrating ibm tivoli workload scheduler and content manager on demand to pr...
 
Integrating ibm tivoli workload scheduler and content manager on demand to pr...
Integrating ibm tivoli workload scheduler and content manager on demand to pr...Integrating ibm tivoli workload scheduler and content manager on demand to pr...
Integrating ibm tivoli workload scheduler and content manager on demand to pr...
 
Us 17-krug-hacking-severless-runtimes
Us 17-krug-hacking-severless-runtimesUs 17-krug-hacking-severless-runtimes
Us 17-krug-hacking-severless-runtimes
 
Big Data: Explore Hadoop and BigInsights self-study lab
Big Data:  Explore Hadoop and BigInsights self-study labBig Data:  Explore Hadoop and BigInsights self-study lab
Big Data: Explore Hadoop and BigInsights self-study lab
 
Ecc6 sr3 ora_win_instguide
Ecc6 sr3 ora_win_instguideEcc6 sr3 ora_win_instguide
Ecc6 sr3 ora_win_instguide
 
Percona Cluster Installation with High Availability
Percona Cluster Installation with High AvailabilityPercona Cluster Installation with High Availability
Percona Cluster Installation with High Availability
 
Dependencies Managers in C/C++. Using stdcpp 2014
Dependencies Managers in C/C++. Using stdcpp 2014Dependencies Managers in C/C++. Using stdcpp 2014
Dependencies Managers in C/C++. Using stdcpp 2014
 
Zurg part 1
Zurg part 1Zurg part 1
Zurg part 1
 
Crash dump analysis - experience sharing
Crash dump analysis - experience sharingCrash dump analysis - experience sharing
Crash dump analysis - experience sharing
 
Check Your Privilege (Escalation)
Check Your Privilege (Escalation) Check Your Privilege (Escalation)
Check Your Privilege (Escalation)
 

Recently uploaded

ODC, Data Fabric and Architecture User Group
ODC, Data Fabric and Architecture User GroupODC, Data Fabric and Architecture User Group
ODC, Data Fabric and Architecture User Group
CatarinaPereira64715
 
From Daily Decisions to Bottom Line: Connecting Product Work to Revenue by VP...
From Daily Decisions to Bottom Line: Connecting Product Work to Revenue by VP...From Daily Decisions to Bottom Line: Connecting Product Work to Revenue by VP...
From Daily Decisions to Bottom Line: Connecting Product Work to Revenue by VP...
Product School
 
From Siloed Products to Connected Ecosystem: Building a Sustainable and Scala...
From Siloed Products to Connected Ecosystem: Building a Sustainable and Scala...From Siloed Products to Connected Ecosystem: Building a Sustainable and Scala...
From Siloed Products to Connected Ecosystem: Building a Sustainable and Scala...
Product School
 
IOS-PENTESTING-BEGINNERS-PRACTICAL-GUIDE-.pptx
IOS-PENTESTING-BEGINNERS-PRACTICAL-GUIDE-.pptxIOS-PENTESTING-BEGINNERS-PRACTICAL-GUIDE-.pptx
IOS-PENTESTING-BEGINNERS-PRACTICAL-GUIDE-.pptx
Abida Shariff
 
Software Delivery At the Speed of AI: Inflectra Invests In AI-Powered Quality
Software Delivery At the Speed of AI: Inflectra Invests In AI-Powered QualitySoftware Delivery At the Speed of AI: Inflectra Invests In AI-Powered Quality
Software Delivery At the Speed of AI: Inflectra Invests In AI-Powered Quality
Inflectra
 
Designing Great Products: The Power of Design and Leadership by Chief Designe...
Designing Great Products: The Power of Design and Leadership by Chief Designe...Designing Great Products: The Power of Design and Leadership by Chief Designe...
Designing Great Products: The Power of Design and Leadership by Chief Designe...
Product School
 
Builder.ai Founder Sachin Dev Duggal's Strategic Approach to Create an Innova...
Builder.ai Founder Sachin Dev Duggal's Strategic Approach to Create an Innova...Builder.ai Founder Sachin Dev Duggal's Strategic Approach to Create an Innova...
Builder.ai Founder Sachin Dev Duggal's Strategic Approach to Create an Innova...
Ramesh Iyer
 
"Impact of front-end architecture on development cost", Viktor Turskyi
"Impact of front-end architecture on development cost", Viktor Turskyi"Impact of front-end architecture on development cost", Viktor Turskyi
"Impact of front-end architecture on development cost", Viktor Turskyi
Fwdays
 
When stars align: studies in data quality, knowledge graphs, and machine lear...
When stars align: studies in data quality, knowledge graphs, and machine lear...When stars align: studies in data quality, knowledge graphs, and machine lear...
When stars align: studies in data quality, knowledge graphs, and machine lear...
Elena Simperl
 
JMeter webinar - integration with InfluxDB and Grafana
JMeter webinar - integration with InfluxDB and GrafanaJMeter webinar - integration with InfluxDB and Grafana
JMeter webinar - integration with InfluxDB and Grafana
RTTS
 
FIDO Alliance Osaka Seminar: The WebAuthn API and Discoverable Credentials.pdf
FIDO Alliance Osaka Seminar: The WebAuthn API and Discoverable Credentials.pdfFIDO Alliance Osaka Seminar: The WebAuthn API and Discoverable Credentials.pdf
FIDO Alliance Osaka Seminar: The WebAuthn API and Discoverable Credentials.pdf
FIDO Alliance
 
State of ICS and IoT Cyber Threat Landscape Report 2024 preview
State of ICS and IoT Cyber Threat Landscape Report 2024 previewState of ICS and IoT Cyber Threat Landscape Report 2024 preview
State of ICS and IoT Cyber Threat Landscape Report 2024 preview
Prayukth K V
 
Unsubscribed: Combat Subscription Fatigue With a Membership Mentality by Head...
Unsubscribed: Combat Subscription Fatigue With a Membership Mentality by Head...Unsubscribed: Combat Subscription Fatigue With a Membership Mentality by Head...
Unsubscribed: Combat Subscription Fatigue With a Membership Mentality by Head...
Product School
 
LF Energy Webinar: Electrical Grid Modelling and Simulation Through PowSyBl -...
LF Energy Webinar: Electrical Grid Modelling and Simulation Through PowSyBl -...LF Energy Webinar: Electrical Grid Modelling and Simulation Through PowSyBl -...
LF Energy Webinar: Electrical Grid Modelling and Simulation Through PowSyBl -...
DanBrown980551
 
To Graph or Not to Graph Knowledge Graph Architectures and LLMs
To Graph or Not to Graph Knowledge Graph Architectures and LLMsTo Graph or Not to Graph Knowledge Graph Architectures and LLMs
To Graph or Not to Graph Knowledge Graph Architectures and LLMs
Paul Groth
 
Kubernetes & AI - Beauty and the Beast !?! @KCD Istanbul 2024
Kubernetes & AI - Beauty and the Beast !?! @KCD Istanbul 2024Kubernetes & AI - Beauty and the Beast !?! @KCD Istanbul 2024
Kubernetes & AI - Beauty and the Beast !?! @KCD Istanbul 2024
Tobias Schneck
 
FIDO Alliance Osaka Seminar: Overview.pdf
FIDO Alliance Osaka Seminar: Overview.pdfFIDO Alliance Osaka Seminar: Overview.pdf
FIDO Alliance Osaka Seminar: Overview.pdf
FIDO Alliance
 
De-mystifying Zero to One: Design Informed Techniques for Greenfield Innovati...
De-mystifying Zero to One: Design Informed Techniques for Greenfield Innovati...De-mystifying Zero to One: Design Informed Techniques for Greenfield Innovati...
De-mystifying Zero to One: Design Informed Techniques for Greenfield Innovati...
Product School
 
Accelerate your Kubernetes clusters with Varnish Caching
Accelerate your Kubernetes clusters with Varnish CachingAccelerate your Kubernetes clusters with Varnish Caching
Accelerate your Kubernetes clusters with Varnish Caching
Thijs Feryn
 
UiPath Test Automation using UiPath Test Suite series, part 4
UiPath Test Automation using UiPath Test Suite series, part 4UiPath Test Automation using UiPath Test Suite series, part 4
UiPath Test Automation using UiPath Test Suite series, part 4
DianaGray10
 

Recently uploaded (20)

ODC, Data Fabric and Architecture User Group
ODC, Data Fabric and Architecture User GroupODC, Data Fabric and Architecture User Group
ODC, Data Fabric and Architecture User Group
 
From Daily Decisions to Bottom Line: Connecting Product Work to Revenue by VP...
From Daily Decisions to Bottom Line: Connecting Product Work to Revenue by VP...From Daily Decisions to Bottom Line: Connecting Product Work to Revenue by VP...
From Daily Decisions to Bottom Line: Connecting Product Work to Revenue by VP...
 
From Siloed Products to Connected Ecosystem: Building a Sustainable and Scala...
From Siloed Products to Connected Ecosystem: Building a Sustainable and Scala...From Siloed Products to Connected Ecosystem: Building a Sustainable and Scala...
From Siloed Products to Connected Ecosystem: Building a Sustainable and Scala...
 
IOS-PENTESTING-BEGINNERS-PRACTICAL-GUIDE-.pptx
IOS-PENTESTING-BEGINNERS-PRACTICAL-GUIDE-.pptxIOS-PENTESTING-BEGINNERS-PRACTICAL-GUIDE-.pptx
IOS-PENTESTING-BEGINNERS-PRACTICAL-GUIDE-.pptx
 
Software Delivery At the Speed of AI: Inflectra Invests In AI-Powered Quality
Software Delivery At the Speed of AI: Inflectra Invests In AI-Powered QualitySoftware Delivery At the Speed of AI: Inflectra Invests In AI-Powered Quality
Software Delivery At the Speed of AI: Inflectra Invests In AI-Powered Quality
 
Designing Great Products: The Power of Design and Leadership by Chief Designe...
Designing Great Products: The Power of Design and Leadership by Chief Designe...Designing Great Products: The Power of Design and Leadership by Chief Designe...
Designing Great Products: The Power of Design and Leadership by Chief Designe...
 
Builder.ai Founder Sachin Dev Duggal's Strategic Approach to Create an Innova...
Builder.ai Founder Sachin Dev Duggal's Strategic Approach to Create an Innova...Builder.ai Founder Sachin Dev Duggal's Strategic Approach to Create an Innova...
Builder.ai Founder Sachin Dev Duggal's Strategic Approach to Create an Innova...
 
"Impact of front-end architecture on development cost", Viktor Turskyi
"Impact of front-end architecture on development cost", Viktor Turskyi"Impact of front-end architecture on development cost", Viktor Turskyi
"Impact of front-end architecture on development cost", Viktor Turskyi
 
When stars align: studies in data quality, knowledge graphs, and machine lear...
When stars align: studies in data quality, knowledge graphs, and machine lear...When stars align: studies in data quality, knowledge graphs, and machine lear...
When stars align: studies in data quality, knowledge graphs, and machine lear...
 
JMeter webinar - integration with InfluxDB and Grafana
JMeter webinar - integration with InfluxDB and GrafanaJMeter webinar - integration with InfluxDB and Grafana
JMeter webinar - integration with InfluxDB and Grafana
 
FIDO Alliance Osaka Seminar: The WebAuthn API and Discoverable Credentials.pdf
FIDO Alliance Osaka Seminar: The WebAuthn API and Discoverable Credentials.pdfFIDO Alliance Osaka Seminar: The WebAuthn API and Discoverable Credentials.pdf
FIDO Alliance Osaka Seminar: The WebAuthn API and Discoverable Credentials.pdf
 
State of ICS and IoT Cyber Threat Landscape Report 2024 preview
State of ICS and IoT Cyber Threat Landscape Report 2024 previewState of ICS and IoT Cyber Threat Landscape Report 2024 preview
State of ICS and IoT Cyber Threat Landscape Report 2024 preview
 
Unsubscribed: Combat Subscription Fatigue With a Membership Mentality by Head...
Unsubscribed: Combat Subscription Fatigue With a Membership Mentality by Head...Unsubscribed: Combat Subscription Fatigue With a Membership Mentality by Head...
Unsubscribed: Combat Subscription Fatigue With a Membership Mentality by Head...
 
LF Energy Webinar: Electrical Grid Modelling and Simulation Through PowSyBl -...
LF Energy Webinar: Electrical Grid Modelling and Simulation Through PowSyBl -...LF Energy Webinar: Electrical Grid Modelling and Simulation Through PowSyBl -...
LF Energy Webinar: Electrical Grid Modelling and Simulation Through PowSyBl -...
 
To Graph or Not to Graph Knowledge Graph Architectures and LLMs
To Graph or Not to Graph Knowledge Graph Architectures and LLMsTo Graph or Not to Graph Knowledge Graph Architectures and LLMs
To Graph or Not to Graph Knowledge Graph Architectures and LLMs
 
Kubernetes & AI - Beauty and the Beast !?! @KCD Istanbul 2024
Kubernetes & AI - Beauty and the Beast !?! @KCD Istanbul 2024Kubernetes & AI - Beauty and the Beast !?! @KCD Istanbul 2024
Kubernetes & AI - Beauty and the Beast !?! @KCD Istanbul 2024
 
FIDO Alliance Osaka Seminar: Overview.pdf
FIDO Alliance Osaka Seminar: Overview.pdfFIDO Alliance Osaka Seminar: Overview.pdf
FIDO Alliance Osaka Seminar: Overview.pdf
 
De-mystifying Zero to One: Design Informed Techniques for Greenfield Innovati...
De-mystifying Zero to One: Design Informed Techniques for Greenfield Innovati...De-mystifying Zero to One: Design Informed Techniques for Greenfield Innovati...
De-mystifying Zero to One: Design Informed Techniques for Greenfield Innovati...
 
Accelerate your Kubernetes clusters with Varnish Caching
Accelerate your Kubernetes clusters with Varnish CachingAccelerate your Kubernetes clusters with Varnish Caching
Accelerate your Kubernetes clusters with Varnish Caching
 
UiPath Test Automation using UiPath Test Suite series, part 4
UiPath Test Automation using UiPath Test Suite series, part 4UiPath Test Automation using UiPath Test Suite series, part 4
UiPath Test Automation using UiPath Test Suite series, part 4
 

Linux Daemon Writting

  • 1. Linux Daemon Writing HOWTO Devin Watson <mailto:dmwatson@comcast.net> v1.0, May 2004 This document shows how to write a daemon in Linux using GCC. Knowledge of Linux and a familiarity with C are necessary to use this document. This HOWTO is Copyright by Devin Watson, under the terms of the BSD License. Contents 1 Introduction: What is a Daemon? 1 2 Getting Started 2 3 Planning Your Daemon 2 3.1 What Is It Going To Do? . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 2 3.2 How Much Interaction? . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 2 4 Basic Daemon Structure 2 4.1 Forking The Parent Process . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 3 4.2 Changing The File Mode Mask (Umask) . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 3 4.3 Opening Logs For Writing . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 4 4.4 Creating a Unique Session ID (SID) . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 4 4.5 Changing The Working Directory . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 4 4.6 Closing Standard File Descriptors . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 5 5 Writing the Daemon Code 6 5.1 Initialization . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 6 5.2 The Big Loop . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 6 6 Putting It All Together 7 6.1 Complete Sample . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 7 1 Introduction: What is a Daemon? A daemon (or service) is a background process is designed to run autonomously,with little or no user in- tervention. The Apache web server http daemon (httpd) is one such example of a daemon. It waits in the background listening on specific ports and serves up pages, or processes scripts, based on the type of request. Creating a daemon in Linux uses a specific set of rules in a given order. Knowing how they work will help you understand how daemons operate in userland Linux, but can also operate with calls to the kernel. In fact, a few daemons interface with kernel modules that work with hardware devices, such as external controller
  • 2. 2. Getting Started 2 boards, printers, and PDAs. They are one of the fundamental building blocks in Linux that give it incredible flexibility and power. Throughout this HOWTO, a very simple daemon will be built in C. As we go along, more code will be added, showing the proper order of execution required to get a daemon up and running. 2 Getting Started First off, you’ll need the following packages installed on your Linux machine to develop daemons, specifically: • GCC 3.2.2 or higher • Linux Development headers and libraries If your system does not already have these installed (not likely, but check anyway), you’ll need them to develop the examples in this HOWTO. To find out what version of GCC you have installed, use: gcc --version 3 Planning Your Daemon 3.1 What Is It Going To Do? A daemon should do one thing, and do it well. That one thing may be as complex as managing hundreds of mailboxes on multiple domains, or as simple as writing a report and calling sendmail to mail it out. In any case, you should have a good plan as to what the daemon should do. If it is going to interoperate with other daemons (which you may or may not be writing), this is something else to consider as well. 3.2 How Much Interaction? Daemons should never have direct communication with a user through a terminal. In fact, a daemon shouldn’t communicate directly with a user at all. All communication should pass through some sort of interface (which you may or may not have to write), which can be as complex as a GTK+ GUI, or as simple as a signal set. 4 Basic Daemon Structure When a daemon starts up, it has to do some low-level housework to get itself ready for its real job. This involves a few steps: • Fork off the parent process • Change file mode mask (umask) • Open logs for writing • Create a unique Session ID (SID) • Change the current working directory to a safe place
  • 3. 4. Basic Daemon Structure 3 • Close standard file descriptors • Enter actual daemon code 4.1 Forking The Parent Process A daemon is started either by the system itself or a user in a terminal or script. When it does start, the process is just like any other executable on the system. To make it truly autonomous, a child process must be created where the actual code is executed. This is known as forking, and it uses the fork() function: pid_t pid; /* Fork off the parent process */ pid = fork(); if (pid < 0) { exit(EXIT_FAILURE); } /* If we got a good PID, then we can exit the parent process. */ if (pid > 0) { exit(EXIT_SUCCESS); } Notice the error check right after the call to fork(). When writing a daemon, you will have to code as defensively as possible. In fact, a good percentage of the total code in a daemon consists of nothing but error checking. The fork() function returns either the process id (PID) of the child process (not equal to zero), or -1 on failure. If the process cannot fork a child, then the daemon should terminate right here. If fork() did succeed, the parent process must exit gracefully. This may seem strange to anyone who hasn’t seen it, but by forking, the child process continues the execution from here on out in the code. 4.2 Changing The File Mode Mask (Umask) In order to write to any files (including logs) created by the daemon, the file mode mask (umask) must be changed to ensure that they can be written to or read from properly. This is similar to running umask from the command line, but we do it programmatically here. We can use the umask() function to accomplish this: pid_t pid, sid; /* Fork off the parent process */ pid = fork(); if (pid < 0) { /* Log failure (use syslog if possible) */ exit(EXIT_FAILURE); } /* If we got a good PID, then we can exit the parent process. */ if (pid > 0) { exit(EXIT_SUCCESS); }
  • 4. 4. Basic Daemon Structure 4 /* Change the file mode mask */ umask(0); By setting the umask to 0, we will have full access to the files generated by the daemon. Even if you aren’t planning on using any files, it is a good idea to set the umask here anyway, just in case you will be accessing files on the filesystem. 4.3 Opening Logs For Writing This part is optional, but it is recommended that you open a log file somewhere in the system for writing. This may be the only place you can look for debug information about your daemon. 4.4 Creating a Unique Session ID (SID) From here, the child process must get a unique SID from the kernel in order to operate. Otherwise, the child process becomes an orphan in the system. The pid t type, declared in the previous section, is also used to create a new SID for the child process: pid_t pid, sid; /* Fork off the parent process */ pid = fork(); if (pid < 0) { exit(EXIT_FAILURE); } /* If we got a good PID, then we can exit the parent process. */ if (pid > 0) { exit(EXIT_SUCCESS); } /* Change the file mode mask */ umask(0); /* Open any logs here */ /* Create a new SID for the child process */ sid = setsid(); if (sid < 0) { /* Log any failure */ exit(EXIT_FAILURE); } Again, the setsid() function has the same return type as fork(). We can apply the same error-checking routine here to see if the function created the SID for the child process. 4.5 Changing The Working Directory The current working directory should be changed to some place that is guaranteed to always be there. Since many Linux distributions do not completely follow the Linux Filesystem Hierarchy standard, the only directory that is guaranteed to be there is the root directory (/). We can do this using the chdir() function:
  • 5. 4. Basic Daemon Structure 5 pid_t pid, sid; /* Fork off the parent process */ pid = fork(); if (pid < 0) { exit(EXIT_FAILURE); } /* If we got a good PID, then we can exit the parent process. */ if (pid > 0) { exit(EXIT_SUCCESS); } /* Change the file mode mask */ umask(0); /* Open any logs here */ /* Create a new SID for the child process */ sid = setsid(); if (sid < 0) { /* Log any failure here */ exit(EXIT_FAILURE); } /* Change the current working directory */ if ((chdir(quot;/quot;)) < 0) { /* Log any failure here */ exit(EXIT_FAILURE); } Once again, you can see the defensive coding taking place. The chdir() function returns -1 on failure, so be sure to check for that after changing to the root directory within the daemon. 4.6 Closing Standard File Descriptors One of the last steps in setting up a daemon is closing out the standard file descriptors (STDIN, STDOUT, STDERR). Since a daemon must not use the terminal, these file descriptors are both redundant and a potential security hazard. The close() function can handle this for us: pid_t pid, sid; /* Fork off the parent process */ pid = fork(); if (pid < 0) { exit(EXIT_FAILURE); } /* If we got a good PID, then we can exit the parent process. */ if (pid > 0) { exit(EXIT_SUCCESS);
  • 6. 5. Writing the Daemon Code 6 } /* Change the file mode mask */ umask(0); /* Open any logs here */ /* Create a new SID for the child process */ sid = setsid(); if (sid < 0) { /* Log any failure here */ exit(EXIT_FAILURE); } /* Change the current working directory */ if ((chdir(quot;/quot;)) < 0) { /* Log any failure here */ exit(EXIT_FAILURE); } /* Close out the standard file descriptors */ close(STDIN_FILENO); close(STDOUT_FILENO); close(STDERR_FILENO); It’s a good idea to stick with the constants defined for the file descriptors, for the greatest portability between system versions. 5 Writing the Daemon Code 5.1 Initialization At this point, you have basically told Linux that you’re a daemon, so now it’s time to write the actual daemon code. Initialization is the first step here. Since there can be a multitude of different functions that can be called here to set up your daemon’s task, I won’t go too deep into them here. The big point here is, when initializing anything in a daemon, the same defensive coding guidelines apply. Be as verbose as possible when writing either to the syslog or your own logs. Debugging a daemon can be quite difficult when there isn’t enough information available as to the status of the daemon. 5.2 The Big Loop A daemon’s main code is typically inside an infinite loop. Technically, it isn’t an infinite loop, but it is structured as one: pid_t pid, sid; /* Fork off the parent process */ pid = fork(); if (pid < 0) { exit(EXIT_FAILURE);
  • 7. 6. Putting It All Together 7 } /* If we got a good PID, then we can exit the parent process. */ if (pid > 0) { exit(EXIT_SUCCESS); } /* Change the file mode mask */ umask(0); /* Open any logs here */ /* Create a new SID for the child process */ sid = setsid(); if (sid < 0) { /* Log any failures here */ exit(EXIT_FAILURE); } /* Change the current working directory */ if ((chdir(quot;/quot;)) < 0) { /* Log any failures here */ exit(EXIT_FAILURE); } /* Close out the standard file descriptors */ close(STDIN_FILENO); close(STDOUT_FILENO); close(STDERR_FILENO); /* Daemon-specific initialization goes here */ /* The Big Loop */ while (1) { /* Do some task here ... */ sleep(30); /* wait 30 seconds */ } This typical loop is usually a while loop that has an infinite terminating condition, with a call to sleep in there to make it run at specified intervals. Think of it like a heartbeat: when your heart beats, it performs a few tasks, then waits until the next beat takes place. Many daemons follow this same methodology. 6 Putting It All Together 6.1 Complete Sample Listed below is a complete sample daemon that shows all of the steps necessary for setup and execution. To run this, simply compile using gcc, and start execution from the command line. To terminate, use the kill command after finding its PID. I’ve also put in the include statements for interfacing with the syslog, recommended (at the very
  • 8. 6. Putting It All Together 8 least) for sending start/stop/pause/die log statements, in addition to using your own logs with the fopen()/fwrite()/fclose() function calls. #include <sys/types.h> #include <sys/stat.h> #include <stdio.h> #include <stdlib.h> #include <fcntl.h> #include <errno.h> #include <unistd.h> #include <syslog.h> #include <string.h> int main(void) { /* Our process ID and Session ID */ pid_t pid, sid; /* Fork off the parent process */ pid = fork(); if (pid < 0) { exit(EXIT_FAILURE); } /* If we got a good PID, then we can exit the parent process. */ if (pid > 0) { exit(EXIT_SUCCESS); } /* Change the file mode mask */ umask(0); /* Open any logs here */ /* Create a new SID for the child process */ sid = setsid(); if (sid < 0) { /* Log the failure */ exit(EXIT_FAILURE); } /* Change the current working directory */ if ((chdir(quot;/quot;)) < 0) { /* Log the failure */ exit(EXIT_FAILURE); } /* Close out the standard file descriptors */ close(STDIN_FILENO); close(STDOUT_FILENO); close(STDERR_FILENO); /* Daemon-specific initialization goes here */ /* The Big Loop */
  • 9. 6. Putting It All Together 9 while (1) { /* Do some task here ... */ sleep(30); /* wait 30 seconds */ } exit(EXIT_SUCCESS); } From here, you should be able to use this skeleton to write your own daemons. Be sure to add in your own logging (or use the syslog facility). Finally, code defensively, code defensively, code defensively!