Summary: | Attached patch for start-stop-daemon to redirect in/out when forking to background | ||
---|---|---|---|
Product: | Gentoo Linux | Reporter: | Iain Buchanan <iaindb> |
Component: | [OLD] baselayout | Assignee: | Gentoo's Team for Core System packages <base-system> |
Status: | RESOLVED FIXED | ||
Severity: | enhancement | ||
Priority: | Normal | ||
Version: | unspecified | ||
Hardware: | All | ||
OS: | Linux | ||
Whiteboard: | |||
Package list: | Runtime testing required: | --- | |
Attachments: | patch to start-stop-daemon.c |
Description
Iain Buchanan
2006-06-28 16:48:33 UTC
I still can't add patches for some reason, so here's the patch, bounded by three -'s: --- --- baselayout-1.12.1/src/start-stop-daemon.c 2006-06-05 23:50:55.000000000 +0930 +++ baselayout-1.12.1-mod/src/start-stop-daemon.c 2006-06-29 09:19:08.000000000 +0930 @@ -27,6 +27,10 @@ * new root if -r option is used!). * Daemon binary will be stat()ed correctly if it's going to be chrooted * with -r|--chroot. + * + * Changes by Iain Buchanan <iaindb@netspace.net.au>: added to public domain. + * Added --stdin --stdout and --stderr for redirecting input and output (eg to + * vt's) when run with --background. * */ @@ -137,6 +141,9 @@ static const char *schedule_str = NULL; static const char *progname = ""; static int nicelevel = 0; +static const char *stdindev = NULL; +static const char *stdoutdev = NULL; +static const char *stderrdev = NULL; static struct stat exec_stat; #if defined(OSHURD) @@ -308,6 +315,9 @@ " -o|--oknodo exit status 0 (not 1) if nothing done\n" " -q|--quiet be more quiet\n" " -v|--verbose be more verbose\n" +" -0|--stdin <device> redirect stdin from <device> when run with --background\n" +" -1|--stdout <device> redirect stdout to <device> when run with --background\n" +" -2|--stderr <device> redirect stderr to <device> when run with --background\n" "Retry <schedule> is <item>|/<item>/... where <item> is one of\n" " -<signal-num>|[-]<signal-name> send that signal\n" " <timeout> wait that many seconds\n" @@ -490,6 +500,9 @@ { "make-pidfile", 0, NULL, 'm'}, { "retry", 1, NULL, 'R'}, { "chdir", 1, NULL, 'd'}, + { "stdin", 1, NULL, '0'}, + { "stdout", 1, NULL, '1'}, + { "stderr", 1, NULL, '2'}, { NULL, 0, NULL, 0} }; int c; @@ -573,6 +586,16 @@ case 'd': /* --chdir /new/dir */ changedir = optarg; break; + case '0': /* --stdin new_stdin */ + stdindev = optarg; + break; + case '1': /* --stdout new_stdout */ + stdoutdev = optarg; + break; + case '2': /* --stderr new_stderr */ + stderrdev = optarg; + break; + default: badusage(NULL); /* message printed by getopt */ } @@ -606,6 +629,9 @@ if (background && !start) badusage("--background is only relevant with --start"); + if ((stdindev != NULL || stdoutdev != NULL || stderrdev != NULL) && !background) + badusage("--stdin --stdout and --stderr only useful with --background!"); + } #if defined(OSLinux) @@ -1255,6 +1281,9 @@ main(int argc, char **argv) { int devnull_fd = -1; + int stdin_fd = -1; + int stdout_fd = -1; + int stderr_fd = -1; #ifdef HAVE_TIOCNOTTY int tty_fd = -1; #endif @@ -1363,6 +1392,12 @@ tty_fd=open("/dev/tty", O_RDWR); #endif devnull_fd=open("/dev/null", O_RDWR); + if (stdindev != NULL) + stdin_fd=open(stdindev, O_RDWR); + if (stdoutdev != NULL) + stdout_fd=open(stdoutdev, O_RDWR); + if (stderrdev != NULL) + stderr_fd=open(stderrdev, O_RDWR); } if (nicelevel) { errno=0; @@ -1407,9 +1442,22 @@ close(tty_fd); #endif umask(022); /* set a default for dumb programs */ - dup2(devnull_fd,0); /* stdin */ - dup2(devnull_fd,1); /* stdout */ - dup2(devnull_fd,2); /* stderr */ + + if (stdin_fd == -1) + dup2(devnull_fd,0); /* stdin */ + else + dup2(stdin_fd,0); /* stdin */ + + if (stdout_fd == -1) + dup2(devnull_fd,1); /* stdout */ + else + dup2(stdout_fd,1); /* stdout */ + + if (stderr_fd == -1) + dup2(devnull_fd,2); /* stderr */ + else + dup2(stderr_fd,2); /* stderr */ + #if defined(OShpux) /* now close all extra fds */ for (i=sysconf(_SC_OPEN_MAX)-1; i>=3; --i) close(i); --- prob be a good idea to try and get this integrated with the Debian guys as well Do you want me to do something there? I don't know the debian avenue to follow... On further testing, this one works better. Note the O_APPEND when opening, because if multiple processes open the same file (eg. for stderr) then output gets a bit confusing :) --- baselayout-1.12.1/src/start-stop-daemon.c 2006-06-05 23:50:55.000000000 +0930 +++ baselayout-1.12.1-mod/src/start-stop-daemon.c 2006-06-29 15:04:49.000000000 +0930 @@ -27,6 +27,10 @@ * new root if -r option is used!). * Daemon binary will be stat()ed correctly if it's going to be chrooted * with -r|--chroot. + * + * Changes by Iain Buchanan <iaindb@netspace.net.au>: added to public domain. + * Added --stdin --stdout and --stderr for redirecting input and output (eg to + * vt's) when run with --background. * */ @@ -137,6 +141,9 @@ static const char *schedule_str = NULL; static const char *progname = ""; static int nicelevel = 0; +static const char *stdindev = NULL; +static const char *stdoutdev = NULL; +static const char *stderrdev = NULL; static struct stat exec_stat; #if defined(OSHURD) @@ -308,6 +315,9 @@ " -o|--oknodo exit status 0 (not 1) if nothing done\n" " -q|--quiet be more quiet\n" " -v|--verbose be more verbose\n" +" -0|--stdin <device> redirect stdin from <device> when run with --background\n" +" -1|--stdout <device> redirect stdout to <device> when run with --background\n" +" -2|--stderr <device> redirect stderr to <device> when run with --background\n" "Retry <schedule> is <item>|/<item>/... where <item> is one of\n" " -<signal-num>|[-]<signal-name> send that signal\n" " <timeout> wait that many seconds\n" @@ -490,6 +500,9 @@ { "make-pidfile", 0, NULL, 'm'}, { "retry", 1, NULL, 'R'}, { "chdir", 1, NULL, 'd'}, + { "stdin", 1, NULL, '0'}, + { "stdout", 1, NULL, '1'}, + { "stderr", 1, NULL, '2'}, { NULL, 0, NULL, 0} }; int c; @@ -573,6 +586,16 @@ case 'd': /* --chdir /new/dir */ changedir = optarg; break; + case '0': /* --stdin new_stdin */ + stdindev = optarg; + break; + case '1': /* --stdout new_stdout */ + stdoutdev = optarg; + break; + case '2': /* --stderr new_stderr */ + stderrdev = optarg; + break; + default: badusage(NULL); /* message printed by getopt */ } @@ -606,6 +629,9 @@ if (background && !start) badusage("--background is only relevant with --start"); + if ((stdindev != NULL || stdoutdev != NULL || stderrdev != NULL) && !background) + badusage("--stdin --stdout and --stderr only useful with --background!"); + } #if defined(OSLinux) @@ -1255,6 +1281,9 @@ main(int argc, char **argv) { int devnull_fd = -1; + int stdin_fd = -1; + int stdout_fd = -1; + int stderr_fd = -1; #ifdef HAVE_TIOCNOTTY int tty_fd = -1; #endif @@ -1363,6 +1392,12 @@ tty_fd=open("/dev/tty", O_RDWR); #endif devnull_fd=open("/dev/null", O_RDWR); + if (stdindev != NULL) + stdin_fd=open(stdindev, O_RDWR | O_APPEND); + if (stdoutdev != NULL) + stdout_fd=open(stdoutdev, O_RDWR | O_APPEND); + if (stderrdev != NULL) + stderr_fd=open(stderrdev, O_RDWR | O_APPEND); } if (nicelevel) { errno=0; @@ -1407,9 +1442,22 @@ close(tty_fd); #endif umask(022); /* set a default for dumb programs */ - dup2(devnull_fd,0); /* stdin */ - dup2(devnull_fd,1); /* stdout */ - dup2(devnull_fd,2); /* stderr */ + + if (stdin_fd == -1) + dup2(devnull_fd,0); /* stdin */ + else + dup2(stdin_fd,0); /* stdin */ + + if (stdout_fd == -1) + dup2(devnull_fd,1); /* stdout */ + else + dup2(stdout_fd,1); /* stdout */ + + if (stderr_fd == -1) + dup2(devnull_fd,2); /* stderr */ + else + dup2(stderr_fd,2); /* stderr */ + #if defined(OShpux) /* now close all extra fds */ for (i=sysconf(_SC_OPEN_MAX)-1; i>=3; --i) close(i); This patch would be exceedingly helpful -- we use a shell-script wrapper around our daemons to collect stderr, and unfortunately that doesn't work with the latest stable baselayout. If we had this feature in s-s-d, we could dispense with the wrapper. Is there anything blocking this? Fixed in baselayout-1.13.0_alpha9, although I merged your patch with mods from someone elses. coolness :) I've actually got another version, which doesn't require --background before using --stdin, --stdout, and --stderr, but I'm having trouble with attachments again, so I haven't posted it yet... Shall I reopen the bug when I post it? thanks heaps! Created attachment 103905 [details, diff]
patch to start-stop-daemon.c
This version is against start-stop-daemon.c from baselayout-1.12.6
The difference here is that --background isn't required. I also spat out some text saying that you may not be able to interact with the process (not that you usually expect to with a daemon). Can remove that if you want.
thanks.
(In reply to comment #8) > This version is against start-stop-daemon.c from baselayout-1.12.6 Please submit patches against the version in 1.13.0_alpha9 Thanks |