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