创建一个守护进程,有几个关键的步骤,也有几个地方需要注意,
几个关键的步骤有:
1:清除文件创建权限
2:调用fork,然后使父进程退出
3:调用setsid以创建一个新的会话,有三个目的使调用进程 a:成为新会话的首进程,b:成为新进程的组长进程,c:没有控制终端
4:切换工作目录
5:关闭不需要的文件描述符
需要注意的地方
1:因为守护进程没有控制终端,所以不能与标准输入输出出错进行交互,不能使用printf,通常用syslog来解决守护进程的打印信息
参考代码如下:
-
#include <signal.h>
-
#include <stdlib.h>
-
#include <syslog.h>
-
#include <fcntl.h>
-
#include <stdio.h>
-
#include <sys/resource.h>
-
-
void daemonize(const char *cmd)
-
{
-
int i, fd0, fd1, fd2;
-
pid_t pid;
-
struct rlimit rl;
-
struct sigaction sa;
-
-
/*
-
* Clear file creation mask.
-
*/
-
umask(0);
-
-
/*
-
* Get maximum number of file descriptors.
-
*/
-
if (getrlimit(RLIMIT_NOFILE, &rl) < 0)
-
printf("%s: can't get file limit", cmd);
-
-
/*
-
* Become a session leader to lose controlling TTY.
-
*/
-
if ((pid = fork()) < 0)
-
printf("%s: can't fork", cmd);
-
else if (pid != 0) /* parent */
-
exit(0);
-
setsid();
-
-
/*
-
* Ensure future opens won't allocate controlling TTYs.
-
*/
-
sa.sa_handler = SIG_IGN;
-
sigemptyset(&sa.sa_mask);
-
sa.sa_flags = 0;
-
if (sigaction(SIGHUP, &sa, NULL) < 0)
-
printf("can't ignore SIGHUP");
-
if ((pid = fork()) < 0)
-
printf("%s: can't fork", cmd);
-
else if (pid != 0) /* parent */
-
exit(0);
-
-
/*
-
* Change the current working directory to the root so
-
* we won't prevent file systems from being unmounted.
-
*/
-
if (chdir("/") < 0)
-
printf("can't change directory to /");
-
-
/*
-
* Close all open file descriptors.
-
*/
-
if (rl.rlim_max == RLIM_INFINITY)
-
rl.rlim_max = 1024;
-
for (i = 0; i < rl.rlim_max; i++)
-
close(i);
-
-
/*
-
* Attach file descriptors 0, 1, and 2 to /dev/null.
-
*/
-
fd0 = open("/dev/null", O_RDWR);
-
fd1 = dup(0);
-
fd2 = dup(0);
-
-
/*
-
* Initialize the log file.
-
*/
-
openlog(cmd, LOG_CONS, LOG_DAEMON);
-
if (fd0 != 0 || fd1 != 1 || fd2 != 2) {
-
syslog(LOG_ERR, "unexpected file descriptors %d %d %d",fd0, fd1, fd2);
-
exit(1);
-
}
-
syslog(LOG_DEBUG, "daem ok ");
-
-
}
-
int main()
-
{
-
daemonize("test");
-
while(1);//守护进程所要干的事情
-
-
}
阅读(2246) | 评论(0) | 转发(1) |