aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorRon Yorston <rmy@pobox.com>2023-05-02 11:00:25 +0100
committerRon Yorston <rmy@pobox.com>2023-05-02 11:00:25 +0100
commit61be00816a0c09379b4b3f2655c70e9e14bc0841 (patch)
tree1e3650ac07a6aed72db303dd0791a81b3563bcfc
parent6113cbb368238541e63f3b415ad044435541688b (diff)
downloadbusybox-w32-61be00816a0c09379b4b3f2655c70e9e14bc0841.tar.gz
busybox-w32-61be00816a0c09379b4b3f2655c70e9e14bc0841.tar.bz2
busybox-w32-61be00816a0c09379b4b3f2655c70e9e14bc0841.zip
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.
-rw-r--r--loginutils/suw32.c30
1 files 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 @@
16//kbuild:lib-$(CONFIG_SUW32) += suw32.o 16//kbuild:lib-$(CONFIG_SUW32) += suw32.o
17 17
18//usage:#define suw32_trivial_usage 18//usage:#define suw32_trivial_usage
19//usage: "[-c 'CMD'] [root [FILE ARGS | ARG0 ARGS]]" 19//usage: "[-W] [root]\n"
20//usage: "or: su [-W] -c CMD_STRING [[--] root [ARG0 [ARG...]]\n"
21//usage: "or: su [-W] [--] root [arbitrary sh arguments]"
20//usage:#define suw32_full_usage "\n\n" 22//usage:#define suw32_full_usage "\n\n"
21//usage: "Run shell with elevated privileges\n" 23//usage: "Run shell with elevated privileges\n"
22//usage: "\n -c CMD Command to pass to 'sh -c'" 24//usage: "\n -c CMD Command to pass to 'sh -c'"
25//usage: "\n -W Wait for shell exit code"
23 26
24#include "libbb.h" 27#include "libbb.h"
25#include "lazyload.h" 28#include "lazyload.h"
26 29
30enum {
31 OPT_c = (1 << 0),
32 OPT_W = (1 << 1)
33};
34
27int suw32_main(int argc, char **argv) MAIN_EXTERNALLY_VISIBLE; 35int suw32_main(int argc, char **argv) MAIN_EXTERNALLY_VISIBLE;
28int suw32_main(int argc UNUSED_PARAM, char **argv) 36int suw32_main(int argc UNUSED_PARAM, char **argv)
29{ 37{
38 unsigned opt;
30 char *opt_command = NULL; 39 char *opt_command = NULL;
31 SHELLEXECUTEINFO info; 40 SHELLEXECUTEINFO info;
32 char *bb_path, *cwd, *q, *args; 41 char *bb_path, *cwd, *q, *args;
33 DECLARE_PROC_ADDR(BOOL, ShellExecuteExA, SHELLEXECUTEINFOA *); 42 DECLARE_PROC_ADDR(BOOL, ShellExecuteExA, SHELLEXECUTEINFOA *);
34 43
35 getopt32(argv, "c:", &opt_command); 44 opt = getopt32(argv, "c:W", &opt_command);
36 argv += optind; 45 argv += optind;
37 if (argv[0]) { 46 if (argv[0]) {
38 if (strcmp(argv[0], "root") != 0) { 47 if (strcmp(argv[0], "root") != 0) {
@@ -48,6 +57,8 @@ int suw32_main(int argc UNUSED_PARAM, char **argv)
48 memset(&info, 0, sizeof(SHELLEXECUTEINFO)); 57 memset(&info, 0, sizeof(SHELLEXECUTEINFO));
49 info.cbSize = sizeof(SHELLEXECUTEINFO); 58 info.cbSize = sizeof(SHELLEXECUTEINFO);
50 /* info.fMask = SEE_MASK_DEFAULT; */ 59 /* info.fMask = SEE_MASK_DEFAULT; */
60 if (opt & OPT_W)
61 info.fMask |= SEE_MASK_NOCLOSEPROCESS;
51 /* info.hwnd = NULL; */ 62 /* info.hwnd = NULL; */
52 info.lpVerb = "runas"; 63 info.lpVerb = "runas";
53 info.lpFile = bb_path; 64 info.lpFile = bb_path;
@@ -87,5 +98,18 @@ int suw32_main(int argc UNUSED_PARAM, char **argv)
87 if (!INIT_PROC_ADDR(shell32.dll, ShellExecuteExA)) 98 if (!INIT_PROC_ADDR(shell32.dll, ShellExecuteExA))
88 return -1; 99 return -1;
89 100
90 return !ShellExecuteExA(&info); 101 if (!ShellExecuteExA(&info))
102 return 1;
103
104 if (opt & OPT_W) {
105 DWORD r;
106
107 WaitForSingleObject(info.hProcess, INFINITE);
108 if (!GetExitCodeProcess(info.hProcess, &r))
109 r = 1;
110 CloseHandle(info.hProcess);
111 return r;
112 }
113
114 return 0;
91} 115}