Don't enable dnsmasq IPSET functionality on 2.4 kernel
[tomato.git] / release / src / router / libdaemon / examples / testd.c
blob6557dff9999c1345f989b272d02a81aca12ed60b
1 /***
2 This file is part of libdaemon.
4 Copyright 2003-2008 Lennart Poettering
6 libdaemon is free software; you can redistribute it and/or modify
7 it under the terms of the GNU Lesser General Public License as
8 published by the Free Software Foundation, either version 2.1 of the
9 License, or (at your option) any later version.
11 libdaemon is distributed in the hope that it will be useful, but
12 WITHOUT ANY WARRANTY; without even the implied warranty of
13 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
14 Lesser General Public License for more details.
16 You should have received a copy of the GNU Lesser General Public
17 License along with libdaemon. If not, see
18 <http://www.gnu.org/licenses/>.
19 ***/
21 #include <signal.h>
22 #include <errno.h>
23 #include <string.h>
24 #include <sys/types.h>
25 #include <sys/time.h>
26 #include <sys/unistd.h>
27 #include <sys/select.h>
29 #include <libdaemon/dfork.h>
30 #include <libdaemon/dsignal.h>
31 #include <libdaemon/dlog.h>
32 #include <libdaemon/dpid.h>
33 #include <libdaemon/dexec.h>
35 int main(int argc, char *argv[]) {
36 pid_t pid;
38 /* Reset signal handlers */
39 if (daemon_reset_sigs(-1) < 0) {
40 daemon_log(LOG_ERR, "Failed to reset all signal handlers: %s", strerror(errno));
41 return 1;
44 /* Unblock signals */
45 if (daemon_unblock_sigs(-1) < 0) {
46 daemon_log(LOG_ERR, "Failed to unblock all signals: %s", strerror(errno));
47 return 1;
50 /* Set indetification string for the daemon for both syslog and PID file */
51 daemon_pid_file_ident = daemon_log_ident = daemon_ident_from_argv0(argv[0]);
53 /* Check if we are called with -k parameter */
54 if (argc >= 2 && !strcmp(argv[1], "-k")) {
55 int ret;
57 /* Kill daemon with SIGTERM */
59 /* Check if the new function daemon_pid_file_kill_wait() is available, if it is, use it. */
60 if ((ret = daemon_pid_file_kill_wait(SIGTERM, 5)) < 0)
61 daemon_log(LOG_WARNING, "Failed to kill daemon: %s", strerror(errno));
63 return ret < 0 ? 1 : 0;
66 /* Check that the daemon is not rung twice a the same time */
67 if ((pid = daemon_pid_file_is_running()) >= 0) {
68 daemon_log(LOG_ERR, "Daemon already running on PID file %u", pid);
69 return 1;
72 /* Prepare for return value passing from the initialization procedure of the daemon process */
73 if (daemon_retval_init() < 0) {
74 daemon_log(LOG_ERR, "Failed to create pipe.");
75 return 1;
78 /* Do the fork */
79 if ((pid = daemon_fork()) < 0) {
81 /* Exit on error */
82 daemon_retval_done();
83 return 1;
85 } else if (pid) { /* The parent */
86 int ret;
88 /* Wait for 20 seconds for the return value passed from the daemon process */
89 if ((ret = daemon_retval_wait(20)) < 0) {
90 daemon_log(LOG_ERR, "Could not recieve return value from daemon process: %s", strerror(errno));
91 return 255;
94 daemon_log(ret != 0 ? LOG_ERR : LOG_INFO, "Daemon returned %i as return value.", ret);
95 return ret;
97 } else { /* The daemon */
98 int fd, quit = 0;
99 fd_set fds;
101 /* Close FDs */
102 if (daemon_close_all(-1) < 0) {
103 daemon_log(LOG_ERR, "Failed to close all file descriptors: %s", strerror(errno));
105 /* Send the error condition to the parent process */
106 daemon_retval_send(1);
107 goto finish;
110 /* Create the PID file */
111 if (daemon_pid_file_create() < 0) {
112 daemon_log(LOG_ERR, "Could not create PID file (%s).", strerror(errno));
113 daemon_retval_send(2);
114 goto finish;
117 /* Initialize signal handling */
118 if (daemon_signal_init(SIGINT, SIGTERM, SIGQUIT, SIGHUP, 0) < 0) {
119 daemon_log(LOG_ERR, "Could not register signal handlers (%s).", strerror(errno));
120 daemon_retval_send(3);
121 goto finish;
124 /*... do some further init work here */
127 /* Send OK to parent process */
128 daemon_retval_send(0);
130 daemon_log(LOG_INFO, "Sucessfully started");
132 /* Prepare for select() on the signal fd */
133 FD_ZERO(&fds);
134 fd = daemon_signal_fd();
135 FD_SET(fd, &fds);
137 while (!quit) {
138 fd_set fds2 = fds;
140 /* Wait for an incoming signal */
141 if (select(FD_SETSIZE, &fds2, 0, 0, 0) < 0) {
143 /* If we've been interrupted by an incoming signal, continue */
144 if (errno == EINTR)
145 continue;
147 daemon_log(LOG_ERR, "select(): %s", strerror(errno));
148 break;
151 /* Check if a signal has been recieved */
152 if (FD_ISSET(fd, &fds2)) {
153 int sig;
155 /* Get signal */
156 if ((sig = daemon_signal_next()) <= 0) {
157 daemon_log(LOG_ERR, "daemon_signal_next() failed: %s", strerror(errno));
158 break;
161 /* Dispatch signal */
162 switch (sig) {
164 case SIGINT:
165 case SIGQUIT:
166 case SIGTERM:
167 daemon_log(LOG_WARNING, "Got SIGINT, SIGQUIT or SIGTERM.");
168 quit = 1;
169 break;
171 case SIGHUP:
172 daemon_log(LOG_INFO, "Got a HUP");
173 daemon_exec("/", NULL, "/bin/ls", "ls", (char*) NULL);
174 break;
180 /* Do a cleanup */
181 finish:
182 daemon_log(LOG_INFO, "Exiting...");
183 daemon_retval_send(255);
184 daemon_signal_done();
185 daemon_pid_file_remove();
187 return 0;