Code: Select all
// Daemon Demo
// Demo code for daemon programs
// Author: guitat
// Date: 18/01/2014
// File name: daemondemo.c
// Features:
// 1) start, stop and status function
// 2) pid file management
// 3) system log implemented
#include <stdio.h>
#include <stdarg.h>
#include <string.h>
#include <stdlib.h>
#include <libconfig.h>
#include <unistd.h>
#include <signal.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <syslog.h>
// change these value as well
const char *filepid="/run/daemondemo.pid";
const char *logname="daemondemo";
void signal_callback_handler(int signum){
pid_t cpid;
FILE *cfpid;
if( access( filepid, F_OK ) != -1 ){
cfpid=fopen(filepid,"r");
fscanf(cfpid, "%d\n", &cpid);
fclose(cfpid);
if (cpid==getpid()){
closelog();
remove(filepid);
abort();
}
}
}
static void daemonize(){
pid_t dpid;
FILE *dfpid;
/* Fork off the parent process */
dpid = fork();
/* An error occurred */
if (dpid < 0)
exit(EXIT_FAILURE);
/* Success: Let the parent terminate */
if (dpid > 0)
exit(EXIT_SUCCESS);
/* On success: The child process becomes session leader */
if (setsid() < 0)
exit(EXIT_FAILURE);
/* Catch, ignore and handle signals */
//TODO: Implement a working signal handler */
//signal(SIGCHLD, SIG_IGN);
//signal(SIGHUP, SIG_IGN);
/* Fork off for the second time*/
dpid = fork();
/* An error occurred */
if (dpid < 0)
exit(EXIT_FAILURE);
/* Success: Let the parent terminate */
if (dpid > 0)
exit(EXIT_SUCCESS);
/* Set new file permissions */
umask(0);
/* Change the working directory to the root directory */
/* or another appropriated directory */
chdir("/");
/* Close all open file descriptors */
int x;
for (x = sysconf(_SC_OPEN_MAX); x>0; x--)
{
close (x);
}
// Saving pid in the .pid file
dfpid=fopen(filepid,"w");
fprintf(dfpid, "%d\n", getpid());
fclose(dfpid);
/* Open the log file */
openlog (logname, LOG_PID, LOG_DAEMON);
signal(SIGINT, signal_callback_handler);
signal(SIGHUP, signal_callback_handler);
signal(SIGTERM, signal_callback_handler);
signal(SIGQUIT, signal_callback_handler);
}
int main (int argc, char **argv)
{
FILE *fpid;
pid_t pid=0;
if ( argc != 2 ){
printf ("Usage: %s [start|stop|status]\n", argv[0]);
return 1;
}else{
if (!strcmp(argv[1],"start")){
if( access( filepid, F_OK ) != -1 ) {
// pid file exist: daemon is running
printf("Daemon is already running.\n");
} else {
// pid file doesn't exist: daemon is stopped
daemonize();
/*------------------------------------------------*/
/* INFINITE LOOP WRITE THE BODY OF PROGRAM INSIDE */
/*------------------------------------------------*/
for(;;){
//body of program
}
}
}
if (!strcmp(argv[1],"stop")){
if( access( filepid, F_OK ) != -1 ) {
// pid file exist: daemon is running
printf("Stopping daemon...");
fpid=fopen(filepid,"r");
fscanf(fpid, "%d\n", &pid);
fclose(fpid);
syslog (LOG_NOTICE, "stopping daemon");
closelog();
kill(pid, SIGINT);
printf(" stopped!\n");
} else {
// pid file doesn't exist: daemon is stopped
printf("Daemon is not running.\n");
}
}
if (!strcmp(argv[1],"status")){
if( access( filepid, F_OK ) != -1 ) {
// pid file exist: daemon is running
fpid=fopen(filepid,"r");
fscanf(fpid, "%d\n", &pid);
fclose(fpid);
printf("Daemon is running with pid: %d.\n",pid);
} else {
// pid file doesn't exist: daemon is stopped
printf("Daemon is stopped.\n");
}
}
}
return(EXIT_SUCCESS);
}
Code: Select all
gcc -Wall daemondemo.c -o daemondemo