리눅스에서는 죽일 수없는 프로세스를 만들 수 없습니다. 루트 사용자 (uid = 0)는 프로세스에 신호를 보낼 수 있으며 잡을 수없는 신호는 SIGKILL = 9, SIGSTOP = 19입니다. 그리고 다른 신호 (잡히지 않은 경우)도 프로세스를 종료 할 수 있습니다.
프로그램 / 데몬의 이름과 프로그램을 실행할 경로 (예 : "/"또는 "/ tmp")를 지정할 수있는보다 일반적인 데몬 화 기능이 필요할 수 있습니다. stderr 및 stdout (및 stdin을 사용하는 제어 경로)에 대한 파일을 제공 할 수도 있습니다.
필요한 것은 다음과 같습니다.
#include <stdio.h> //printf(3)
#include <stdlib.h> //exit(3)
#include <unistd.h> //fork(3), chdir(3), sysconf(3)
#include <signal.h> //signal(3)
#include <sys/stat.h> //umask(3)
#include <syslog.h> //syslog(3), openlog(3), closelog(3)
여기 더 일반적인 기능이 있습니다.
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"; }
//printf("%s %s %s %s\n",name,path,outfile,infile);
pid_t child;
//fork, detach from process group leader
if( (child=fork())<0 ) { //failed fork
fprintf(stderr,"error: failed fork\n");
exit(EXIT_FAILURE);
}
if (child>0) { //parent
exit(EXIT_SUCCESS);
}
if( setsid()<0 ) { //failed to become session leader
fprintf(stderr,"error: failed setsid\n");
exit(EXIT_FAILURE);
}
//catch/ignore signals
signal(SIGCHLD,SIG_IGN);
signal(SIGHUP,SIG_IGN);
//fork second time
if ( (child=fork())<0) { //failed fork
fprintf(stderr,"error: failed fork\n");
exit(EXIT_FAILURE);
}
if( child>0 ) { //parent
exit(EXIT_SUCCESS);
}
//new file permissions
umask(0);
//change to path directory
chdir(path);
//Close all open file descriptors
int fd;
for( fd=sysconf(_SC_OPEN_MAX); fd>0; --fd )
{
close(fd);
}
//reopen stdin, stdout, stderr
stdin=fopen(infile,"r"); //fd=0
stdout=fopen(outfile,"w+"); //fd=1
stderr=fopen(errfile,"w+"); //fd=2
//open syslog
openlog(name,LOG_PID,LOG_DAEMON);
return(0);
}
다음은 데몬이되어 주위를 맴돌다가 떠나는 샘플 프로그램입니다.
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 ) {
//daemon code here
syslog(LOG_NOTICE,"daemon ttl %d",ttl);
sleep(delay);
ttl-=delay;
}
syslog(LOG_NOTICE,"daemon ttl expired");
closelog();
return(EXIT_SUCCESS);
}
SIG_IGN은 신호를 포착하고 무시 함을 나타냅니다. 신호 수신을 기록 할 수있는 신호 처리기를 빌드하고 플래그 (예 : 정상 종료를 나타내는 플래그)를 설정할 수 있습니다.