Chinaunix首页 | 论坛 | 博客
  • 博客访问: 98937
  • 博文数量: 87
  • 博客积分: 0
  • 博客等级: 民兵
  • 技术积分: 10
  • 用 户 组: 普通用户
  • 注册时间: 2013-12-20 10:54
文章分类
文章存档

2016年(19)

2015年(2)

2013年(66)

我的朋友

分类: LINUX

2013-12-20 11:04:54

创建一个守护进程,有几个关键的步骤,也有几个地方需要注意,
几个关键的步骤有:
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. }

阅读(214) | 评论(0) | 转发(0) |
给主人留下些什么吧!~~