(1)子进程等待父进程退出
(2)子进程使用setsid创建新的会话期,脱离控制台
(3)调用chdir将当前工作目录设置为/
(4)umask设置为0以取消任何文件权限屏蔽
(5)关闭所有文件描述符
(6)将0、1、2定位到/dev/null
#include <stdio.h>
#include <unistd.h>
#include <stdlib.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <fcntl.h>
// 函数作用就是把调用该函数的进程变成一个守护进程
void create_daemon(void)
{
pid_t pid = 0;
pid = fork();
if (pid < 0)
{
perror("fork");
exit(-1);
}
if (pid > 0)
{
exit(0); // 父进程直接退出
}
// 执行到这里就是子进程
// setsid将当前进程设置为一个新的会话期session,目的就是让当前进程
// 脱离控制台。
pid = setsid();
if (pid < 0)
{
perror("setsid");
exit(-1);
}
// 将当前进程工作目录设置为根目录
chdir("/");
// umask设置为0确保将来进程有最大的文件操作权限
umask(0);
// 关闭所有文件描述符
// 先要获取当前系统中所允许打开的最大文件描述符数目
int cnt = sysconf(_SC_OPEN_MAX);
int i = 0;
for (i=0; i<cnt; i++)
{
close(i);
}
//将0、1、2定位到/dev/null
open("/dev/null", O_RDWR);//标准输入 0
open("/dev/null", O_RDWR);//标准输出 1
open("/dev/null", O_RDWR);//标准错误 2
}
int main(void)
{
create_daemon();
while (1)
{
printf("I am running.\n");
sleep(1);
}
return 0;
}
/dev/null 可理解为一个垃圾堆,在Linux系统里我们要销毁一个文件,扔掉一个文件,那我们就吧这个文件放到这里。以上代码把标准输入,输出,错误,都关联了这里,从此该程序的输入输出,错误都扔到了这里。