testd.c

This is an example for the usage of libdaemon

00001 /* $Id: testd.c 121 2007-06-11 15:45:51Z lennart $ */
00002 
00003 /*
00004  * This file is part of libdaemon.
00005  *
00006  * libdaemon is free software; you can redistribute it and/or modify
00007  * it under the terms of the GNU Lesser General Public License as
00008  * published by the Free Software Foundation; either version 2.1 of
00009  * the License, or (at your option) any later version.
00010  *
00011  * libdaemon is distributed in the hope that it will be useful, but
00012  * WITHOUT ANY WARRANTY; without even the implied warranty of
00013  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
00014  * Lesser General Public License for more details.
00015  *
00016  * You should have received a copy of the GNU Lesser General Public
00017  * License along with libdaemon; if not, write to the Free Software
00018  * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA
00019  * 02110-1301 USA
00020  */
00021 
00022 #include <signal.h>
00023 #include <errno.h>
00024 #include <string.h>
00025 #include <sys/types.h>
00026 #include <sys/time.h>
00027 #include <sys/unistd.h>
00028 #include <sys/select.h>
00029 
00030 #include <libdaemon/dfork.h>
00031 #include <libdaemon/dsignal.h>
00032 #include <libdaemon/dlog.h>
00033 #include <libdaemon/dpid.h>
00034 #include <libdaemon/dexec.h>
00035 
00036 int main(int argc, char *argv[]) {
00037     pid_t pid;
00038 
00039     /* Set indetification string for the daemon for both syslog and PID file */
00040     daemon_pid_file_ident = daemon_log_ident = daemon_ident_from_argv0(argv[0]);
00041 
00042     /* Check if we are called with -k parameter */
00043     if (argc >= 2 && !strcmp(argv[1], "-k")) {
00044         int ret;
00045 
00046         /* Kill daemon with SIGINT */
00047         
00048         /* Check if the new function daemon_pid_file_kill_wait() is available, if it is, use it. */
00049         if ((ret = daemon_pid_file_kill_wait(SIGINT, 5)) < 0)
00050             daemon_log(LOG_WARNING, "Failed to kill daemon");
00051         
00052         return ret < 0 ? 1 : 0;
00053     }
00054 
00055     /* Check that the daemon is not rung twice a the same time */
00056     if ((pid = daemon_pid_file_is_running()) >= 0) {
00057         daemon_log(LOG_ERR, "Daemon already running on PID file %u", pid);
00058         return 1;
00059         
00060     }
00061 
00062     /* Prepare for return value passing from the initialization procedure of the daemon process */
00063     daemon_retval_init();
00064 
00065     /* Do the fork */
00066     if ((pid = daemon_fork()) < 0) {
00067 
00068         /* Exit on error */
00069         daemon_retval_done();
00070         return 1;
00071         
00072     } else if (pid) { /* The parent */
00073         int ret;
00074 
00075         /* Wait for 20 seconds for the return value passed from the daemon process */
00076         if ((ret = daemon_retval_wait(20)) < 0) {
00077             daemon_log(LOG_ERR, "Could not recieve return value from daemon process.");
00078             return 255;
00079         }
00080 
00081         daemon_log(ret != 0 ? LOG_ERR : LOG_INFO, "Daemon returned %i as return value.", ret);
00082         return ret;
00083         
00084     } else { /* The daemon */
00085         int fd, quit = 0;
00086         fd_set fds;
00087 
00088         if (daemon_close_all(-1) < 0) {
00089             daemon_log(LOG_ERR, "Failed to close all file descriptors: %s", strerror(errno));
00090             goto finish;
00091         }
00092         
00093         /* Create the PID file */
00094         if (daemon_pid_file_create() < 0) {
00095             daemon_log(LOG_ERR, "Could not create PID file (%s).", strerror(errno));
00096 
00097             /* Send the error condition to the parent process */
00098             daemon_retval_send(1);
00099             goto finish;
00100         }
00101 
00102         /* Initialize signal handling */
00103         if (daemon_signal_init(SIGINT, SIGTERM, SIGQUIT, SIGHUP, 0) < 0) {
00104             daemon_log(LOG_ERR, "Could not register signal handlers (%s).", strerror(errno));
00105             daemon_retval_send(2);
00106             goto finish;
00107         }
00108         
00109         /*... do some further init work here */
00110 
00111 
00112         /* Send OK to parent process */
00113         daemon_retval_send(0);
00114 
00115         daemon_log(LOG_INFO, "Sucessfully started");
00116 
00117 
00118         /* Prepare for select() on the signal fd */
00119         FD_ZERO(&fds);
00120         FD_SET(fd = daemon_signal_fd(), &fds);
00121         
00122         while (!quit) {
00123             fd_set fds2 = fds;
00124 
00125             /* Wait for an incoming signal */
00126             if (select(FD_SETSIZE, &fds2, 0, 0, 0) < 0) {
00127 
00128                 /* If we've been interrupted by an incoming signal, continue */
00129                 if (errno == EINTR)
00130                     continue;
00131                 
00132                 daemon_log(LOG_ERR, "select(): %s", strerror(errno));
00133                 break;
00134             }
00135 
00136             /* Check if a signal has been recieved */
00137             if (FD_ISSET(fd, &fds)) {
00138                 int sig;
00139 
00140                 /* Get signal */
00141                 if ((sig = daemon_signal_next()) <= 0) {
00142                     daemon_log(LOG_ERR, "daemon_signal_next() failed.");
00143                     break;
00144                 }
00145 
00146                 /* Dispatch signal */
00147                 switch (sig) {
00148 
00149                     case SIGINT:
00150                     case SIGQUIT:
00151                     case SIGTERM:
00152                         daemon_log(LOG_WARNING, "Got SIGINT, SIGQUIT or SIGTERM");
00153                         quit = 1;
00154                         break;
00155 
00156                     case SIGHUP:
00157                         daemon_log(LOG_INFO, "Got a HUP");
00158                         daemon_exec("/", NULL, "/bin/ls", "ls", (char*) NULL);
00159                         break;
00160 
00161                 }
00162             }
00163         }
00164 
00165         /* Do a cleanup */
00166 finish:
00167         daemon_log(LOG_INFO, "Exiting...");
00168         daemon_retval_send(-1);
00169         daemon_signal_done();
00170         daemon_pid_file_remove();
00171         
00172         return 0;
00173     }
00174 }

Generated on Wed Jul 11 01:39:11 2007 for libdaemon by  doxygen 1.5.1