How to daemonize in Linux

Source: Internet
Author: User

How to daemonize in Linux-silent_wind column-blog channel-csdn. net

How to daemonize in Linux Category: Unix Read by 170 Comment (0) Favorites Report Signalredirectuserterminalfilelogging

Directory (?)[+]

    1. Simple Example
    2. A more useful example

One of the things I keep running restart SS isLinuxDaemons that don't properlyDaemonizeThemselves. To properlyDaemonize, The following steps must be followed.

    • The fork () call is used to create a separate process.
    • The setsid () call is used to detach the process from the parent (normally a shell ).
    • The file mask shocould be reset.
    • The current directory shocould be changed to something benign.
    • The standard files (stdin, stdout and stderr) need to be reopened.

Failure to do any of these steps will lead to a daemon process that can misbehave. The typical symptoms are as follows.

    • Starting the daemon and then logging out will cause the terminal to hang. This is particle ly nasty with SSH.
    • The directory from which the daemon was launched remains locked.
    • Spurious output appears in the shell from which the daemon was started.
Simple Example

The following example program performs the bare minimum steps required to launch a daemon process.

# Include <stdio. h> # include <stdlib. h> # include <unistd. h> # include <sys/types. h> # include <sys/STAT. h> # define exit_success 0 # define exit_failure 1 static void Daemonize (Void) {pid_t PID, Sid;/* already a daemon */If (getppid () = 1) return; /* 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 );} /* at this point we are executing as the child process * // * change the file mode mask */umask (0 ); /* Create a New Sid for the child process */SID = setsid (); If (SID <0) {exit (exit_failure);}/* change the current working directory. this prevents the current directory from being locked; hence not being able to remove it. */If (chdir ("/") <0) {exit (exit_failure );} /* redirect standard files to/dev/null */freopen ("/dev/null", "r", stdin); freopen ("/dev/null ", "W", stdout); freopen ("/dev/null", "W", stderr);} int main (INT argc, char * argv []) {Daemonize ();/* Now we are a daemon -- do the work for which we were paid */return 0 ;}

 

It has been brought to my attention that a second call to fork () may be required to fully detach the process from the Controller terminal (in other words: fork, setsid, fork ). this does not seem to be required in Linux . A second fork wocould not cause any problems, although it wowould complicate the child/parent signalling below.

 

A more useful example

The following program extends the basic daemon by adding the following features.

    • logs messages to the System Log (via syslog).
    • creates a lock file to prevent the daemon from being run twice.
    • changes the valid user (drops privileges).
    • startup errors are reported to the main process.
# Include <stdio. h> # include <stdlib. h> # include <string. h> # include <unistd. h> # include <sys/types. h> # include <sys/STAT. h> # include <fcntl. h> # include <syslog. h> # include <errno. h> # include <PWD. h> # include <signal. h>/* change this to whatever your daemon is called */# define daemon_name "mydaemon"/* change this to the user under which to run */# define run_as_user "daemon "# define exit_success 0 # define exit_failure 1 static void child_handler (int signum) {Switch (SIGNUM) {Case sigalrm: exit (exit_failure); break; Case SIGUSR1: exit (exit_success); break; Case sigchld: exit (exit_failure); break;} static void Daemonize (Const char * lockfile) {pid_t PID, Sid, parent; int LFP =-1;/* already a daemon */If (getppid () = 1) return; /* Create the lock file as the current user */If (lockfile & lockfile [0]) {LFP = open (lockfile, o_rdwr | o_creat, 0640 ); if (LFP <0) {syslog (log_err, "unable to create lock file % s, code = % d (% s)", lockfile, errno, strerror (errno )); exit (exit_failure) ;}}/* Drop user if there is one, and we were run as root */If (getuid () = 0 | geteuid () = 0) {struct passwd * PW = getpwnam (run_as_user); If (PW) {syslog (log_notice, "setting user to" run_as_user ); setuid (PW-> pw_uid) ;}}/* trap signals that we expect CT to recieve */signal (sigchld, child_handler); signal (SIGUSR1, child_handler); signal (sigalrm, child_handler);/* fork off the parent process */PID = fork (); If (PID <0) {syslog (log_err, "unable to fork daemon, code = % d (% s) ", errno, strerror (errno); exit (exit_failure);}/* If we got a good PID, then we can exit the parent process. */If (pid> 0) {/* wait for confirmation from the child via sigterm or sigchld, or for two seconds to elapse (sigalrm ). pause () shocould not return. */alarm (2); pause (); exit (exit_failure);}/* at this point we are executing as the child process */parent = getppid (); /* cancel certain signals */signal (sigchld, sig_dfl);/* a child process dies */signal (sigtstp, sig_ign);/* vartty signals */signal (sigttou, sig_ign); signal (sigttin, sig_ign); signal (sighup, sig_ign);/* ignore hangup signal */signal (sigterm, sig_dfl ); /* die on sigterm * // * change the file mode mask */umask (0);/* Create a New Sid for the child process */SID = setsid (); if (SID <0) {syslog (log_err, "unable to create a new session, code % d (% s)", errno, strerror (errno )); exit (exit_failure);}/* change the current working directory. this prevents the current directory from being locked; hence not being able to remove it. */If (chdir ("/") <0) {syslog (log_err, "unable to change directory to % s, code % d (% s )", "/", errno, strerror (errno); exit (exit_failure);}/* redirect standard files to/dev/null */freopen ("/dev/null ", "r", stdin); freopen ("/dev/null", "W", stdout); freopen ("/dev/null", "W", stderr ); /* tell the parent process that we are a-okay */kill (parent, SIGUSR1);} int main (INT argc, char * argv []) {/* initialize the logging interface */openlog (daemon_name, log_pid, log_local5); syslog (log_info, "starting "); /* One may wish to process command line arguments here *//*Daemonize */ Daemonize ("/Var/lock/subsys/" daemon_name ); /* now we are a daemon -- do the work for which we were paid * // * Finish up */syslog (log_notice, "terminated"); closelog (); return 0 ;}

Contact Us

The content source of this page is from Internet, which doesn't represent Alibaba Cloud's opinion; products and services mentioned on that page don't have any relationship with Alibaba Cloud. If the content of the page makes you feel confusing, please write us an email, we will handle the problem within 5 days after receiving your email.

If you find any instances of plagiarism from the community, please send an email to: info-contact@alibabacloud.com and provide relevant evidence. A staff member will contact you within 5 working days.

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.