diff options
author | Lennart Poettering <lennart@poettering.net> | 2007-06-11 15:16:09 +0000 |
---|---|---|
committer | Lennart Poettering <lennart@poettering.net> | 2007-06-11 15:16:09 +0000 |
commit | b45cd330549c234d0c061602d6239b083ddb9978 (patch) | |
tree | 019ed7655be9ce4a62f718f1d55490e00277b569 | |
parent | e64d682f16b36ca16c6e8b2dada36520243a3d1c (diff) |
add daemon_logv()
git-svn-id: file:///home/lennart/svn/public/libdaemon/trunk@116 153bfa13-eec0-0310-be40-b0cb6a0e1b4b
-rw-r--r-- | libdaemon/dexec.c | 17 | ||||
-rw-r--r-- | libdaemon/dexec.h | 8 | ||||
-rw-r--r-- | libdaemon/dfork.c | 142 | ||||
-rw-r--r-- | libdaemon/dfork.h | 9 | ||||
-rw-r--r-- | libdaemon/dlog.c | 12 | ||||
-rw-r--r-- | libdaemon/dlog.h | 7 |
6 files changed, 173 insertions, 22 deletions
diff --git a/libdaemon/dexec.c b/libdaemon/dexec.c index 3726565..10c757c 100644 --- a/libdaemon/dexec.c +++ b/libdaemon/dexec.c @@ -44,14 +44,13 @@ #define MAX_ARGS 100 -int daemon_exec(const char *dir, int *ret, const char *prog, ...) { +int daemon_execv(const char *dir, int *ret, const char *prog, va_list ap) { pid_t pid; int p[2]; unsigned n = 0; static char buf[256]; int sigfd, r; fd_set fds; - va_list ap; assert(daemon_signal_fd() >= 0); @@ -93,12 +92,10 @@ int daemon_exec(const char *dir, int *ret, const char *prog, ...) { 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); @@ -128,7 +125,6 @@ int daemon_exec(const char *dir, int *ret, const char *prog, ...) { return -1; } - if (FD_ISSET(p[0], &qfds)) { char c; @@ -190,3 +186,14 @@ int daemon_exec(const char *dir, int *ret, const char *prog, ...) { } } } + +int daemon_exec(const char *dir, int *ret, const char *prog, ...) { + va_list ap; + int r; + + va_start(ap, prog); + r = daemon_execv(dir, ret, prog, ap); + va_end(ap); + + return r; +} diff --git a/libdaemon/dexec.h b/libdaemon/dexec.h index 03fea2b..4b74f5e 100644 --- a/libdaemon/dexec.h +++ b/libdaemon/dexec.h @@ -22,6 +22,8 @@ * 02110-1301 USA */ +#include <stdarg.h> + #ifdef __cplusplus extern "C" { #endif @@ -50,6 +52,12 @@ extern "C" { */ int daemon_exec(const char *dir, int *ret, const char *prog, ...); +/** This variable is defined to 1 iff daemon_execv() is supported.*/ +#define DAEMON_EXECV_AVAILABLE 1 + +/** The same as daemon_exec, but without variadic arguments */ +int daemon_execv(const char *dir, int *ret, const char *prog, va_list ap); + #ifdef __cplusplus } #endif diff --git a/libdaemon/dfork.c b/libdaemon/dfork.c index 86acaee..ad7a77f 100644 --- a/libdaemon/dfork.c +++ b/libdaemon/dfork.c @@ -36,6 +36,8 @@ #include <sys/ioctl.h> #include <signal.h> #include <sys/time.h> +#include <sys/resource.h> +#include <dirent.h> #include "dfork.h" #include "dnonblock.h" @@ -199,30 +201,29 @@ pid_t daemon_fork(void) { goto fail; } else if (pid == 0) { - int tty_fd; + int tty_fd; /* Second child */ if (daemon_log_use & DAEMON_LOG_AUTO) daemon_log_use = DAEMON_LOG_SYSLOG; - signal(SIGTTOU, SIG_IGN); - signal(SIGTTIN, SIG_IGN); - signal(SIGTSTP, SIG_IGN); - - setsid(); - setpgid(0,0); + signal(SIGTTOU, SIG_IGN); + signal(SIGTTIN, SIG_IGN); + signal(SIGTSTP, SIG_IGN); + + setsid(); + setpgid(0,0); #ifdef TIOCNOTTY - if ((tty_fd = open("/dev/tty", O_RDWR)) >= 0) { - ioctl(tty_fd, TIOCNOTTY, NULL); - close(tty_fd); - } + if ((tty_fd = open("/dev/tty", O_RDWR)) >= 0) { + ioctl(tty_fd, TIOCNOTTY, NULL); + close(tty_fd); + } #endif dpid = getpid(); if (atomic_write(pipe_fds[1], &dpid, sizeof(dpid)) != sizeof(dpid)) goto fail; close(pipe_fds[1]); - return 0; } else { @@ -279,6 +280,9 @@ void daemon_retval_done(void) { int daemon_retval_send(int i) { ssize_t r; + if (_daemon_retval_pipe[1] < 0) + return -1; + r = atomic_write(_daemon_retval_pipe[1], &i, sizeof(i)); daemon_retval_done(); @@ -339,3 +343,117 @@ int daemon_retval_wait(int timeout) { return i; } +int daemon_close_all(int except_fd, ...) { + va_list original_ap, ap; + int n, i, r; + int *p; + + va_start(original_ap, except_fd); + va_copy(ap, original_ap); + + for (n = 0; va_arg(ap, int) >= 0; n++) + ; + + va_end(ap); + + if (!(p = malloc(sizeof(int) * (n+1)))) { + va_end(original_ap); + return -1; + } + + i = 0; + while ((p[i++] = va_arg(original_ap, int)) >= 0) + ; + + p[i] = -1; + + r = daemon_close_allv(p); + free(p); + + return r; +} + +/** Same as daemon_close_all but takes an array of fds, terminated by -1 */ +int daemon_close_allv(const int except_fds[]) { + struct rlimit rl; + int fd; + +#ifdef xxx__linux__ + + DIR *d; + + if ((d = opendir("/proc/self/fd"))) { + + struct dirent *de; + + while ((de = readdir(d))) { + long l; + char *e = NULL; + int i, fd; + + if (de->d_name[0] == '.') + continue; + + errno = 0; + l = strtol(de->d_name, &e, 10); + if (errno != 0 || !e || *e) { + closedir(d); + errno = EINVAL; + return -1; + } + + fd = (int) l; + + if ((long) fd != l) { + closedir(d); + errno = EINVAL; + return -1; + } + + if (fd <= 3) + continue; + + if (fd == dirfd(d)) + continue; + + if (fd == _daemon_retval_pipe[1]) + continue; + + for (i = 0; except_fds[i] >= 0; i++) + if (except_fds[i] == fd) + continue; + + if (close(fd) < 0) { + closedir(d); + return -1; + } + } + + closedir(d); + return 0; + } + +#endif + + if (getrlimit(RLIMIT_NOFILE, &rl) < 0) + return -1; + + for (fd = 0; fd < (int) rl.rlim_max; fd++) { + int i; + + if (fd <= 3) + continue; + + if (fd == _daemon_retval_pipe[1]) + continue; + + for (i = 0; except_fds[i] >= 0; i++) + if (except_fds[i] == fd) + continue; + + if (close(fd) < 0 && errno != EBADF) + return -1; + } + + return 0; +} diff --git a/libdaemon/dfork.h b/libdaemon/dfork.h index b7effa1..fcb32c3 100644 --- a/libdaemon/dfork.h +++ b/libdaemon/dfork.h @@ -27,7 +27,7 @@ #ifdef __cplusplus extern "C" { #endif - + /** \mainpage libdaemon * * libdaemon @@ -100,6 +100,13 @@ int daemon_retval_wait(int timeout); */ int daemon_retval_send(int s); +/** Close all file descriptors except those passed. List needs to be + * terminated by -1. FDs 0, 1, 2 will be kept open anyway. */ +int daemon_close_all(int except_fd, ...); + +/** Same as daemon_close_all but takes an array of fds, terminated by -1 */ +int daemon_close_allv(const int except_fds[]); + #ifdef __cplusplus } #endif diff --git a/libdaemon/dlog.c b/libdaemon/dlog.c index a50123c..3748cf8 100644 --- a/libdaemon/dlog.c +++ b/libdaemon/dlog.c @@ -32,10 +32,8 @@ enum daemon_log_flags daemon_log_use = DAEMON_LOG_AUTO|DAEMON_LOG_STDERR; const char* daemon_log_ident = NULL; -void daemon_log(int prio, const char* template, ...) { - va_list arglist; - va_start(arglist, template); - +void daemon_logv(int prio, const char* template, va_list arglist) { + if (daemon_log_use & DAEMON_LOG_SYSLOG) { openlog(daemon_log_ident ? daemon_log_ident : "UNKNOWN", LOG_PID, LOG_DAEMON); vsyslog(prio | LOG_DAEMON, template, arglist); @@ -50,8 +48,14 @@ void daemon_log(int prio, const char* template, ...) { vfprintf(stdout, template, arglist); fprintf(stdout, "\n"); } + +} +void daemon_log(int prio, const char* template, ...) { + va_list arglist; + va_start(arglist, template); + daemon_logv(prio, template, arglist); va_end(arglist); } diff --git a/libdaemon/dlog.h b/libdaemon/dlog.h index f0d5d41..ff66060 100644 --- a/libdaemon/dlog.h +++ b/libdaemon/dlog.h @@ -23,6 +23,7 @@ */ #include <syslog.h> +#include <stdarg.h> #ifdef __cplusplus extern "C" { @@ -64,6 +65,12 @@ extern const char* daemon_log_ident; */ void daemon_log(int prio, const char* t, ...) DAEMON_GCC_PRINTF_ATTR(2,3); +/** This variable is defined to 1 iff daemon_logv() is supported.*/ +#define DAEMON_LOGV_AVAILABLE 1 + +/** Same as daemon_logv, but without variadic arguments */ +void daemon_logv(int prio, const char* t, va_list ap); + /** Return a sensible syslog identification for daemon_log_ident * generated from argv[0]. This will return a pointer to the file name * of argv[0], i.e. strrchr(argv[0], '\')+1 |