守护进程

来源:互联网 发布:华娱无线java 编辑:程序博客网 时间:2024/04/19 22:55

对于守护进程,在APUE的13.3节中介绍了其编程规则,共6点。

  1. 调用umask()设置用户创建文件的默认权限(一般是umask(0));
  2. 调用fork,然后使其父进程退出exit;
  3. 调用setsid来创建一个新的会话
  4. 将当前工作目录切换到根目录
  5. 关闭所有不需要的文件描述符
  6. 重定位stdin,stdout 和 stderr 到 /dev/null

对于daemonize.c程序,其完全按照13.3节中介绍的编程规则进行编写

/* 设置创建文件的默认权限为可读、可写 */umask(0);/* 调用fork, 然后使父进程退出, 以此来保证子进程不是组长进程 *//* 调用setsid(), 使得子进程成为新会话的首进程, 并且没有终端 */if ((pid = fork()) < 0)    err_quit("%s: can't fork", cmd);else if (pid != 0) /* parent */    exit(0);setsid();sa.sa_handler = SIG_IGN;sigemptyset(&sa.sa_mask);sa.sa_flags = 0;if (sigaction(SIGHUP, &sa, NULL) < 0)    err_quit("%s: can't ignore SIGHUP");/* 使用第二个子进程作为守护进程, 这样可以确保守护进程不是会话首进程 */if ((pid = fork()) < 0)    err_quit("%s: can't fork", cmd);else if (pid != 0) /* parent */    exit(0);/* 将当前工作目录切换为根目录, 这样可以避免原工作目录所在的文件系统不能被拆卸 */if (chdir("/") < 0)    err_quit("%s: can't change directory to /");/* 关闭所有的文件描述符(从0到最大的文件描述符值) */if (rl.rlim_max == RLIM_INFINITY)    rl.rlim_max = 1024;for (i = 0; i < rl.rlim_max; i++)    close(i);/* 重定位标准输入(stdin), 标准输出(stdout), 标准出错(stderr) 到 /dev/null *//* 在stdin,stdout和stderr都关闭的情况下, 此处的open函数会返回最小的文件描述符(也就是stdin) */fd0 = open("/dev/null", O_RDWR);/* dup函数会返回当前可用文件描述符中最小的数值, 这里返回的依次是 stdout和stderr */fd1 = dup(0);fd2 = dup(0);

其中对于 open("/dev/null", O_RDWR) 的用法可以参考APUE中3.3节关于open函数返回值得描述,这里就是用来获取标准输入对应的文件描述符0的。

0 0