From 61be00816a0c09379b4b3f2655c70e9e14bc0841 Mon Sep 17 00:00:00 2001 From: Ron Yorston Date: Tue, 2 May 2023 11:00:25 +0100 Subject: su: add option to wait for shell exit code The '-W' option causes su to wait for the elevated shell to terminate and returns its exit code. Costs 144 bytes. --- loginutils/suw32.c | 30 +++++++++++++++++++++++++++--- 1 file changed, 27 insertions(+), 3 deletions(-) diff --git a/loginutils/suw32.c b/loginutils/suw32.c index 34cb175ab..b0fb26442 100644 --- a/loginutils/suw32.c +++ b/loginutils/suw32.c @@ -16,23 +16,32 @@ //kbuild:lib-$(CONFIG_SUW32) += suw32.o //usage:#define suw32_trivial_usage -//usage: "[-c 'CMD'] [root [FILE ARGS | ARG0 ARGS]]" +//usage: "[-W] [root]\n" +//usage: "or: su [-W] -c CMD_STRING [[--] root [ARG0 [ARG...]]\n" +//usage: "or: su [-W] [--] root [arbitrary sh arguments]" //usage:#define suw32_full_usage "\n\n" //usage: "Run shell with elevated privileges\n" //usage: "\n -c CMD Command to pass to 'sh -c'" +//usage: "\n -W Wait for shell exit code" #include "libbb.h" #include "lazyload.h" +enum { + OPT_c = (1 << 0), + OPT_W = (1 << 1) +}; + int suw32_main(int argc, char **argv) MAIN_EXTERNALLY_VISIBLE; int suw32_main(int argc UNUSED_PARAM, char **argv) { + unsigned opt; char *opt_command = NULL; SHELLEXECUTEINFO info; char *bb_path, *cwd, *q, *args; DECLARE_PROC_ADDR(BOOL, ShellExecuteExA, SHELLEXECUTEINFOA *); - getopt32(argv, "c:", &opt_command); + opt = getopt32(argv, "c:W", &opt_command); argv += optind; if (argv[0]) { if (strcmp(argv[0], "root") != 0) { @@ -48,6 +57,8 @@ int suw32_main(int argc UNUSED_PARAM, char **argv) memset(&info, 0, sizeof(SHELLEXECUTEINFO)); info.cbSize = sizeof(SHELLEXECUTEINFO); /* info.fMask = SEE_MASK_DEFAULT; */ + if (opt & OPT_W) + info.fMask |= SEE_MASK_NOCLOSEPROCESS; /* info.hwnd = NULL; */ info.lpVerb = "runas"; info.lpFile = bb_path; @@ -87,5 +98,18 @@ int suw32_main(int argc UNUSED_PARAM, char **argv) if (!INIT_PROC_ADDR(shell32.dll, ShellExecuteExA)) return -1; - return !ShellExecuteExA(&info); + if (!ShellExecuteExA(&info)) + return 1; + + if (opt & OPT_W) { + DWORD r; + + WaitForSingleObject(info.hProcess, INFINITE); + if (!GetExitCodeProcess(info.hProcess, &r)) + r = 1; + CloseHandle(info.hProcess); + return r; + } + + return 0; } -- cgit v1.2.3-55-g6feb