daemon (守护) 程序编写规则:
1. 程序运行后调用 fork, 并让父进程退出, 子进程获得一个新的进程 ID, 但继承了父进程的进程组 ID
2. 调用 setsid 创建一个新的 session, 使自己成为新 session 和新进程组的 leader, 并使进程没有控制终端 (tty)
3. 改变当前工作目录至根目录, 以免影响可加载文件系统, 或者也可以改变到某些特定的目录
4. 设置文件创建 mask 为 0, 避免创建文件时权限的影响
5. 关闭不需要的打开文件描述符, 因为 daemon 程序在后台执行, 不需要于终端交互, 通常就关闭 STDIN, STDOUT 和 STDERR, 其它根据实际情况处理, 另一个问题是 daemon 程序不能和终端交互, 也就无法使用printf方法输出信息了, 可以使用 syslog 机制来实现信息的输出, 方便程序的调试
程序运行后使用 ps 命令查看
$ ps axj | grep a.out
PPID PID PGID SID TTY TPGID STAT UID TIME COMMAND
1 10118 10118 10118 ? -1 Ss 505 0:00 ./a.out
例子:
================================================================================
#include <unistd.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <stdlib.h>
#include <stdio.h>
#include <syslog.h>
#include <signal.h>
int main(void)
{
if(daemon_init() == -1) {
printf("can't fork self/n");
exit(0);
}
openlog("daemontest", LOG_PID, LOG_USER);
syslog(LOG_INFO, "program started.");
signal(SIGTERM, sig_term); /* arrange to catch the signal */
while(1) {
sleep(1); /* put your main program here */
}
return(0);
}
int daemon_init(void)
{
pid_t pid;
if((pid = fork()) < 0)
return(-1);
else if(pid != 0)
exit(0); /* parent exit */
/* child continues */
setsid(); /* become session leader */
chdir("/"); /* change working directory */
umask(0); /* clear file mode creation mask */
close(0); /* close stdin */
close(1); /* close stdout */
close(2); /* close stderr */
return(0);
}
void sig_term(int signo)
{
if(signo == SIGTERM)
/* catched signal sent by kill(1) command */
{
syslog(LOG_INFO, "program terminated.");
closelog();
exit(0);
}
}
================================================================================
1. 程序运行后调用 fork, 并让父进程退出, 子进程获得一个新的进程 ID, 但继承了父进程的进程组 ID
2. 调用 setsid 创建一个新的 session, 使自己成为新 session 和新进程组的 leader, 并使进程没有控制终端 (tty)
3. 改变当前工作目录至根目录, 以免影响可加载文件系统, 或者也可以改变到某些特定的目录
4. 设置文件创建 mask 为 0, 避免创建文件时权限的影响
5. 关闭不需要的打开文件描述符, 因为 daemon 程序在后台执行, 不需要于终端交互, 通常就关闭 STDIN, STDOUT 和 STDERR, 其它根据实际情况处理, 另一个问题是 daemon 程序不能和终端交互, 也就无法使用printf方法输出信息了, 可以使用 syslog 机制来实现信息的输出, 方便程序的调试
程序运行后使用 ps 命令查看
$ ps axj | grep a.out
PPID PID PGID SID TTY TPGID STAT UID TIME COMMAND
1 10118 10118 10118 ? -1 Ss 505 0:00 ./a.out
例子:
================================================================================
#include <unistd.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <stdlib.h>
#include <stdio.h>
#include <syslog.h>
#include <signal.h>
int main(void)
{
if(daemon_init() == -1) {
printf("can't fork self/n");
exit(0);
}
openlog("daemontest", LOG_PID, LOG_USER);
syslog(LOG_INFO, "program started.");
signal(SIGTERM, sig_term); /* arrange to catch the signal */
while(1) {
sleep(1); /* put your main program here */
}
return(0);
}
int daemon_init(void)
{
pid_t pid;
if((pid = fork()) < 0)
return(-1);
else if(pid != 0)
exit(0); /* parent exit */
/* child continues */
setsid(); /* become session leader */
chdir("/"); /* change working directory */
umask(0); /* clear file mode creation mask */
close(0); /* close stdin */
close(1); /* close stdout */
close(2); /* close stderr */
return(0);
}
void sig_term(int signo)
{
if(signo == SIGTERM)
/* catched signal sent by kill(1) command */
{
syslog(LOG_INFO, "program terminated.");
closelog();
exit(0);
}
}
================================================================================
0 件のコメント:
コメントを投稿