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();