From 9934e9f96ea91995dfab382bf05b47d43c1ac4f9 Mon Sep 17 00:00:00 2001 From: Lexxy Fox Date: Mon, 25 Sep 2023 17:33:22 -0500 Subject: supervise-daemon: implement output_logger and error_logger. Allows redirecting process stdin and stdout to another process, just like is already possible with start-stop-daemon. Also added --stdout-logger and --stderr-logger to the man page. --- man/supervise-daemon.8 | 17 +++++++++++++++++ sh/supervise-daemon.sh | 2 ++ src/supervise-daemon/meson.build | 2 +- src/supervise-daemon/supervise-daemon.c | 33 +++++++++++++++++++++++++++++++-- 4 files changed, 51 insertions(+), 3 deletions(-) diff --git a/man/supervise-daemon.8 b/man/supervise-daemon.8 index cd76beb2..c3a6e9f7 100644 --- a/man/supervise-daemon.8 +++ b/man/supervise-daemon.8 @@ -158,6 +158,23 @@ The logfile can also be a named pipe. The same thing as .Fl 1 , -stdout but with the standard error output. +.It Fl -stdout-logger Ar cmd +Run cmd as a child process redirecting the standard output to the +standard input of cmd when started with +.Fl background . +Cmd must be an absolute pathname, but relative to the path optionally given with +.Fl r , -chroot . +This process must be prepared to accept input on stdin and be able to +log it or send it to another location. +.It Fl -stderr-logger Ar cmd +Run cmd as a child process and +Redirect the standard error of the process to the standard input of cmd +when started with +.Fl background . +Cmd must be an absolute pathname, but relative to the path optionally given with +.Fl r , -chroot . +This process must be prepared to accept input on stdin and be able to +log it or send it to another location. .It Fl -capabilities Ar cap-list Start the daemon with the listed inheritable, ambient and bounding capabilities. The format is the same as in cap_iab(3). diff --git a/sh/supervise-daemon.sh b/sh/supervise-daemon.sh index 8eb98a17..4ff64a2e 100644 --- a/sh/supervise-daemon.sh +++ b/sh/supervise-daemon.sh @@ -30,6 +30,8 @@ supervise_start() ${chroot:+--chroot} $chroot \ ${output_log+--stdout} ${output_log} \ ${error_log+--stderr} $error_log \ + ${output_logger:+--stdout-logger \"$output_logger\"} \ + ${error_logger:+--stderr-logger \"$error_logger\"} \ ${pidfile:+--pidfile} $pidfile \ ${respawn_delay:+--respawn-delay} $respawn_delay \ ${respawn_max:+--respawn-max} $respawn_max \ diff --git a/src/supervise-daemon/meson.build b/src/supervise-daemon/meson.build index 808114f0..f7d70c4c 100644 --- a/src/supervise-daemon/meson.build +++ b/src/supervise-daemon/meson.build @@ -1,5 +1,5 @@ executable('supervise-daemon', - ['supervise-daemon.c', misc_c, plugin_c, schedules_c, usage_c, version_h], + ['supervise-daemon.c', '../start-stop-daemon/pipes.c', misc_c, plugin_c, schedules_c, usage_c, version_h], c_args : [cc_branding_flags, cc_pam_flags, cc_cap_flags, cc_selinux_flags], link_with: [libeinfo, librc], dependencies: [dl_dep, pam_dep, cap_dep, util_dep, selinux_dep], diff --git a/src/supervise-daemon/supervise-daemon.c b/src/supervise-daemon/supervise-daemon.c index f0f298d2..4a0c1c49 100644 --- a/src/supervise-daemon/supervise-daemon.c +++ b/src/supervise-daemon/supervise-daemon.c @@ -62,6 +62,7 @@ static struct pam_conv conv = { NULL, NULL}; #include "queue.h" #include "rc.h" #include "misc.h" +#include "../start-stop-daemon/pipes.h" #include "plugin.h" #include "schedules.h" #include "_usage.h" @@ -79,6 +80,8 @@ enum { LONGOPT_OOM_SCORE_ADJ, LONGOPT_NO_NEW_PRIVS, LONGOPT_SECBITS, + LONGOPT_STDERR_LOGGER, + LONGOPT_STDOUT_LOGGER, }; const char *applet = NULL; @@ -110,6 +113,8 @@ const struct option longopts[] = { { "user", 1, NULL, 'u'}, { "stdout", 1, NULL, '1'}, { "stderr", 1, NULL, '2'}, + { "stdout-logger",1, NULL, LONGOPT_STDOUT_LOGGER}, + { "stderr-logger",1, NULL, LONGOPT_STDERR_LOGGER}, { "reexec", 0, NULL, '3'}, longopts_COMMON }; @@ -138,6 +143,8 @@ const char * const longopts_help[] = { "Change the process user", "Redirect stdout to file", "Redirect stderr to file", + "Redirect stdout to process", + "Redirect stderr to process", "reexec (used internally)", longopts_help_COMMON }; @@ -160,6 +167,8 @@ static int stdout_fd; static int stderr_fd; static char *redirect_stderr = NULL; static char *redirect_stdout = NULL; +static char *stderr_process = NULL; +static char *stdout_process = NULL; #ifdef TIOCNOTTY static int tty_fd = -1; #endif @@ -549,6 +558,12 @@ RC_NORETURN static void child_process(char *exec, char **argv) eerrorx("%s: unable to open the logfile" " for stdout `%s': %s", applet, redirect_stdout, strerror(errno)); + } else if (stdout_process) { + stdout_fd = rc_pipe_command(stdout_process); + if (stdout_fd == -1) + eerrorx("%s: unable to open the logging process" + " for stdout `%s': %s", + applet, stdout_process, strerror(errno)); } if (redirect_stderr) { if ((stderr_fd = open(redirect_stderr, @@ -557,12 +572,18 @@ RC_NORETURN static void child_process(char *exec, char **argv) eerrorx("%s: unable to open the logfile" " for stderr `%s': %s", applet, redirect_stderr, strerror(errno)); + } else if (stderr_process) { + stderr_fd = rc_pipe_command(stderr_process); + if (stderr_fd == -1) + eerrorx("%s: unable to open the logging process" + " for stderr `%s': %s", + applet, stderr_process, strerror(errno)); } dup2(stdin_fd, STDIN_FILENO); - if (redirect_stdout || rc_yesno(getenv("EINFO_QUIET"))) + if (redirect_stdout || stdout_process || rc_yesno(getenv("EINFO_QUIET"))) dup2(stdout_fd, STDOUT_FILENO); - if (redirect_stderr || rc_yesno(getenv("EINFO_QUIET"))) + if (redirect_stderr || stderr_process || rc_yesno(getenv("EINFO_QUIET"))) dup2(stderr_fd, STDERR_FILENO); cloexec_fds_from(3); @@ -1039,6 +1060,14 @@ int main(int argc, char **argv) reexec = true; break; + case LONGOPT_STDOUT_LOGGER: /* --stdout-logger "command to run for stdout logging" */ + stdout_process = optarg; + break; + + case LONGOPT_STDERR_LOGGER: /* --stderr-logger "command to run for stderr logging" */ + stderr_process = optarg; + break; + case_RC_COMMON_GETOPT } -- cgit v1.2.3