/** * Compile: cc daemonize.c -o daemonize * * Execute: daemonize */ #include #include #include #include #include #include #include char *logfile; char *pidfile; char *command; void log_message(char *message) { FILE *logf; logf=fopen(logfile,"a"); if ( !logf ) { return; } fprintf(logf,"%s",message); fclose(logf); } void signal_handler(int sig) { switch(sig) { case SIGHUP: log_message("hangup signal caught\n"); break; case SIGTERM: log_message("terminate signal caught\n"); exit(0); break; } } void daemonize() { int i; int lfp; char str[1024]; // START: Fork if ( getppid() == 1 ) { return; /* already a daemon */ } i = fork(); if ( i < 0 ) { exit(1); /* fork error */ } if ( i > 0 ) { exit(0); /* parent exits */ } setsid(); /* obtain a new process group */ // STOP: Fork // START: Detach for ( i = getdtablesize(); i >= 0; --i ) { close(i); /* close all descriptors */ } i = open( "/dev/null", O_RDWR ); dup(i); dup(i); // STOP: Detach // SART: locking, pidfile umask(027); /* set newly created file permissions */ lfp = open( pidfile, O_RDWR|O_CREAT, 0640); if ( lfp < 0 ) { exit(1); /* can not open */ } if ( lockf( lfp, F_TLOCK, 0 ) < 0 ) { exit(0); /* can not lock */ } /* first instance continues */ sprintf( str, "%d\n", getpid() ); write( lfp, str, strlen(str) ); /* record pid to lockfile */ // STOP: locking, pidfile signal( SIGCHLD, SIG_IGN ); /* ignore child */ signal( SIGTSTP, SIG_IGN ); /* ignore tty signals */ signal( SIGTTOU, SIG_IGN ); signal( SIGTTIN, SIG_IGN ); signal( SIGHUP, signal_handler ); /* catch hangup signal */ signal( SIGTERM, signal_handler ); /* catch kill signal */ sprintf(str, "Daemon Started: %s (%d)\n", command, getpid()); log_message(str); } int main( int argc, char *argv[] ) { if ( argc < 4 ) { printf("Usage:\t%s pidfile logfile executable\n", argv[0]); return 1; } pidfile = argv[1]; logfile = argv[2]; command = argv[3]; daemonize(); FILE *fpipe; char str[1024]; if ( !(fpipe = (FILE*)popen(command,"r")) ) { sprintf( str, "Unable to execute command via pipe: %s\n", command ); log_message( str ); return 1; } while ( fgets( str, sizeof str, fpipe)) { log_message( str ); } pclose(fpipe); return 0; }