守护进程

对于守护进程,在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的。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值