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/>.
25 #include <sys/types.h>
46 int daemon_execv(const char *dir, int *ret, const char *prog, va_list ap) {
55 assert(daemon_signal_fd() >= 0);
58 daemon_log(LOG_ERR, "pipe() failed: %s", strerror(errno));
62 if ((pid = fork()) < 0) {
63 daemon_log(LOG_ERR, "fork() failed: %s", strerror(errno));
72 } else if (pid == 0) {
77 if (dup2(p[1], 1) < 0) {
78 daemon_log(LOG_ERR, "dup2: %s", strerror(errno));
83 if (dup2(p[1], 2) < 0) {
84 daemon_log(LOG_ERR, "dup2: %s", strerror(errno));
97 if (open("/dev/null", O_RDONLY) != 0) {
98 daemon_log(LOG_ERR, "Unable to open /dev/null as STDIN");
102 daemon_close_all(-1);
103 daemon_reset_sigs(-1);
104 daemon_unblock_sigs(-1);
106 umask(0022); /* Set up a sane umask */
108 if (dir && chdir(dir) < 0) {
109 daemon_log(LOG_WARNING, "Failed to change to directory '%s'", dir);
113 for (i = 0; i < MAX_ARGS-1; i++)
114 if (!(args[i] = va_arg(ap, char*)))
120 daemon_log(LOG_ERR, "execv(%s) failed: %s", prog, strerror(errno));
131 sigfd = daemon_signal_fd();
139 if (select(FD_SETSIZE, &qfds, NULL, NULL, NULL) < 0) {
144 daemon_log(LOG_ERR, "select() failed: %s", strerror(errno));
152 if (FD_ISSET(p[0], &qfds)) {
155 if (read(p[0], &c, 1) != 1)
160 if (c == '\n' || n >= sizeof(buf) - 2) {
165 daemon_log(LOG_INFO, "client: %s", buf);
172 if (FD_ISSET(sigfd, &qfds)) {
175 if ((sig = daemon_signal_next()) < 0) {
182 if (sig != SIGCHLD) {
183 daemon_log(LOG_WARNING, "Killing child.");
191 daemon_log(LOG_WARNING, "client: %s", buf);
197 if (waitpid(pid, &r, 0) < 0) {
202 daemon_log(LOG_ERR, "waitpid(): %s", strerror(errno));
211 *ret = WEXITSTATUS(r);
218 int daemon_exec(const char *dir, int *ret, const char *prog, ...) {
223 r = daemon_execv(dir, ret, prog, ap);