diff options
Diffstat (limited to 'sys-utils')
-rw-r--r-- | sys-utils/nsenter.c | 48 |
1 files changed, 35 insertions, 13 deletions
diff --git a/sys-utils/nsenter.c b/sys-utils/nsenter.c index f9c663648..a264515eb 100644 --- a/sys-utils/nsenter.c +++ b/sys-utils/nsenter.c @@ -145,6 +145,39 @@ static void open_namespace_fd(int nstype, char *path) err(EXIT_FAILURE, "Unrecognized namespace type"); } +static void continue_as_child(void) +{ + pid_t child = fork(); + int status; + pid_t ret; + + if (child < 0) + err(EXIT_FAILURE, _("fork failed")); + + /* Only the child returns */ + if (child == 0) + return; + + for (;;) { + ret = waitpid(child, &status, WUNTRACED); + if ((ret == child) && (WIFSTOPPED(status))) { + /* The child suspended so suspend us as well */ + kill(getpid(), SIGSTOP); + kill(child, SIGCONT); + } else { + break; + } + } + /* Return the child's exit code if possible */ + if (WIFEXITED(status)) { + exit(WEXITSTATUS(status)); + } + else if (WIFSIGNALED(status)) { + kill(getpid(), WTERMSIG(status)); + } + exit(EXIT_FAILURE); +} + int main(int argc, char *argv[]) { static const struct option longopts[] = { @@ -266,19 +299,8 @@ int main(int argc, char *argv[]) wd_fd = -1; } - if (do_fork) { - pid_t child = fork(); - if (child < 0) - err(EXIT_FAILURE, _("fork failed")); - if (child != 0) { - int status; - if ((waitpid(child, &status, 0) == child) && - WIFEXITED(status)) { - exit(WEXITSTATUS(status)); - } - exit(EXIT_FAILURE); - } - } + if (do_fork) + continue_as_child(); execvp(argv[optind], argv + optind); |