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/>.
24 #include <sys/types.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[]) {
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));
45 if (daemon_unblock_sigs(-1) < 0) {
46 daemon_log(LOG_ERR, "Failed to unblock all signals: %s", strerror(errno));
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")) {
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);
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.");
79 if ((pid = daemon_fork()) < 0) {
85 } else if (pid) { /* The parent */
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));
94 daemon_log(ret != 0 ? LOG_ERR : LOG_INFO, "Daemon returned %i as return value.", ret);
97 } else { /* The daemon */
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);
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);
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);
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 */
134 fd = daemon_signal_fd();
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 */
147 daemon_log(LOG_ERR, "select(): %s", strerror(errno));
151 /* Check if a signal has been recieved */
152 if (FD_ISSET(fd, &fds2)) {
156 if ((sig = daemon_signal_next()) <= 0) {
157 daemon_log(LOG_ERR, "daemon_signal_next() failed: %s", strerror(errno));
161 /* Dispatch signal */
167 daemon_log(LOG_WARNING, "Got SIGINT, SIGQUIT or SIGTERM.");
172 daemon_log(LOG_INFO, "Got a HUP");
173 daemon_exec("/", NULL, "/bin/ls", "ls", (char*) NULL);
182 daemon_log(LOG_INFO, "Exiting...");
183 daemon_retval_send(255);
184 daemon_signal_done();
185 daemon_pid_file_remove();