Difference between revisions of "Daemon linux"

From Teknologisk videncenter
Jump to: navigation, search
m
m
 
(11 intermediate revisions by the same user not shown)
Line 1: Line 1:
Example of creating a daemon in Linux:
+
 
 +
=Creating your own daemon=
 +
<onlyinclude>
 +
Example of creating a daemon in Linux: (See [[systemd debian]] for systemd daemons)
 
*'''setsid()''' - damon will be the session leader. Sets Session ID (SID) and Group ID (GID) to Process ID (PID)
 
*'''setsid()''' - damon will be the session leader. Sets Session ID (SID) and Group ID (GID) to Process ID (PID)
 
*Reopening stdin, stdout and stderr to /dev/null detaches the process from the controlling terminal and Parent PID is set to 1 (init or systemd - depending on Linux version/distribution)
 
*Reopening stdin, stdout and stderr to /dev/null detaches the process from the controlling terminal and Parent PID is set to 1 (init or systemd - depending on Linux version/distribution)
*'''log_err()''' and '''log_to_log()''' are calls to a logging system not shown here
 
  
 
<source lang=c line>
 
<source lang=c line>
 +
#include <stdio.h>
 +
#include <unistd.h>
 +
#include <stdlib.h>
 +
#include <syslog.h>
 +
void  daemon_create(void);
 +
 +
int main(void) {
 +
        printf("Starting my_daemon\n");
 +
        openlog("my_daemon", LOG_INFO, LOG_DAEMON);
 +
        daemon_create();
 +
        for (int i=0; i < 100; i++) {
 +
                syslog(LOG_INFO,"Countet to %d", i);
 +
                sleep(2);
 +
        }
 +
        return(0);
 +
}
 +
 
void  daemon_create(void) {
 
void  daemon_create(void) {
 
     pid_t pid;
 
     pid_t pid;
Line 10: Line 29:
 
     pid = fork();
 
     pid = fork();
 
     if(pid < 0){
 
     if(pid < 0){
         log_err("Error in fork: %m"); // Write error to terminal
+
         syslog(LOG_ERR, "Error in fork: %m");
 
         exit(1);
 
         exit(1);
 
     }
 
     }
     if(pid > 0){
+
     if(pid > 0) {
 +
        syslog(LOG_INFO, "Parent dying");
 
         exit(0); // Parent die
 
         exit(0); // Parent die
 
     }
 
     }
 
     if(setsid() < 0){ // Make child session leader
 
     if(setsid() < 0){ // Make child session leader
         log_err("Error in setsid: %m");
+
         syslog(LOG_ERR, "Error in setsid: %m");
         exit(1);
+
         exit(2);
 
         }
 
         }
         if (   freopen("/dev/null", "r", stdin) == NULL
+
         if (freopen("/dev/null", "r", stdin) == NULL
 
         || freopen("/dev/null", "w", stdout) == NULL
 
         || freopen("/dev/null", "w", stdout) == NULL
 
         || freopen("/dev/null", "w", stderr) == NULL ) {
 
         || freopen("/dev/null", "w", stderr) == NULL ) {
                 log_err("When creating daemon freopen from STDIN/OUT/ERR failed: %m");
+
                 syslog(LOG_ERR, "When creating daemon freopen from STDIN/OUT/ERR failed: %m");
    }
+
                exit(3);
        log_to_syslog(); // Log to syslog only when in daemon mode
+
  }
 
}
 
}
 
</source>
 
</source>
 
===Checking the daemon===
 
===Checking the daemon===
 +
*Daemon detached from TTY - PPID is 1
 +
* Session and session group leader - SID and PGID same as PID
 
<source lang=bash>
 
<source lang=bash>
$ ps xo pid,ppid,pgid,sid,comm | grep -P '(my_daemon|PPID)'
+
$ ps xo uname,pid,ppid,pgid,sid,tty,comm | grep -P '(my_daemon|COMMAND)'
    PID    PPID    PGID    SID COMMAND
+
USER        PID    PPID    PGID    SID TTY      COMMAND
775354       1  775353 714976 my_daemon
+
heth      778254       1  778254 778254 ?        my_daemon
 +
$ tail -f /var/log/sysg
 +
Dec 20 12:37:59 emb3 my_daemon: Countet to 2
 +
Dec 20 12:38:01 emb3 my_daemon: Countet to 3
 +
Dec 20 12:38:03 emb3 my_daemon: Countet to 4
 +
Dec 20 12:38:05 emb3 my_daemon: Countet to 5
 +
...
 
</source>
 
</source>
 +
</onlyinclude>
 +
[[Category:Linux]]

Latest revision as of 05:07, 22 December 2022

Creating your own daemon

Example of creating a daemon in Linux: (See systemd debian for systemd daemons)

  • setsid() - damon will be the session leader. Sets Session ID (SID) and Group ID (GID) to Process ID (PID)
  • Reopening stdin, stdout and stderr to /dev/null detaches the process from the controlling terminal and Parent PID is set to 1 (init or systemd - depending on Linux version/distribution)
 1 #include <stdio.h>
 2 #include <unistd.h>
 3 #include <stdlib.h>
 4 #include <syslog.h>
 5 void  daemon_create(void);
 6 
 7 int main(void) {
 8         printf("Starting my_daemon\n");
 9         openlog("my_daemon", LOG_INFO, LOG_DAEMON);
10         daemon_create();
11         for (int i=0; i < 100; i++) {
12                 syslog(LOG_INFO,"Countet to %d", i);
13                 sleep(2);
14         }
15         return(0);
16 }
17 
18 void  daemon_create(void) {
19     pid_t pid;
20 
21     pid = fork();
22     if(pid < 0){
23         syslog(LOG_ERR, "Error in fork: %m");
24         exit(1);
25     }
26     if(pid > 0) {
27         syslog(LOG_INFO, "Parent dying");
28         exit(0); // Parent die
29     }
30     if(setsid() < 0){ // Make child session leader
31         syslog(LOG_ERR, "Error in setsid: %m");
32         exit(2);
33         }
34         if (freopen("/dev/null", "r", stdin) == NULL
35         || freopen("/dev/null", "w", stdout) == NULL
36         || freopen("/dev/null", "w", stderr) == NULL ) {
37                 syslog(LOG_ERR, "When creating daemon freopen from STDIN/OUT/ERR failed: %m");
38                 exit(3);
39    }
40 }

Checking the daemon

  • Daemon detached from TTY - PPID is 1
  • Session and session group leader - SID and PGID same as PID
$ ps xo uname,pid,ppid,pgid,sid,tty,comm | grep -P '(my_daemon|COMMAND)'
USER         PID    PPID    PGID     SID TTY       COMMAND
heth      778254       1  778254  778254 ?        my_daemon
$ tail -f /var/log/sysg
Dec 20 12:37:59 emb3 my_daemon: Countet to 2
Dec 20 12:38:01 emb3 my_daemon: Countet to 3
Dec 20 12:38:03 emb3 my_daemon: Countet to 4
Dec 20 12:38:05 emb3 my_daemon: Countet to 5
...