aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorLexxy Fox <lexxyfox@gmail.com>2023-09-25 17:33:22 -0500
committerWilliam Hubbs <w.d.hubbs@gmail.com>2023-10-03 16:43:39 -0500
commit9934e9f96ea91995dfab382bf05b47d43c1ac4f9 (patch)
treea6f3bc377be9506ab8126f91827b9cb243c3f918
parentf1e5510ccf06a2e0ea61a2de2e764ddc6a7b1d5d (diff)
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.
-rw-r--r--man/supervise-daemon.817
-rw-r--r--sh/supervise-daemon.sh2
-rw-r--r--src/supervise-daemon/meson.build2
-rw-r--r--src/supervise-daemon/supervise-daemon.c33
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
}