testd.c

This is an example for the usage of libdaemon

00001 /***
00002   This file is part of libdaemon.
00003 
00004   Copyright 2003-2008 Lennart Poettering
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 the
00009   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, see
00018   <http://www.gnu.org/licenses/>.
00019 ***/
00020 
00021 #include <signal.h>
00022 #include <errno.h>
00023 #include <string.h>
00024 #include <sys/types.h>
00025 #include <sys/time.h>
00026 #include <sys/unistd.h>
00027 #include <sys/select.h>
00028 
00029 #include <libdaemon/dfork.h>
00030 #include <libdaemon/dsignal.h>
00031 #include <libdaemon/dlog.h>
00032 #include <libdaemon/dpid.h>
00033 #include <libdaemon/dexec.h>
00034 
00035 int main(int argc, char *argv[]) {
00036     pid_t pid;
00037 
00038     /* Reset signal handlers */
00039     if (daemon_reset_sigs(-1) < 0) {
00040         daemon_log(LOG_ERR, "Failed to reset all signal handlers: %s", strerror(errno));
00041         return 1;
00042     }
00043 
00044     /* Unblock signals */
00045     if (daemon_unblock_sigs(-1) < 0) {
00046         daemon_log(LOG_ERR, "Failed to unblock all signals: %s", strerror(errno));
00047         return 1;
00048     }
00049 
00050     /* Set indetification string for the daemon for both syslog and PID file */
00051     daemon_pid_file_ident = daemon_log_ident = daemon_ident_from_argv0(argv[0]);
00052 
00053     /* Check if we are called with -k parameter */
00054     if (argc >= 2 && !strcmp(argv[1], "-k")) {
00055         int ret;
00056 
00057         /* Kill daemon with SIGINT */
00058 
00059         /* Check if the new function daemon_pid_file_kill_wait() is available, if it is, use it. */
00060         if ((ret = daemon_pid_file_kill_wait(SIGINT, 5)) < 0)
00061             daemon_log(LOG_WARNING, "Failed to kill daemon: %s", strerror(errno));
00062 
00063         return ret < 0 ? 1 : 0;
00064     }
00065 
00066     /* Check that the daemon is not rung twice a the same time */
00067     if ((pid = daemon_pid_file_is_running()) >= 0) {
00068         daemon_log(LOG_ERR, "Daemon already running on PID file %u", pid);
00069         return 1;
00070     }
00071 
00072     /* Prepare for return value passing from the initialization procedure of the daemon process */
00073     daemon_retval_init();
00074 
00075     /* Do the fork */
00076     if ((pid = daemon_fork()) < 0) {
00077 
00078         /* Exit on error */
00079         daemon_retval_done();
00080         return 1;
00081 
00082     } else if (pid) { /* The parent */
00083         int ret;
00084 
00085         /* Wait for 20 seconds for the return value passed from the daemon process */
00086         if ((ret = daemon_retval_wait(20)) < 0) {
00087             daemon_log(LOG_ERR, "Could not recieve return value from daemon process: %s", strerror(errno));
00088             return 255;
00089         }
00090 
00091         daemon_log(ret != 0 ? LOG_ERR : LOG_INFO, "Daemon returned %i as return value.", ret);
00092         return ret;
00093 
00094     } else { /* The daemon */
00095         int fd, quit = 0;
00096         fd_set fds;
00097 
00098         /* Close FDs */
00099         if (daemon_close_all(-1) < 0) {
00100             daemon_log(LOG_ERR, "Failed to close all file descriptors: %s", strerror(errno));
00101 
00102             /* Send the error condition to the parent process */
00103             daemon_retval_send(1);
00104             goto finish;
00105         }
00106 
00107         /* Create the PID file */
00108         if (daemon_pid_file_create() < 0) {
00109             daemon_log(LOG_ERR, "Could not create PID file (%s).", strerror(errno));
00110             daemon_retval_send(2);
00111             goto finish;
00112         }
00113 
00114         /* Initialize signal handling */
00115         if (daemon_signal_init(SIGINT, SIGTERM, SIGQUIT, SIGHUP, 0) < 0) {
00116             daemon_log(LOG_ERR, "Could not register signal handlers (%s).", strerror(errno));
00117             daemon_retval_send(3);
00118             goto finish;
00119         }
00120 
00121         /*... do some further init work here */
00122 
00123 
00124         /* Send OK to parent process */
00125         daemon_retval_send(0);
00126 
00127         daemon_log(LOG_INFO, "Sucessfully started");
00128 
00129         /* Prepare for select() on the signal fd */
00130         FD_ZERO(&fds);
00131         fd = daemon_signal_fd();
00132         FD_SET(fd, &fds);
00133 
00134         while (!quit) {
00135             fd_set fds2 = fds;
00136 
00137             /* Wait for an incoming signal */
00138             if (select(FD_SETSIZE, &fds2, 0, 0, 0) < 0) {
00139 
00140                 /* If we've been interrupted by an incoming signal, continue */
00141                 if (errno == EINTR)
00142                     continue;
00143 
00144                 daemon_log(LOG_ERR, "select(): %s", strerror(errno));
00145                 break;
00146             }
00147 
00148             /* Check if a signal has been recieved */
00149             if (FD_ISSET(fd, &fds)) {
00150                 int sig;
00151 
00152                 /* Get signal */
00153                 if ((sig = daemon_signal_next()) <= 0) {
00154                     daemon_log(LOG_ERR, "daemon_signal_next() failed: %s", strerror(errno));
00155                     break;
00156                 }
00157 
00158                 /* Dispatch signal */
00159                 switch (sig) {
00160 
00161                     case SIGINT:
00162                     case SIGQUIT:
00163                     case SIGTERM:
00164                         daemon_log(LOG_WARNING, "Got SIGINT, SIGQUIT or SIGTERM");
00165                         quit = 1;
00166                         break;
00167 
00168                     case SIGHUP:
00169                         daemon_log(LOG_INFO, "Got a HUP");
00170                         daemon_exec("/", NULL, "/bin/ls", "ls", (char*) NULL);
00171                         break;
00172 
00173                 }
00174             }
00175         }
00176 
00177         /* Do a cleanup */
00178 finish:
00179         daemon_log(LOG_INFO, "Exiting...");
00180         daemon_retval_send(255);
00181         daemon_signal_done();
00182         daemon_pid_file_remove();
00183 
00184         return 0;
00185     }
00186 }

Generated on Fri Mar 27 11:42:57 2009 for libdaemon by  doxygen 1.5.1