nsenter,unshare: share common code; fix a bug of not closing all fds
function old new delta xvfork_parent_waits_and_exits - 64 +64 exec_prog_or_SHELL - 39 +39 unshare_main 873 810 -63 nsenter_main 663 596 -67 ------------------------------------------------------------------------------ (add/remove: 2/0 grow/shrink: 0/2 up/down: 106/-130) Total: -27 bytes Signed-off-by: Denys Vlasenko <vda.linux@googlemail.com>
This commit is contained in:
parent
c87e81f944
commit
8220399173
@ -992,9 +992,10 @@ int BB_EXECVP(const char *file, char *const argv[]) FAST_FUNC;
|
|||||||
#define BB_EXECVP(prog,cmd) execvp(prog,cmd)
|
#define BB_EXECVP(prog,cmd) execvp(prog,cmd)
|
||||||
#define BB_EXECLP(prog,cmd,...) execlp(prog,cmd,__VA_ARGS__)
|
#define BB_EXECLP(prog,cmd,...) execlp(prog,cmd,__VA_ARGS__)
|
||||||
#endif
|
#endif
|
||||||
int BB_EXECVP_or_die(char **argv) NORETURN FAST_FUNC;
|
void BB_EXECVP_or_die(char **argv) NORETURN FAST_FUNC;
|
||||||
|
void exec_prog_or_SHELL(char **argv) NORETURN FAST_FUNC;
|
||||||
|
|
||||||
/* xvfork() can't be a _function_, return after vfork mangles stack
|
/* xvfork() can't be a _function_, return after vfork in child mangles stack
|
||||||
* in the parent. It must be a macro. */
|
* in the parent. It must be a macro. */
|
||||||
#define xvfork() \
|
#define xvfork() \
|
||||||
({ \
|
({ \
|
||||||
@ -1006,6 +1007,7 @@ int BB_EXECVP_or_die(char **argv) NORETURN FAST_FUNC;
|
|||||||
#if BB_MMU
|
#if BB_MMU
|
||||||
pid_t xfork(void) FAST_FUNC;
|
pid_t xfork(void) FAST_FUNC;
|
||||||
#endif
|
#endif
|
||||||
|
void xvfork_parent_waits_and_exits(void) FAST_FUNC;
|
||||||
|
|
||||||
/* NOMMU friendy fork+exec: */
|
/* NOMMU friendy fork+exec: */
|
||||||
pid_t spawn(char **argv) FAST_FUNC;
|
pid_t spawn(char **argv) FAST_FUNC;
|
||||||
|
@ -83,10 +83,19 @@ int FAST_FUNC BB_EXECVP(const char *file, char *const argv[])
|
|||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
int FAST_FUNC BB_EXECVP_or_die(char **argv)
|
void FAST_FUNC BB_EXECVP_or_die(char **argv)
|
||||||
{
|
{
|
||||||
BB_EXECVP(argv[0], argv);
|
BB_EXECVP(argv[0], argv);
|
||||||
/* SUSv3-mandated exit codes */
|
/* SUSv3-mandated exit codes */
|
||||||
xfunc_error_retval = (errno == ENOENT) ? 127 : 126;
|
xfunc_error_retval = (errno == ENOENT) ? 127 : 126;
|
||||||
bb_perror_msg_and_die("can't execute '%s'", argv[0]);
|
bb_perror_msg_and_die("can't execute '%s'", argv[0]);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* Typical idiom for applets which exec *optional* PROG [ARGS] */
|
||||||
|
void FAST_FUNC exec_prog_or_SHELL(char **argv)
|
||||||
|
{
|
||||||
|
if (argv[0]) {
|
||||||
|
BB_EXECVP_or_die(argv);
|
||||||
|
}
|
||||||
|
run_shell(getenv("SHELL"), /*login:*/ 1, NULL, NULL);
|
||||||
|
}
|
||||||
|
@ -659,3 +659,19 @@ pid_t FAST_FUNC xfork(void)
|
|||||||
return pid;
|
return pid;
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
void FAST_FUNC xvfork_parent_waits_and_exits(void)
|
||||||
|
{
|
||||||
|
pid_t pid;
|
||||||
|
|
||||||
|
fflush_all();
|
||||||
|
pid = xvfork();
|
||||||
|
if (pid > 0) {
|
||||||
|
/* Parent */
|
||||||
|
int exit_status = wait_for_exitstatus(pid);
|
||||||
|
if (WIFSIGNALED(exit_status))
|
||||||
|
kill_myself_with_sig(WTERMSIG(exit_status));
|
||||||
|
_exit(WEXITSTATUS(exit_status));
|
||||||
|
}
|
||||||
|
/* Child continues */
|
||||||
|
}
|
||||||
|
@ -230,7 +230,7 @@ int nsenter_main(int argc UNUSED_PARAM, char **argv)
|
|||||||
ns->ns_nsfile8 + 3 /* skip over "ns/" */
|
ns->ns_nsfile8 + 3 /* skip over "ns/" */
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
/*close(ns_ctx->fd);*/
|
close(ns_ctx->fd); /* should close fds, to not confuse exec'ed PROG */
|
||||||
/*ns_ctx->fd = -1;*/
|
/*ns_ctx->fd = -1;*/
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -244,13 +244,13 @@ int nsenter_main(int argc UNUSED_PARAM, char **argv)
|
|||||||
}
|
}
|
||||||
xfchdir(root_fd);
|
xfchdir(root_fd);
|
||||||
xchroot(".");
|
xchroot(".");
|
||||||
/*close(root_fd);*/
|
close(root_fd);
|
||||||
/*root_fd = -1;*/
|
/*root_fd = -1;*/
|
||||||
}
|
}
|
||||||
|
|
||||||
if (wd_fd >= 0) {
|
if (wd_fd >= 0) {
|
||||||
xfchdir(wd_fd);
|
xfchdir(wd_fd);
|
||||||
/*close(wd_fd);*/
|
close(wd_fd);
|
||||||
/*wd_fd = -1;*/
|
/*wd_fd = -1;*/
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -259,14 +259,7 @@ int nsenter_main(int argc UNUSED_PARAM, char **argv)
|
|||||||
* explicitly requested by the user not to.
|
* explicitly requested by the user not to.
|
||||||
*/
|
*/
|
||||||
if (!(opts & OPT_nofork) && (opts & OPT_pid)) {
|
if (!(opts & OPT_nofork) && (opts & OPT_pid)) {
|
||||||
pid_t pid = xvfork();
|
xvfork_parent_waits_and_exits();
|
||||||
if (pid > 0) {
|
|
||||||
/* Parent */
|
|
||||||
int exit_status = wait_for_exitstatus(pid);
|
|
||||||
if (WIFSIGNALED(exit_status))
|
|
||||||
kill_myself_with_sig(WTERMSIG(exit_status));
|
|
||||||
return WEXITSTATUS(exit_status);
|
|
||||||
}
|
|
||||||
/* Child continues */
|
/* Child continues */
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -278,9 +271,5 @@ int nsenter_main(int argc UNUSED_PARAM, char **argv)
|
|||||||
if (opts & OPT_setuid)
|
if (opts & OPT_setuid)
|
||||||
xsetuid(uid);
|
xsetuid(uid);
|
||||||
|
|
||||||
if (*argv) {
|
exec_prog_or_SHELL(argv);
|
||||||
BB_EXECVP_or_die(argv);
|
|
||||||
}
|
|
||||||
|
|
||||||
run_shell(getenv("SHELL"), /*login:*/ 1, NULL, NULL);
|
|
||||||
}
|
}
|
||||||
|
@ -281,7 +281,7 @@ int unshare_main(int argc UNUSED_PARAM, char **argv)
|
|||||||
|
|
||||||
if (fdp.wr >= 0) {
|
if (fdp.wr >= 0) {
|
||||||
close(fdp.wr); /* Release child */
|
close(fdp.wr); /* Release child */
|
||||||
/*close(fdp.rd);*/
|
close(fdp.rd); /* should close fd, to not confuse exec'ed PROG */
|
||||||
}
|
}
|
||||||
|
|
||||||
if (need_mount) {
|
if (need_mount) {
|
||||||
@ -307,14 +307,7 @@ int unshare_main(int argc UNUSED_PARAM, char **argv)
|
|||||||
* that'll become PID 1 in this new namespace.
|
* that'll become PID 1 in this new namespace.
|
||||||
*/
|
*/
|
||||||
if (opts & OPT_fork) {
|
if (opts & OPT_fork) {
|
||||||
pid_t pid = xfork();
|
xvfork_parent_waits_and_exits();
|
||||||
if (pid > 0) {
|
|
||||||
/* Parent */
|
|
||||||
int exit_status = wait_for_exitstatus(pid);
|
|
||||||
if (WIFSIGNALED(exit_status))
|
|
||||||
kill_myself_with_sig(WTERMSIG(exit_status));
|
|
||||||
return WEXITSTATUS(exit_status);
|
|
||||||
}
|
|
||||||
/* Child continues */
|
/* Child continues */
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -354,11 +347,5 @@ int unshare_main(int argc UNUSED_PARAM, char **argv)
|
|||||||
mount_or_die("proc", proc_mnt_target, "proc", MS_NOSUID | MS_NOEXEC | MS_NODEV);
|
mount_or_die("proc", proc_mnt_target, "proc", MS_NOSUID | MS_NOEXEC | MS_NODEV);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (argv[0]) {
|
exec_prog_or_SHELL(argv);
|
||||||
BB_EXECVP_or_die(argv);
|
|
||||||
}
|
|
||||||
/* unshare from util-linux 2.27.1, despite not documenting it,
|
|
||||||
* runs a login shell (argv0="-sh") if no PROG is given
|
|
||||||
*/
|
|
||||||
run_shell(getenv("SHELL"), /*login:*/ 1, NULL, NULL);
|
|
||||||
}
|
}
|
||||||
|
Loading…
x
Reference in New Issue
Block a user