diff --git a/man/openrc-run.8 b/man/openrc-run.8 index c74767283..e02559430 100644 --- a/man/openrc-run.8 +++ b/man/openrc-run.8 @@ -158,18 +158,23 @@ use this to change the user id, and optionally group id, before or .Xr supervise-daemon 8 launches the daemon. -.It Ar output_log -This is the path to a file or named pipe where the standard output from -the service will be redirected. If you are starting this service with +.It Ar input_file +This is the path to a file or named pipe to which the standard input of the +service will be redirected to. If you are starting this service with .Xr start-stop-daemon 8 , , you must set .Pa command_background to true. Keep in mind that this path will be inside the chroot if the .Pa chroot -variable is set. +variable is set. Contrary to output and error redirection, input redirection +assumes that the file exists already. +.It Ar output_log +The same thing as +.Pa input_file +but for the standard output. .It Ar error_log The same thing as -.Pa output_log +.Pa input_file but for the standard error output. .It Ar output_logger This is a process which will be used to log the standard output from the diff --git a/man/start-stop-daemon.8 b/man/start-stop-daemon.8 index b6d62ff0d..32103a37e 100644 --- a/man/start-stop-daemon.8 +++ b/man/start-stop-daemon.8 @@ -143,6 +143,13 @@ on POSIX systems and, additionally, batch and idle on Linux. If is an integer, it is passed directly to pthread_setschedparam(3). .It Fl -scheduler-priority Ar priority Sets the priority parameter of the scheduling policy of the daemon. See sched(7) for details. +.It Fl 0 , -stdin Ar file +Redirect the standard input of the process to file when started with +.Fl background . +The file Must be an absolute pathname, but relative to the path +optionally given with +.Fl r , -chroot . +The file can also be a named pipe. The file must exist, otherwise an error is emitted. .It Fl 1 , -stdout Ar logfile Redirect the standard output of the process to logfile when started with .Fl background . diff --git a/man/supervise-daemon.8 b/man/supervise-daemon.8 index 5fa226e91..7abb034b4 100644 --- a/man/supervise-daemon.8 +++ b/man/supervise-daemon.8 @@ -50,6 +50,8 @@ servicename .Ar chrootpath .Fl u , -user .Ar user +.Fl 0 , -stdin +.Ar file .Fl 1 , -stdout .Ar logfile .Fl 2 , -stderr @@ -154,11 +156,20 @@ process to communicate with is determined by the name of the service taken from the RC_SVCNAME environment variable. .It Fl u , -user Ar user Start the daemon as the specified user. -.It Fl 1 , -stdout Ar logfile -Redirect the standard output of the process to logfile. +.It Fl 0 , -stdin Ar file +Redirect the standard input of the process to file. Must be an absolute pathname, but relative to the path optionally given with .Fl r , -chroot . -The logfile can also be a named pipe. +The file can also be a named pipe. Input redirection assumes that the file +exists already while output redirection via +.Fl 1 , -stdout +or +.Fl 1 , -stderr +creates it, if it doesn't. +.It Fl 1 , -stdout Ar logfile +The same thing as +.Fl 0 , -stdin +but with the standard output. .It Fl 2 , -stderr Ar logfile The same thing as .Fl 1 , -stdout diff --git a/sh/start-stop-daemon.sh b/sh/start-stop-daemon.sh index 1f9dfa5a7..ba90bb47f 100644 --- a/sh/start-stop-daemon.sh +++ b/sh/start-stop-daemon.sh @@ -45,6 +45,7 @@ ssd_start() --exec $command \ ${chroot:+--chroot} $chroot \ ${directory:+--chdir} $directory \ + ${input_file+--stdin} $input_file \ ${output_log+--stdout} $output_log \ ${error_log+--stderr} $error_log \ ${output_logger:+--stdout-logger \"$output_logger\"} \ diff --git a/sh/supervise-daemon.sh b/sh/supervise-daemon.sh index 8cdde18b5..7a6b46746 100644 --- a/sh/supervise-daemon.sh +++ b/sh/supervise-daemon.sh @@ -28,6 +28,7 @@ supervise_start() ${retry:+--retry} $retry \ ${directory:+--chdir} $directory \ ${chroot:+--chroot} $chroot \ + ${input_file+--stdin} $input_file \ ${output_log+--stdout} ${output_log} \ ${error_log+--stderr} $error_log \ ${output_logger:+--stdout-logger \"$output_logger\"} \ diff --git a/src/start-stop-daemon/start-stop-daemon.c b/src/start-stop-daemon/start-stop-daemon.c index 5c21960f4..0af29c42d 100644 --- a/src/start-stop-daemon/start-stop-daemon.c +++ b/src/start-stop-daemon/start-stop-daemon.c @@ -94,7 +94,7 @@ enum { const char *applet = NULL; const char *extraopts = NULL; -const char getoptstring[] = "I:KN:PR:Sa:bc:d:e:g:ik:mn:op:s:tu:r:w:x:1:2:3:4:" \ +const char getoptstring[] = "I:KN:PR:Sa:bc:d:e:g:ik:mn:op:s:tu:r:w:x:0:1:2:3:4:" \ getoptstring_COMMON; const struct option longopts[] = { { "capabilities", 1, NULL, LONGOPT_CAPABILITIES}, @@ -124,6 +124,7 @@ const struct option longopts[] = { { "chroot", 1, NULL, 'r'}, { "wait", 1, NULL, 'w'}, { "exec", 1, NULL, 'x'}, + { "stdin", 1, NULL, '0'}, { "stdout", 1, NULL, '1'}, { "stderr", 1, NULL, '2'}, { "stdout-logger",1, NULL, '3'}, @@ -162,6 +163,7 @@ const char * const longopts_help[] = { "Chroot to this directory", "Milliseconds to wait for daemon start", "Binary to start/stop", + "Redirect stdin to file", "Redirect stdout to file", "Redirect stderr to file", "Redirect stdout to process", @@ -318,6 +320,7 @@ int main(int argc, char **argv) gid_t gid = 0; char *home = NULL; int tid = 0; + char *redirect_stdin = NULL; char *redirect_stderr = NULL; char *redirect_stdout = NULL; char *stderr_process = NULL; @@ -601,6 +604,10 @@ int main(int argc, char **argv) exec = optarg; break; + case '0': /* --stdin /path/to/stdin.input-file */ + redirect_stdin = optarg; + break; + case '1': /* --stdout /path/to/stdout.lgfile */ redirect_stdout = optarg; break; @@ -1071,6 +1078,13 @@ int main(int argc, char **argv) stdin_fd = devnull_fd; stdout_fd = devnull_fd; stderr_fd = devnull_fd; + if (redirect_stdin) { + if ((stdin_fd = open(redirect_stdin, + O_RDONLY)) == -1) + eerrorx("%s: unable to open the input file" + " for stdin `%s': %s", + applet, redirect_stdin, strerror(errno)); + } if (redirect_stdout) { if ((stdout_fd = open(redirect_stdout, O_WRONLY | O_CREAT | O_APPEND, diff --git a/src/supervise-daemon/supervise-daemon.c b/src/supervise-daemon/supervise-daemon.c index 210d572db..57f8d2b8d 100644 --- a/src/supervise-daemon/supervise-daemon.c +++ b/src/supervise-daemon/supervise-daemon.c @@ -87,7 +87,7 @@ enum { const char *applet = NULL; const char *extraopts = NULL; -const char getoptstring[] = "A:a:D:d:e:g:H:I:Kk:m:N:p:R:r:s:Su:1:2:3" \ +const char getoptstring[] = "A:a:D:d:e:g:H:I:Kk:m:N:p:R:r:s:Su:0:1:2:3" \ getoptstring_COMMON; const struct option longopts[] = { { "healthcheck-timer", 1, NULL, 'a'}, @@ -112,6 +112,7 @@ const struct option longopts[] = { { "signal", 1, NULL, 's'}, { "start", 0, NULL, 'S'}, { "user", 1, NULL, 'u'}, + { "stdin", 1, NULL, '0'}, { "stdout", 1, NULL, '1'}, { "stderr", 1, NULL, '2'}, { "stdout-logger",1, NULL, LONGOPT_STDOUT_LOGGER}, @@ -143,6 +144,7 @@ const char * const longopts_help[] = { "Send a signal to the daemon", "Start daemon", "Change the process user", + "Redirect stdin to file", "Redirect stdout to file", "Redirect stderr to file", "Redirect stdout to process", @@ -168,6 +170,7 @@ static int stdin_fd; static int stdout_fd; static int stderr_fd; static struct ready ready; +static char *redirect_stdin = NULL; static char *redirect_stderr = NULL; static char *redirect_stdout = NULL; static char *stderr_process = NULL; @@ -554,6 +557,13 @@ RC_NORETURN static void child_process(char *exec, char **argv) stdin_fd = devnull_fd; stdout_fd = devnull_fd; stderr_fd = devnull_fd; + if (redirect_stdin) { + if ((stdin_fd = open(redirect_stdin, + O_RDONLY)) == -1) + eerrorx("%s: unable to open the input file" + " for stdin `%s': %s", + applet, redirect_stdin, strerror(errno)); + } if (redirect_stdout) { if ((stdout_fd = open(redirect_stdout, O_WRONLY | O_CREAT | O_APPEND, @@ -1057,6 +1067,10 @@ int main(int argc, char **argv) } break; + case '0': /* --stdin /path/to/stdin.input-file */ + redirect_stdin = optarg; + break; + case '1': /* --stdout /path/to/stdout.lgfile */ redirect_stdout = optarg; break;