public inbox for util-linux@vger.kernel.org
 help / color / mirror / Atom feed
From: ebiederm@xmission.com (Eric W. Biederman)
To: Karel Zak <kzak@redhat.com>
Cc: Mike Frysinger <vapier@gentoo.org>,
	util-linux@vger.kernel.org, Neil Horman <nhorman@tuxdriver.com>,
	"Serge E. Hallyn" <serge@hallyn.com>,
	"Michael Kerrisk \(man-pages\)" <mtk.manpages@gmail.com>
Subject: [PATCH 1/5] nsenter: Enhance waiting for a child process
Date: Wed, 16 Jan 2013 16:34:17 -0800	[thread overview]
Message-ID: <874niglkae.fsf_-_@xmission.com> (raw)
In-Reply-To: <87a9s8lkbq.fsf_-_@xmission.com> (Eric W. Biederman's message of "Wed, 16 Jan 2013 16:33:29 -0800")


In the case of a pid namespace we need to fork a child process instead
of calling exec.  Move all of that logic out of line into a function
continue_as_child, making the logic of the primary case easier to
understand.

Update the logic for waiting for a child process to suspend ourselves
when the child processes suspends and to continue the child process
when we are unsuspsended.  This supports the bash suspend command and
various editors that suspend themselves.

If the child process exits with a signal update the logic to run
kill(getpid(), WTERMSIG(status)) so the caller sees the same exit code
that nsenter observed.

There will always be permission to send signals to our children and
the tty is not changing so there is no need for the intermediate
process to forward signals to it's child.

Signed-off-by: "Eric W. Biederman" <ebiederm@xmission.com>
---
 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 e1f3995..ad01355 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);
 
-- 
1.7.5.4

  reply	other threads:[~2013-01-17  0:34 UTC|newest]

Thread overview: 24+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2013-01-11 10:29 [PATCH] enter: new command (light wrapper around setns) Eric W. Biederman
2013-01-11 10:54 ` Michael Kerrisk (man-pages)
2013-01-11 11:10   ` Eric W. Biederman
2013-01-11 13:13     ` Ángel González
2013-01-12  8:59     ` Michael Kerrisk (man-pages)
2013-01-11 16:13 ` Karel Zak
2013-01-11 22:11   ` Eric W. Biederman
2013-01-12  9:01     ` Michael Kerrisk (man-pages)
2013-01-11 22:46   ` [PATCH] nsenter: " Eric W. Biederman
2013-01-11 23:45     ` Mike Frysinger
2013-01-14  8:28       ` Karel Zak
2013-01-17  0:33         ` [PATCH 0/5] nsenter review comment fixes Eric W. Biederman
2013-01-17  0:34           ` Eric W. Biederman [this message]
2013-01-17  0:34           ` [PATCH 2/5] nsenter: Properly spell significant in a comment Eric W. Biederman
2013-01-17  0:35           ` [PATCH 3/5] nsenter: Add const to declarations where possible Eric W. Biederman
2013-01-17  0:35           ` [PATCH 4/5] nsenter: Replace a bare strtoul with strtoul_or_err Eric W. Biederman
2013-01-17  0:36           ` [PATCH 5/5] unshare,nsenter: Move the old libc handling into a common header namespace.h Eric W. Biederman
2013-01-17  3:11           ` [PATCH 0/5] nsenter review comment fixes Mike Frysinger
2013-01-17 12:35           ` Karel Zak
2013-01-15 18:51     ` [PATCH] nsenter: new command (light wrapper around setns) Serge E. Hallyn
2013-01-17 12:34     ` Karel Zak
2013-01-11 22:53   ` [PATCH] unshare: Add support for the pid and user namespaces Eric W. Biederman
2013-01-17 12:35     ` Karel Zak
2013-01-17 12:56       ` Eric W. Biederman

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=874niglkae.fsf_-_@xmission.com \
    --to=ebiederm@xmission.com \
    --cc=kzak@redhat.com \
    --cc=mtk.manpages@gmail.com \
    --cc=nhorman@tuxdriver.com \
    --cc=serge@hallyn.com \
    --cc=util-linux@vger.kernel.org \
    --cc=vapier@gentoo.org \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox