summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--sys-utils/setsid.15
-rw-r--r--sys-utils/setsid.c27
2 files changed, 27 insertions, 5 deletions
diff --git a/sys-utils/setsid.1 b/sys-utils/setsid.1
index eff794858..da8d648e7 100644
--- a/sys-utils/setsid.1
+++ b/sys-utils/setsid.1
@@ -15,6 +15,11 @@ runs a program in a new session.
.TP
\fB\-c\fP, \fB\-\-ctty\fP
Set the controlling terminal to the current one.
+.TP
+\fB\-w\fP, \fB\-\-wait\fP
+Wait the execution of the program to end, and return the exit value of
+the child as return value of the
+.BR setsid .
.SH "SEE ALSO"
.BR setsid (2)
.SH AUTHOR
diff --git a/sys-utils/setsid.c b/sys-utils/setsid.c
index 756a520d8..782de82b5 100644
--- a/sys-utils/setsid.c
+++ b/sys-utils/setsid.c
@@ -9,6 +9,8 @@
* 2001-01-18 John Fremlin <vii@penguinpowered.com>
* - fork in case we are process group leader
*
+ * 2008-08-20 Daniel Kahn Gillmor <dkg@fifthhorseman.net>
+ * - if forked, wait on child process and emit its return code.
*/
#include <getopt.h>
@@ -16,6 +18,8 @@
#include <stdlib.h>
#include <unistd.h>
#include <sys/ioctl.h>
+#include <sys/types.h>
+#include <sys/wait.h>
#include "c.h"
#include "nls.h"
@@ -29,8 +33,8 @@ static void __attribute__ ((__noreturn__)) usage(FILE * out)
program_invocation_short_name);
fputs(USAGE_OPTIONS, out);
- fputs(_(" -c, --ctty set the controlling terminal to the current one\n"),
- out);
+ fputs(_(" -c, --ctty set the controlling terminal to the current one\n"), out);
+ fputs(_(" -w, --wait wait program to exit, and use the same return\n"), out);
fputs(USAGE_HELP, out);
fputs(USAGE_VERSION, out);
@@ -43,9 +47,12 @@ int main(int argc, char **argv)
{
int ch;
int ctty = 0;
+ pid_t pid;
+ int status = 0;
static const struct option longopts[] = {
{"ctty", no_argument, NULL, 'c'},
+ {"wait", no_argument, NULL, 'w'},
{"version", no_argument, NULL, 'V'},
{"help", no_argument, NULL, 'h'},
{NULL, 0, NULL, 0}
@@ -56,7 +63,7 @@ int main(int argc, char **argv)
textdomain(PACKAGE);
atexit(close_stdout);
- while ((ch = getopt_long(argc, argv, "+Vhc", longopts, NULL)) != -1)
+ while ((ch = getopt_long(argc, argv, "+Vhcw", longopts, NULL)) != -1)
switch (ch) {
case 'V':
printf(UTIL_LINUX_VERSION);
@@ -64,6 +71,9 @@ int main(int argc, char **argv)
case 'c':
ctty=1;
break;
+ case 'w':
+ status = 1;
+ break;
case 'h':
usage(stdout);
default:
@@ -74,7 +84,8 @@ int main(int argc, char **argv)
usage(stderr);
if (getpgrp() == getpid()) {
- switch (fork()) {
+ pid = fork();
+ switch (pid) {
case -1:
err(EXIT_FAILURE, _("fork"));
case 0:
@@ -82,7 +93,13 @@ int main(int argc, char **argv)
break;
default:
/* parent */
- return 0;
+ if (!status)
+ return EXIT_SUCCESS;
+ if (wait(&status) != pid)
+ err(EXIT_FAILURE, "wait");
+ if (WIFEXITED(status))
+ return WEXITSTATUS(status);
+ err(status, _("child %d did not exit normally"), pid);
}
}
if (setsid() < 0)