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 }