diff options
-rw-r--r-- | Makefile.am | 3 | ||||
-rw-r--r-- | configure.ac | 8 | ||||
-rw-r--r-- | doc/README.html.in | 2 | ||||
-rw-r--r-- | examples/testd.c | 2 | ||||
-rw-r--r-- | libdaemon.pc.in | 10 | ||||
-rw-r--r-- | src/Makefile.am | 8 | ||||
-rw-r--r-- | src/daemon.h | 36 | ||||
-rw-r--r-- | src/dexec.c | 173 | ||||
-rw-r--r-- | src/dexec.h | 47 | ||||
-rw-r--r-- | src/dlog.h | 2 |
10 files changed, 281 insertions, 10 deletions
diff --git a/Makefile.am b/Makefile.am index 05b43a6..ca83772 100644 --- a/Makefile.am +++ b/Makefile.am @@ -22,6 +22,9 @@ SUBDIRS=src doc examples MAINTAINERCLEANFILES = README libdaemon.spec noinst_DATA = README libdaemon.spec +pkgconfigdir = $(libdir)/pkgconfig +pkgconfig_DATA = libdaemon.pc + README: rm -f README $(MAKE) -C doc README diff --git a/configure.ac b/configure.ac index 7deb5d8..a7ddaae 100644 --- a/configure.ac +++ b/configure.ac @@ -20,7 +20,7 @@ # Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA. AC_PREREQ(2.57) -AC_INIT([libdaemon], [0.3], [mzqnrzba (at) 0pointer (dot) de]) +AC_INIT([libdaemon], [0.4], [mzqnrzba (at) 0pointer (dot) de]) AC_CONFIG_SRCDIR([src/dfork.c]) AC_CONFIG_HEADERS([config.h]) AM_INIT_AUTOMAKE([foreign -Wall]) @@ -38,8 +38,8 @@ if test "x$GCC" = "xyes" ; then fi if type -p stow > /dev/null && test -d /usr/local/stow ; then - AC_MSG_NOTICE([*** Found /usr/local/stow: installing to /usr/local/stow/${PACKAGE_NAME}-${PACKAGE_VERSION} ***]) - AC_PREFIX_DEFAULT([/usr/local/stow/${PACKAGE_NAME}-${PACKAGE_VERSION}]) + AC_MSG_NOTICE([*** Found /usr/local/stow: default install prefix set to /usr/local/stow/${PACKAGE_NAME}-${PACKAGE_VERSION} ***]) + ac_default_prefix="/usr/local/stow/${PACKAGE_NAME}-${PACKAGE_VERSION}" fi # Checks for header files. @@ -97,5 +97,5 @@ fi AM_CONDITIONAL([USE_LYNX], [test "x$lynx" = xyes]) -AC_CONFIG_FILES([src/Makefile Makefile doc/Makefile doc/README.html doc/doxygen.conf examples/Makefile libdaemon.spec]) +AC_CONFIG_FILES([src/Makefile Makefile doc/Makefile doc/README.html doc/doxygen.conf examples/Makefile libdaemon.spec libdaemon.pc]) AC_OUTPUT diff --git a/doc/README.html.in b/doc/README.html.in index d66fdc4..fc3aea9 100644 --- a/doc/README.html.in +++ b/doc/README.html.in @@ -53,7 +53,7 @@ Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.</p> <h2><a name="overview">Overview</a></h2> -<p><tt>libdaemon</tt> is a lightweight C library which eases the writing of UNIX +<p><tt>libdaemon</tt> is a lightweight C library that eases the writing of UNIX daemons. It consists of the following parts:</p> <ul> diff --git a/examples/testd.c b/examples/testd.c index ec5f690..cf93870 100644 --- a/examples/testd.c +++ b/examples/testd.c @@ -26,6 +26,7 @@ #include <dsignal.h> #include <dlog.h> #include <dpid.h> +#include <dexec.h> int main(int argc, char *argv[]) { pid_t pid; @@ -147,6 +148,7 @@ int main(int argc, char *argv[]) { case SIGHUP: daemon_log(LOG_INFO, "Got a HUP"); + daemon_exec("/", NULL, "/bin/ls", "ls", (char*) NULL); break; } diff --git a/libdaemon.pc.in b/libdaemon.pc.in new file mode 100644 index 0000000..4074627 --- /dev/null +++ b/libdaemon.pc.in @@ -0,0 +1,10 @@ +prefix=@prefix@ +exec_prefix=${prefix} +libdir=${exec_prefix}/lib +includedir=${prefix}/include + +Name: libdaemon +Description: a lightweight C library that eases the writing of UNIX daemons +Version: @PACKAGE_VERSION@ +Libs: -L${libdir} -ldaemon +Cflags: -D_REENTRANT -I${includedir}/libdaemon diff --git a/src/Makefile.am b/src/Makefile.am index c2719ed..cef803e 100644 --- a/src/Makefile.am +++ b/src/Makefile.am @@ -16,7 +16,7 @@ # along with libdaemon; if not, write to the Free Software Foundation, # Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA. -pkginclude_HEADERS = dlog.h dfork.h dsignal.h dnonblock.h dpid.h +pkginclude_HEADERS = dlog.h dfork.h dsignal.h dnonblock.h dpid.h dexec.h daemon.h lib_LTLIBRARIES = libdaemon.la @@ -25,6 +25,8 @@ libdaemon_la_SOURCES = \ dfork.c dfork.h \ dsignal.c dsignal.h \ dnonblock.c dnonblock.h \ - dpid.c dpid.h + dpid.c dpid.h \ + dexec.c dexec.h \ + daemon.h -libdaemon_la_LDFLAGS = -version-info 1:0:1 +libdaemon_la_LDFLAGS = -version-info 2:0:2 diff --git a/src/daemon.h b/src/daemon.h new file mode 100644 index 0000000..405b4f9 --- /dev/null +++ b/src/daemon.h @@ -0,0 +1,36 @@ +#ifndef foodaemonhfoo +#define foodaemonhfoo + +/* $Id: exec.h 4 2003-08-10 19:56:53Z lennart $ */ + +/* + * This file is part of libdaemon. + * + * libdaemon is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * libdaemon is distributed in the hope that it will be useful, but + * WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with libdaemon; if not, write to the Free Software Foundation, + * Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA. + */ + +/** \file + * + * A header file including all other header files part of libdaemon + */ + +#include "dfork.h" +#include "dlog.h" +#include "dpid.h" +#include "dsignal.h" +#include "dexec.h" +#include "dnonblock.h" + +#endif diff --git a/src/dexec.c b/src/dexec.c new file mode 100644 index 0000000..dba0fc1 --- /dev/null +++ b/src/dexec.c @@ -0,0 +1,173 @@ +/* $Id: exec.c 31 2003-11-05 22:04:26Z lennart $ */ + +/* + * This file is part of libdaemon. + * + * libdaemon is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * libdaemon is distributed in the hope that it will be useful, but + * WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with libdaemon; if not, write to the Free Software Foundation, + * Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA. + */ + +#include <sys/types.h> +#include <unistd.h> +#include <string.h> +#include <errno.h> +#include <sys/stat.h> +#include <stdlib.h> +#include <signal.h> +#include <sys/wait.h> +#include <limits.h> +#include <fcntl.h> +#include <stdio.h> +#include <stdarg.h> + +#include "dlog.h" +#include "dsignal.h" + +#include "dexec.h" + +#define MAX_ARGS 100 + +int daemon_exec(const char *dir, int *ret, const char *prog, ...) { + pid_t pid; + int p[2]; + unsigned n = 0; + static char buf[256]; + int sigfd, r; + fd_set fds; + va_list ap; + + if (pipe(p) < 0) { + daemon_log(LOG_ERR, "pipe() failed: %s", strerror(errno)); + return -1; + } + + if ((pid = fork()) < 0) { + daemon_log(LOG_ERR, "fork() failed: %s", strerror(errno)); + return -1; + + } else if (pid == 0) { + char *args[MAX_ARGS]; + int i; + + if (p[1] != 1) + dup2(p[1], 1); + + if (p[1] != 2) + dup2(p[1], 2); + + if (p[0] > 2) + close(p[0]); + + if (p[1] > 2) + close(p[1]); + + close(0); + if (open("/dev/null", O_RDONLY) != 0) { + daemon_log(LOG_ERR, "Unable to open /dev/null as STDIN"); + _exit(EXIT_FAILURE); + } + + umask(0022); /* Set up a sane umask */ + + if (dir && chdir(dir) < 0) { + daemon_log(LOG_WARNING, "Failed to change to directory '%s'", dir); + chdir("/"); + } + + va_start(ap, prog); + for (i = 0; i < MAX_ARGS-1; i++) + if (!(args[i] = va_arg(ap, char*))) + break; + args[i] = NULL; + va_end(ap); + + execv(prog, args); + + daemon_log(LOG_ERR, "execv(%s) failed: %s\n", prog, strerror(errno)); + + _exit(EXIT_FAILURE); + } + + close(p[1]); + + FD_ZERO(&fds); + FD_SET(p[0], &fds); + FD_SET(sigfd = daemon_signal_fd(), &fds); + + n = 0; + + for (;;) { + fd_set qfds = fds; + + if (select(FD_SETSIZE, &qfds, NULL, NULL, NULL) < 0) { + + if (errno == EINTR) + continue; + + daemon_log(LOG_ERR, "select() failed: %s", strerror(errno)); + return -1; + } + + + if (FD_ISSET(p[0], &qfds)) { + char c; + + if (read(p[0], &c, 1) != 1) + break; + + buf[n] = c; + + if (c == '\n' || n >= sizeof(buf) - 2) { + if (c != '\n') n++; + buf[n] = 0; + + if (buf[0]) + daemon_log(LOG_INFO, "client: %s", buf); + + n = 0; + } else + n++; + } + + if (FD_ISSET(sigfd, &qfds)) { + int sig; + + if ((sig = daemon_signal_next()) < 0) { + daemon_log(LOG_ERR, "daemon_signal_next(): %s", strerror(errno)); + break; + } + + if (sig != SIGCHLD) { + daemon_log(LOG_WARNING, "Killing child."); + kill(pid, SIGTERM); + } + } + } + + if (n > 0) { + buf[n] = 0; + daemon_log(LOG_WARNING, "client: %s", buf); + } + + waitpid(pid, &r, 0); + + close(p[0]); + + if (!WIFEXITED(r)) + return -1; + + if (ret) + *ret = WEXITSTATUS(r); + return 0; +} diff --git a/src/dexec.h b/src/dexec.h new file mode 100644 index 0000000..b9e1879 --- /dev/null +++ b/src/dexec.h @@ -0,0 +1,47 @@ +#ifndef foodexechfoo +#define foodexechfoo + +/* $Id: exec.h 4 2003-08-10 19:56:53Z lennart $ */ + +/* + * This file is part of libdaemon. + * + * libdaemon is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * libdaemon is distributed in the hope that it will be useful, but + * WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with libdaemon; if not, write to the Free Software Foundation, + * Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA. + */ + +/** \file + * + * Contains a robust API for running sub processes with STDOUT and + * STDERR redirected to syslog + */ + +/** If this variable is defined to 1 iff daemon_pid_file_kill_wait() is supported.*/ +#define DAEMON_EXEC_AVAILABLE 1 + +/** Run the specified executable with the specified arguments in the + * specified directory and return the return value of the program in + * the specified pointer. The calling process is blocked until the + * child finishes, alls child output (either STDOUT or STDIN) is + * written to syslog. + * + * @param dir Working directory for the process. + * @param ret A pointer to an integer to write the return value of the program to. + * @param prog The path to the executable + * @param ... The arguments to be passed to the program, followed by a (char *) NULL + * @return Nonzero on failure, zero on success + */ +int daemon_exec(const char *dir, int *ret, const char *prog, ...); + +#endif @@ -21,13 +21,11 @@ #include <syslog.h> - /** \file * * Contains a robust API for logging messages */ - /** Specifies where to send the log messages to */ enum daemon_log_flags { |