在Linux中,无法创建一个无法被杀死的进程。根用户(uid=0)可以向进程发送信号,有两个信号无法被捕获,分别是SIGKILL=9和SIGSTOP=19。当其他信号无法被捕获时也可能导致进程终止。
您可能需要一个更通用的daemonize函数,其中可以指定程序/守护程序的名称和运行程序的路径(例如“/”或“/tmp”)。您还可以提供stderr和stdout的文件(以及可能使用stdin的控件路径)。
以下是必要的包含内容:
#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <signal.h>
#include <sys/stat.h>
#include <syslog.h>
这里有一个更通用的函数:
int
daemonize(char* name, char* path, char* outfile, char* errfile, char* infile )
{
if(!path) { path="/"; }
if(!name) { name="medaemon"; }
if(!infile) { infile="/dev/null"; }
if(!outfile) { outfile="/dev/null"; }
if(!errfile) { errfile="/dev/null"; }
pid_t child;
if( (child=fork())<0 ) {
fprintf(stderr,"error: failed fork\n");
exit(EXIT_FAILURE);
}
if (child>0) {
exit(EXIT_SUCCESS);
}
if( setsid()<0 ) {
fprintf(stderr,"error: failed setsid\n");
exit(EXIT_FAILURE);
}
signal(SIGCHLD,SIG_IGN);
signal(SIGHUP,SIG_IGN);
if ( (child=fork())<0) {
fprintf(stderr,"error: failed fork\n");
exit(EXIT_FAILURE);
}
if( child>0 ) {
exit(EXIT_SUCCESS);
}
umask(0);
chdir(path);
int fd;
for( fd=sysconf(_SC_OPEN_MAX); fd>0; --fd )
{
close(fd);
}
stdin=fopen(infile,"r");
stdout=fopen(outfile,"w+");
stderr=fopen(errfile,"w+");
openlog(name,LOG_PID,LOG_DAEMON);
return(0);
}
这是一个样例程序,它会变成一个守护进程(daemon),并持续运行一段时间后退出。
int
main()
{
int res;
int ttl=120;
int delay=5;
if( (res=daemonize("mydaemon","/tmp",NULL,NULL,NULL)) != 0 ) {
fprintf(stderr,"error: daemonize failed\n");
exit(EXIT_FAILURE);
}
while( ttl>0 ) {
syslog(LOG_NOTICE,"daemon ttl %d",ttl);
sleep(delay);
ttl-=delay;
}
syslog(LOG_NOTICE,"daemon ttl expired");
closelog();
return(EXIT_SUCCESS);
}
请注意,SIG_IGN 表示捕获并忽略信号。您可以构建一个信号处理程序,记录信号接收情况并设置标志(例如,指示优雅关闭的标志)。