LinuxSir.cn,穿越时空的Linuxsir!

 找回密码
 注册
搜索
热搜: shell linux mysql
查看: 598|回复: 3

(读apue2)关于后台进程初始化的疑问

[复制链接]
发表于 2007-5-29 09:01:46 | 显示全部楼层 |阅读模式

  1. #include <stdio.h>
  2. #include <stdlib.h>
  3. #include <syslog.h>
  4. #include <sys/resource.h>
  5. #include <sys/stat.h>
  6. #include <fcntl.h>
  7. #include <unistd.h>
  8. #include <signal.h>

  9. void
  10. daemonize(const char *cmd)
  11. {
  12.         int                        i, fd0, fd1, fd2;
  13.         pid_t                        pid;
  14.         struct rlimit                rl;
  15.         struct sigaction        sa;
  16.        
  17.         umask(0);
  18.        
  19.         if (getrlimit(RLIMIT_NOFILE, &rl) < 0) {
  20.                 printf("getrlimit failed");
  21.                 exit(1);
  22.         }
  23.        
  24.         if ((pid = fork()) < 0) {
  25.                 printf("first fork failed");
  26.                 exit(1);
  27.         } else if (pid > 0) {
  28.                 exit(0);
  29.         }
  30.        
  31.         setsid();
  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("sigaction failed");
  38.                 exit(1);
  39.         }
  40.         if ((pid = fork()) < 0) {
  41.                 prinrf("second failed");
  42.                 exit(1);
  43.         } else if (pid > 0) {
  44.                 exit(0);
  45.         }
  46.        
  47.         if (chdir("/") < 0) {
  48.                 printf("chdir failed");
  49.                 exit(1);
  50.         }
  51.        
  52.         if (rl.rlim_max == RLIM_INFINITY)
  53.                 rl.rlim_max = 1024;
  54.         for (i = 0; i < rl.rlim_max; i++)
  55.                 close(i);
  56.                
  57.         fd0 = open("/dev/null", O_RDWR);
  58.         fd1 = dup(0);
  59.         fd2 = dup(0);
  60.        
  61.         openlog(cmd, LOG_CONS, LOG_DAEMON);
  62.         if (fd0 != 0 || fd1 != 1 || fd2 != 2) {
  63.                 syslog(LOG_ERR, "unexpected file descriptor %d %d %d", fd0, fd1, fd2);
  64.                 exit(1);
  65.         }
  66. }
复制代码

上面是一个后台进程初始化代码,这里我有几个疑问:
第一:umask(0),这样的话岂不是任何用户都可以写由该进程创建的文件了吗
第二:为什么要忽略SIGHUP信号呢
发表于 2007-5-29 09:26:24 | 显示全部楼层
因为是后台进程也就是服务,所以不希望一个会话结束后,该进程就被杀掉,所以采用了忽略SIGHUP信号。
因为一个login会话退出,比如一次ssh会话,会话头进程会向所有子进程发送SIGHUP信号,该信号的系统默认处理方式是杀死被通知的进程。
如果不忽略SIGHUP,用nohup命令去执行这个程序也是可以的。
回复 支持 反对

使用道具 举报

 楼主| 发表于 2007-5-29 09:36:55 | 显示全部楼层
谢谢版主,我明白了,关于第一个问题,他为什么将umask设为0呢
回复 支持 反对

使用道具 举报

发表于 2007-5-29 11:52:01 | 显示全部楼层
在创建一个新文件时,可以指定权限,用参数mode表示,
最终创建的文件的权限并不是mode所示,而是可由进程的umask值修改。
修改方法是(mode & ~umask)。
进程的umask值由父进程继承而来。
为了避免不同的umask值导致后台进程需要创建的文件权限产生差异。将其设为0,可明确由mode得到要创建的权限。
回复 支持 反对

使用道具 举报

您需要登录后才可以回帖 登录 | 注册

本版积分规则

快速回复 返回顶部 返回列表