Both unshare and nsenter use similar code to fork and have the parent wait for child's completion. Move it to a common library function.
function old new delta continue_as_child - 105 +105 unshare_main 1066 1004 -62 nsenter_main 850 753 -97 ------------------------------------------------------------------------------ (add/remove: 2/0 grow/shrink: 0/2 up/down: 105/-159) Total: -54 bytes text data bss dec hex filename 829552 4486 9120 843158 cdd96 busybox_old 829498 4486 9120 843104 cdd60 busybox_unstripped Signed-off-by: Bartosz Golaszewski <bartekg...@gmail.com> --- util-linux/namespace.c | 34 ++++++++++++++++++++++++++++++++++ util-linux/namespace.h | 7 +++++++ util-linux/nsenter.c | 20 ++------------------ util-linux/unshare.c | 19 ++----------------- 4 files changed, 45 insertions(+), 35 deletions(-) create mode 100644 util-linux/namespace.c diff --git a/util-linux/namespace.c b/util-linux/namespace.c new file mode 100644 index 0000000..1cfa1ae --- /dev/null +++ b/util-linux/namespace.c @@ -0,0 +1,34 @@ +/* vi: set sw=4 ts=4: */ +/* + * Common namespace code. + * + * Copyright (C) 2016 by Bartosz Golaszewski <bartekg...@gmail.com> + * + * Licensed under GPLv2 or later, see file LICENSE in this source tree. + */ + +//kbuild:lib-$(CONFIG_UNSHARE) += namespace.o +//kbuild:lib-$(CONFIG_NSENTER) += namespace.o + +#include "libbb.h" +#include "namespace.h" + +void continue_as_child(void) +{ + int exit_status, rv; + pid_t pid; + + pid = xfork(); + if (pid > 0) { + rv = safe_waitpid(pid, &exit_status, WUNTRACED); + if (rv < 0) + bb_perror_msg_and_die("waitpid"); + + if (WIFEXITED(exit_status)) + exit(WEXITSTATUS(exit_status)); + else if (WIFSIGNALED(exit_status)) + kill(getpid(), WTERMSIG(exit_status)); + + bb_error_msg_and_die("child exit failed"); + } /* Child continues. */ +} diff --git a/util-linux/namespace.h b/util-linux/namespace.h index da79fd9..42e8361 100644 --- a/util-linux/namespace.h +++ b/util-linux/namespace.h @@ -17,4 +17,11 @@ */ #define NS_PROC_PATH_MAX (sizeof("/proc//ns/user") + sizeof(pid_t) * 3) +/* + * Fork and wait for the child process to finish. Exit with the child process' + * exit status or deliver the signal which killed the child to the parent. + * Exit if fork() or waitpid() fails. + */ +void continue_as_child(void); + #endif /* __BB_NAMESPACE_H */ diff --git a/util-linux/nsenter.c b/util-linux/nsenter.c index 7beaddb..8e9247a 100644 --- a/util-linux/nsenter.c +++ b/util-linux/nsenter.c @@ -318,24 +318,8 @@ int nsenter_main(int argc UNUSED_PARAM, char **argv) * Entering the pid namespace implies forking unless it's been * explicitly requested by the user not to. */ - if (!(opts & OPT_nofork) && (opts & OPT_pid)) { - int exit_status; - pid_t pid; - - pid = xfork(); - if (pid > 0) { - status = safe_waitpid(pid, &exit_status, 0); - if (status < 0) - bb_perror_msg_and_die("waitpid"); - - if (WIFEXITED(exit_status)) - return WEXITSTATUS(exit_status); - else if (WIFSIGNALED(exit_status)) - kill(getpid(), WTERMSIG(exit_status)); - - bb_error_msg_and_die("child exit failed"); - } /* Child continues. */ - } + if (!(opts & OPT_nofork) && (opts & OPT_pid)) + continue_as_child(); if (opts & OPT_setgid) { status = setgroups(0, NULL); diff --git a/util-linux/unshare.c b/util-linux/unshare.c index b6146e3..637ff2a 100644 --- a/util-linux/unshare.c +++ b/util-linux/unshare.c @@ -386,23 +386,8 @@ int unshare_main(int argc UNUSED_PARAM, char **argv) * child. The user may want to use this option to spawn a new process * that'll become PID 1 in this new namespace. */ - if (opts & OPT_fork) { - int exit_status; - - pid = xfork(); - if (pid > 0) { - status = safe_waitpid(pid, &exit_status, 0); - if (status < 0) - bb_perror_msg_and_die("waitpid"); - - if (WIFEXITED(exit_status)) - return WEXITSTATUS(exit_status); - else if (WIFSIGNALED(exit_status)) - kill(getpid(), WTERMSIG(exit_status)); - - bb_error_msg_and_die("child exit failed"); - } /* Child continues. */ - } + if (opts & OPT_fork) + continue_as_child(); if (opts & OPT_map_root) { char uidmap_buf[sizeof(unsigned int) * 3 + sizeof(" 0 1")]; -- 2.1.4 _______________________________________________ busybox mailing list busybox@busybox.net http://lists.busybox.net/mailman/listinfo/busybox