คุณไม่สามารถสร้างกระบวนการใน linux ที่ไม่สามารถฆ่าได้ ผู้ใช้รูท (uid = 0) สามารถส่งสัญญาณไปยังโปรเซสและมีสองสัญญาณที่ไม่สามารถจับได้ SIGKILL = 9, SIGSTOP = 19 และสัญญาณอื่น ๆ (เมื่อไม่มีการตรวจจับ) อาจส่งผลให้กระบวนการยุติลงได้เช่นกัน
คุณอาจต้องการฟังก์ชัน daemonize ทั่วไปมากขึ้นซึ่งคุณสามารถระบุชื่อสำหรับโปรแกรม / daemon ของคุณและเส้นทางในการรันโปรแกรมของคุณ (อาจเป็น "/" หรือ "/ 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 ระบุว่าจับและละเว้นสัญญาณ คุณสามารถสร้างตัวจัดการสัญญาณที่สามารถบันทึกการรับสัญญาณและตั้งค่าแฟล็ก (เช่นแฟล็กเพื่อระบุการปิดระบบอย่างสง่างาม)