/* * UNIX Damon Server Programming Sample Program * To compile: cc -o exampled exampled.c * TO run: ./exampled * To test daemon: ps aux | grep exampled * To test log: tail -f /tmp/exampled.log * To test signal: kill -HUP `cat /tmp/exampled.lock` * To terminate: kill `cat /tmp/exampled.lock` */ #include #include #include #include #include #include #include #include #include #define RUNNING_DIR "/tmp" #define LOCK_FILE "exampled.lock" #define LOG_FILE "exampled.log" static const char *months[] = { "Jan","Feb","Mar","Apr","May","Jun", "Jul","Aug","Sep","Oct","Nov","Dec"}; void log_message(char *filename, char *message) { FILE *logfile; char buf[30]; long n = time(NULL); struct tm *now; now = localtime(&n); sprintf(buf, "%02d:%02d:%02d %s %02d %02d", now->tm_hour, now->tm_min, now->tm_sec,months[now->tm_mon], now->tm_mday,now->tm_year % 100); logfile = fopen(filename, "a"); if (!logfile) return; fprintf(logfile, "%s: %s\n", buf, message); fclose(logfile); } void signal_handler(int sig) { switch(sig) { case SIGHUP: log_message(LOG_FILE, "hangup signal catched"); break; case SIGTERM: log_message(LOG_FILE, "terminate signal catched...exiting"); unlink(LOCK_FILE); exit(0); break; } } void daemonize() { int i, lfp; char str[10]; if (getppid() == 1) /* already a daemon */ return; i=fork(); if (i<0) /* fork error */ exit(1); if (i>0) /* parent exits */ exit(0); /* child daemon continues */ setsid(); /* obtain a new process group */ for (i=getdtablesize(); i>=0; --i) close(i); /*close all descriptors*/ i=open("/dev/null", O_RDWR); /* handle std. io */ dup(i); dup(i); umask(027); /* set newly created file permissions */ chdir(RUNNING_DIR); /* change running directory*/ //attempt to create lockfile and put a file-lock on it lfp=open(LOCK_FILE,O_RDWR|O_CREAT, 0640); if (lfp<0) /* can not open */ exit(1); if (lockf(lfp,F_TLOCK,0) < 0) /* can not lock */ exit(0); /* first instance continues */ sprintf(str, "%d\n", getpid() ); /* record pid to lockfile */ write(lfp, str, strlen(str) ); 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 */ log_message(LOG_FILE, "exampled started ..."); } int main() { daemonize(); while(1) sleep(1); /*run*/ return 0; }