Sie können unter Linux keinen Prozess erstellen, der nicht beendet werden kann. Der Root-Benutzer (uid = 0) kann ein Signal an einen Prozess senden, und es gibt zwei Signale, die nicht abgefangen werden können: SIGKILL = 9, SIGSTOP = 19. Andere Signale (wenn sie nicht erfasst werden) können ebenfalls zur Beendigung des Prozesses führen.
Möglicherweise möchten Sie eine allgemeinere Daemonisierungsfunktion, in der Sie einen Namen für Ihr Programm / Ihren Daemon und einen Pfad zum Ausführen Ihres Programms angeben können (möglicherweise "/" oder "/ tmp"). Möglicherweise möchten Sie auch Dateien für stderr und stdout (und möglicherweise einen Steuerpfad mit stdin) bereitstellen.
Hier sind die notwendigen Includes:
#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)
Und hier ist eine allgemeinere Funktion,
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);
}
Hier ist ein Beispielprogramm, das zu einem Daemon wird, herumhängt und dann geht.
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);
}
Beachten Sie, dass SIG_IGN anzeigt, dass das Signal abgefangen und ignoriert werden soll. Sie können einen Signalhandler erstellen, der den Signalempfang protokollieren und Flags setzen kann (z. B. ein Flag, das ein ordnungsgemäßes Herunterfahren anzeigt).