[轉] linux守护进程的几个关键地方

出處:http://blog.chinaunix.net/uid-26583794-id-3166018.html

创建一个守护进程,有几个关键的步骤,也有几个地方需要注意,
几个关键的步骤有:
1:清除文件创建权限
2:调用fork,然后使父进程退出
3:调用setsid以创建一个新的会话,有三个目的使调用进程 a:成为新会话的首进程,b:成为新进程的组长进程,c:没有控制终端
4:切换工作目录
5:关闭不需要的文件描述符
需要注意的地方
1:因为守护进程没有控制终端,所以不能与标准输入输出出错进行交互,不能使用printf,通常用syslog来解决守护进程的打印信息
参考代码如下:
点击(此处)折叠或打开
  1. #include <signal.h>
  2. #include <stdlib.h>
  3. #include <syslog.h>
  4. #include <fcntl.h>
  5. #include <stdio.h>
  6. #include <sys/resource.h>

  7. void daemonize(const char *cmd)
  8. {
  9.     int                    i, fd0, fd1, fd2;
  10.     pid_t                pid;
  11.     struct rlimit        rl;
  12.     struct sigaction    sa;

  13.     /*
  14.      * Clear file creation mask.
  15.      */
  16.     umask(0);

  17.     /*
  18.      * Get maximum number of file descriptors.
  19.      */
  20.     if (getrlimit(RLIMIT_NOFILE, &rl) < 0)
  21.         printf(“%s: can’t get file limit”, cmd);

  22.     /*
  23.      * Become a session leader to lose controlling TTY.
  24.      */
  25.     if ((pid = fork()) < 0)
  26.         printf(“%s: can’t fork”, cmd);
  27.     else if (pid != 0) /* parent */
  28.         exit(0);
  29.     setsid();

  30.     /*
  31.      * Ensure future opens won’t allocate controlling TTYs.
  32.      */
  33.     sa.sa_handler = SIG_IGN;
  34.     sigemptyset(&sa.sa_mask);
  35.     sa.sa_flags = 0;
  36.     if (sigaction(SIGHUP, &sa, NULL) < 0)
  37.         printf(“can’t ignore SIGHUP”);
  38.     if ((pid = fork()) < 0)
  39.         printf(“%s: can’t fork”, cmd);
  40.     else if (pid != 0) /* parent */
  41.         exit(0);

  42.     /*
  43.      * Change the current working directory to the root so
  44.      * we won’t prevent file systems from being unmounted.
  45.      */
  46.     if (chdir(“/”) < 0)
  47.         printf(“can’t change directory to /”);

  48.     /*
  49.      * Close all open file descriptors.
  50.      */
  51.     if (rl.rlim_max == RLIM_INFINITY)
  52.         rl.rlim_max = 1024;
  53.     for (i = 0; i < rl.rlim_max; i++)
  54.         close(i);

  55.     /*
  56.      * Attach file descriptors 0, 1, and 2 to /dev/null.
  57.      */
  58.     fd0 = open(“/dev/null”, O_RDWR);
  59.     fd1 = dup(0);
  60.     fd2 = dup(0);

  61.     /*
  62.      * Initialize the log file.
  63.      */
  64.     openlog(cmd, LOG_CONS, LOG_DAEMON);
  65.     if (fd0 != 0 || fd1 != 1 || fd2 != 2) {
  66.         syslog(LOG_ERR, “unexpected file descriptors %d %d %d”,fd0, fd1, fd2);
  67.         exit(1);
  68.     }
  69.     syslog(LOG_DEBUG, “daem ok “);
  70.     
  71. }
  72. int main()
  73. {
  74.      daemonize(“test”);
  75.      while(1);//守护进程所要干的事情
  76.     
  77. }
未經允許不得轉載:GoMCU » [轉] linux守护进程的几个关键地方