00001 /* $Id: testd.c 101 2005-11-18 20:39:12Z 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 #ifdef DAEMON_PID_FILE_KILL_WAIT_AVAILABLE 00050 if ((ret = daemon_pid_file_kill_wait(SIGINT, 5)) < 0) 00051 #else 00052 if ((ret = daemon_pid_file_kill(SIGINT)) < 0) 00053 #endif 00054 daemon_log(LOG_WARNING, "Failed to kill daemon"); 00055 00056 return ret < 0 ? 1 : 0; 00057 } 00058 00059 /* Check that the daemon is not rung twice a the same time */ 00060 if ((pid = daemon_pid_file_is_running()) >= 0) { 00061 daemon_log(LOG_ERR, "Daemon already running on PID file %u", pid); 00062 return 1; 00063 00064 } 00065 00066 /* Prepare for return value passing from the initialization procedure of the daemon process */ 00067 daemon_retval_init(); 00068 00069 /* Do the fork */ 00070 if ((pid = daemon_fork()) < 0) { 00071 00072 /* Exit on error */ 00073 daemon_retval_done(); 00074 return 1; 00075 00076 } else if (pid) { /* The parent */ 00077 int ret; 00078 00079 /* Wait for 20 seconds for the return value passed from the daemon process */ 00080 if ((ret = daemon_retval_wait(20)) < 0) { 00081 daemon_log(LOG_ERR, "Could not recieve return value from daemon process."); 00082 return 255; 00083 } 00084 00085 daemon_log(ret != 0 ? LOG_ERR : LOG_INFO, "Daemon returned %i as return value.", ret); 00086 return ret; 00087 00088 } else { /* The daemon */ 00089 int fd, quit = 0; 00090 fd_set fds; 00091 00092 /* Create the PID file */ 00093 if (daemon_pid_file_create() < 0) { 00094 daemon_log(LOG_ERR, "Could not create PID file (%s).", strerror(errno)); 00095 00096 /* Send the error condition to the parent process */ 00097 daemon_retval_send(1); 00098 goto finish; 00099 } 00100 00101 /* Initialize signal handling */ 00102 if (daemon_signal_init(SIGINT, SIGQUIT, SIGHUP, 0) < 0) { 00103 daemon_log(LOG_ERR, "Could not register signal handlers (%s).", strerror(errno)); 00104 daemon_retval_send(2); 00105 goto finish; 00106 } 00107 00108 /*... do some further init work here */ 00109 00110 00111 /* Send OK to parent process */ 00112 daemon_retval_send(0); 00113 00114 daemon_log(LOG_INFO, "Sucessfully started"); 00115 00116 00117 /* Prepare for select() on the signal fd */ 00118 FD_ZERO(&fds); 00119 FD_SET(fd = daemon_signal_fd(), &fds); 00120 00121 while (!quit) { 00122 fd_set fds2 = fds; 00123 00124 /* Wait for an incoming signal */ 00125 if (select(FD_SETSIZE, &fds2, 0, 0, 0) < 0) { 00126 00127 /* If we've been interrupted by an incoming signal, continue */ 00128 if (errno == EINTR) 00129 continue; 00130 00131 daemon_log(LOG_ERR, "select(): %s", strerror(errno)); 00132 break; 00133 } 00134 00135 /* Check if a signal has been recieved */ 00136 if (FD_ISSET(fd, &fds)) { 00137 int sig; 00138 00139 /* Get signal */ 00140 if ((sig = daemon_signal_next()) <= 0) { 00141 daemon_log(LOG_ERR, "daemon_signal_next() failed."); 00142 break; 00143 } 00144 00145 /* Dispatch signal */ 00146 switch (sig) { 00147 00148 case SIGINT: 00149 case SIGQUIT: 00150 daemon_log(LOG_WARNING, "Got SIGINT or SIGQUIT"); 00151 quit = 1; 00152 break; 00153 00154 case SIGHUP: 00155 daemon_log(LOG_INFO, "Got a HUP"); 00156 daemon_exec("/", NULL, "/bin/ls", "ls", (char*) NULL); 00157 break; 00158 00159 } 00160 } 00161 } 00162 00163 /* Do a cleanup */ 00164 finish: 00165 daemon_log(LOG_INFO, "Exiting..."); 00166 00167 daemon_signal_done(); 00168 daemon_pid_file_remove(); 00169 00170 return 0; 00171 } 00172 }