diff options
-rw-r--r-- | Makefile.flags | 2 | ||||
-rw-r--r-- | applets/applet_tables.c | 9 | ||||
-rw-r--r-- | include/libbb.h | 2 | ||||
-rw-r--r-- | libbb/appletlib.c | 19 | ||||
-rw-r--r-- | shell/ash.c | 7 | ||||
-rw-r--r-- | win32/process.c | 107 |
6 files changed, 104 insertions, 42 deletions
diff --git a/Makefile.flags b/Makefile.flags index 6bb6a8fb1..86ab0a0ec 100644 --- a/Makefile.flags +++ b/Makefile.flags | |||
@@ -126,7 +126,7 @@ endif | |||
126 | ifeq ($(CONFIG_PLATFORM_MINGW32),y) | 126 | ifeq ($(CONFIG_PLATFORM_MINGW32),y) |
127 | CFLAGS += -Iwin32 -DHAVE_STRING_H=1 -DHAVE_CONFIG_H=0 -fno-builtin-stpcpy -fno-ident | 127 | CFLAGS += -Iwin32 -DHAVE_STRING_H=1 -DHAVE_CONFIG_H=0 -fno-builtin-stpcpy -fno-ident |
128 | EXEEXT = .exe | 128 | EXEEXT = .exe |
129 | LDLIBS += userenv ws2_32 | 129 | LDLIBS += userenv psapi ws2_32 |
130 | endif | 130 | endif |
131 | 131 | ||
132 | # Android has no separate crypt library | 132 | # Android has no separate crypt library |
diff --git a/applets/applet_tables.c b/applets/applet_tables.c index 9a2aa5329..858429ac2 100644 --- a/applets/applet_tables.c +++ b/applets/applet_tables.c | |||
@@ -61,6 +61,7 @@ static int str_isalnum_(const char *s) | |||
61 | int main(int argc, char **argv) | 61 | int main(int argc, char **argv) |
62 | { | 62 | { |
63 | int i, j; | 63 | int i, j; |
64 | unsigned MAX_APPLET_NAME_LEN = 1; | ||
64 | 65 | ||
65 | // In find_applet_by_name(), before linear search, narrow it down | 66 | // In find_applet_by_name(), before linear search, narrow it down |
66 | // by looking at N "equidistant" names. With ~350 applets: | 67 | // by looking at N "equidistant" names. With ~350 applets: |
@@ -124,8 +125,8 @@ int main(int argc, char **argv) | |||
124 | printf("const char applet_names[] ALIGN1 = \"\"\n"); | 125 | printf("const char applet_names[] ALIGN1 = \"\"\n"); |
125 | for (i = 0; i < NUM_APPLETS; i++) { | 126 | for (i = 0; i < NUM_APPLETS; i++) { |
126 | printf("\"%s\" \"\\0\"\n", applets[i].name); | 127 | printf("\"%s\" \"\\0\"\n", applets[i].name); |
127 | // if (MAX_APPLET_NAME_LEN < strlen(applets[i].name)) | 128 | if (MAX_APPLET_NAME_LEN < strlen(applets[i].name)) |
128 | // MAX_APPLET_NAME_LEN = strlen(applets[i].name); | 129 | MAX_APPLET_NAME_LEN = strlen(applets[i].name); |
129 | } | 130 | } |
130 | printf(";\n\n"); | 131 | printf(";\n\n"); |
131 | 132 | ||
@@ -193,8 +194,8 @@ int main(int argc, char **argv) | |||
193 | #endif | 194 | #endif |
194 | //printf("#endif /* SKIP_definitions */\n"); | 195 | //printf("#endif /* SKIP_definitions */\n"); |
195 | 196 | ||
196 | // printf("\n"); | 197 | printf("\n"); |
197 | // printf("#define MAX_APPLET_NAME_LEN %u\n", MAX_APPLET_NAME_LEN); | 198 | printf("#define MAX_APPLET_NAME_LEN %u\n", MAX_APPLET_NAME_LEN); |
198 | 199 | ||
199 | if (argv[2]) { | 200 | if (argv[2]) { |
200 | FILE *fp; | 201 | FILE *fp; |
diff --git a/include/libbb.h b/include/libbb.h index da3459224..d948f88f3 100644 --- a/include/libbb.h +++ b/include/libbb.h | |||
@@ -2075,7 +2075,7 @@ extern const char bb_path_wtmp_file[] ALIGN1; | |||
2075 | #define bb_dev_null "/dev/null" | 2075 | #define bb_dev_null "/dev/null" |
2076 | #if ENABLE_PLATFORM_MINGW32 | 2076 | #if ENABLE_PLATFORM_MINGW32 |
2077 | #define bb_busybox_exec_path get_busybox_exec_path() | 2077 | #define bb_busybox_exec_path get_busybox_exec_path() |
2078 | extern char *bb_applet_pid(void); | 2078 | extern char bb_applet_name[]; |
2079 | #else | 2079 | #else |
2080 | extern const char bb_busybox_exec_path[] ALIGN1; | 2080 | extern const char bb_busybox_exec_path[] ALIGN1; |
2081 | #endif | 2081 | #endif |
diff --git a/libbb/appletlib.c b/libbb/appletlib.c index 1488d4bd6..3e740363a 100644 --- a/libbb/appletlib.c +++ b/libbb/appletlib.c | |||
@@ -796,13 +796,6 @@ static void install_links(const char *busybox UNUSED_PARAM, | |||
796 | 796 | ||
797 | static void run_applet_and_exit(const char *name, char **argv) NORETURN; | 797 | static void run_applet_and_exit(const char *name, char **argv) NORETURN; |
798 | 798 | ||
799 | #if ENABLE_PLATFORM_MINGW32 | ||
800 | char *bb_applet_pid(void) | ||
801 | { | ||
802 | return auto_string(xasprintf("BB_APPLET_%d=%s", getpid(), applet_name)); | ||
803 | } | ||
804 | #endif | ||
805 | |||
806 | # if ENABLE_BUSYBOX | 799 | # if ENABLE_BUSYBOX |
807 | # if ENABLE_FEATURE_SH_STANDALONE && ENABLE_FEATURE_TAB_COMPLETION | 800 | # if ENABLE_FEATURE_SH_STANDALONE && ENABLE_FEATURE_TAB_COMPLETION |
808 | /* | 801 | /* |
@@ -979,6 +972,11 @@ int busybox_main(int argc UNUSED_PARAM, char **argv) | |||
979 | # endif | 972 | # endif |
980 | 973 | ||
981 | # if NUM_APPLETS > 0 | 974 | # if NUM_APPLETS > 0 |
975 | |||
976 | # if ENABLE_PLATFORM_MINGW32 | ||
977 | char bb_applet_name[MAX_APPLET_NAME_LEN+1]; | ||
978 | # endif | ||
979 | |||
982 | void FAST_FUNC run_applet_no_and_exit(int applet_no, const char *name, char **argv) | 980 | void FAST_FUNC run_applet_no_and_exit(int applet_no, const char *name, char **argv) |
983 | { | 981 | { |
984 | int argc = string_array_len(argv); | 982 | int argc = string_array_len(argv); |
@@ -988,6 +986,9 @@ void FAST_FUNC run_applet_no_and_exit(int applet_no, const char *name, char **ar | |||
988 | * "-/sbin/halt" -> "halt", for example. | 986 | * "-/sbin/halt" -> "halt", for example. |
989 | */ | 987 | */ |
990 | applet_name = name; | 988 | applet_name = name; |
989 | #if ENABLE_PLATFORM_MINGW32 | ||
990 | strcpy(bb_applet_name, applet_name); | ||
991 | #endif | ||
991 | 992 | ||
992 | /* Special case. POSIX says "test --help" | 993 | /* Special case. POSIX says "test --help" |
993 | * should be no different from e.g. "test --foo". | 994 | * should be no different from e.g. "test --foo". |
@@ -1014,10 +1015,6 @@ void FAST_FUNC run_applet_no_and_exit(int applet_no, const char *name, char **ar | |||
1014 | if (ENABLE_FEATURE_SUID) | 1015 | if (ENABLE_FEATURE_SUID) |
1015 | check_suid(applet_no); | 1016 | check_suid(applet_no); |
1016 | 1017 | ||
1017 | #if ENABLE_PLATFORM_MINGW32 | ||
1018 | putenv(bb_applet_pid()); | ||
1019 | #endif | ||
1020 | |||
1021 | xfunc_error_retval = applet_main[applet_no](argc, argv); | 1018 | xfunc_error_retval = applet_main[applet_no](argc, argv); |
1022 | /* Note: applet_main() may also not return (die on a xfunc or such) */ | 1019 | /* Note: applet_main() may also not return (die on a xfunc or such) */ |
1023 | xfunc_die(); | 1020 | xfunc_die(); |
diff --git a/shell/ash.c b/shell/ash.c index 2a1ddac39..6d24fb55a 100644 --- a/shell/ash.c +++ b/shell/ash.c | |||
@@ -14975,13 +14975,6 @@ reinitvar(void) | |||
14975 | varinit[i].var_func = varinit_data[i].var_func; | 14975 | varinit[i].var_func = varinit_data[i].var_func; |
14976 | } | 14976 | } |
14977 | vlineno.var_text = linenovar; | 14977 | vlineno.var_text = linenovar; |
14978 | |||
14979 | /* | ||
14980 | * BB_APPLET_<pid> was correct when 'sh --forkshell' was started | ||
14981 | * but has now been overwritten by the environment from the forkshell | ||
14982 | * data block. Reinstate it. | ||
14983 | */ | ||
14984 | setvareq(bb_applet_pid(), VEXPORT); | ||
14985 | } | 14978 | } |
14986 | 14979 | ||
14987 | /* FIXME: should consider running forkparent() and forkchild() */ | 14980 | /* FIXME: should consider running forkparent() and forkchild() */ |
diff --git a/win32/process.c b/win32/process.c index d6176ca23..3219fcad4 100644 --- a/win32/process.c +++ b/win32/process.c | |||
@@ -1,5 +1,6 @@ | |||
1 | #include "libbb.h" | 1 | #include "libbb.h" |
2 | #include <tlhelp32.h> | 2 | #include <tlhelp32.h> |
3 | #include <psapi.h> | ||
3 | 4 | ||
4 | int waitpid(pid_t pid, int *status, int options) | 5 | int waitpid(pid_t pid, int *status, int options) |
5 | { | 6 | { |
@@ -406,6 +407,79 @@ static inline long long filetime_to_ticks(const FILETIME *ft) | |||
406 | HNSEC_PER_TICK; | 407 | HNSEC_PER_TICK; |
407 | } | 408 | } |
408 | 409 | ||
410 | /* | ||
411 | * Attempt to get the applet name from another instance of busybox.exe. | ||
412 | * This will only work if the other process is using the same binary | ||
413 | * as the current process. If anything goes wrong just give up. | ||
414 | */ | ||
415 | static char *get_applet_name(DWORD pid, char *exe) | ||
416 | { | ||
417 | HANDLE proc; | ||
418 | HMODULE mlist[32]; | ||
419 | DWORD needed; | ||
420 | void *address; | ||
421 | char *my_base; | ||
422 | char buffer[128]; | ||
423 | char *name = NULL; | ||
424 | int i; | ||
425 | |||
426 | if (!(proc=OpenProcess(PROCESS_QUERY_INFORMATION|PROCESS_VM_READ, | ||
427 | FALSE, pid))) { | ||
428 | return NULL; | ||
429 | } | ||
430 | |||
431 | /* | ||
432 | * Search for the module that matches the name of the executable. | ||
433 | * The values returned in mlist are actually the base address of | ||
434 | * the module in the other process (as noted in the documentation | ||
435 | * for the MODULEINFO structure). | ||
436 | */ | ||
437 | if (!EnumProcessModules(proc, mlist, sizeof(mlist), &needed)) { | ||
438 | goto finish; | ||
439 | } | ||
440 | |||
441 | for (i=0; i<needed/sizeof(HMODULE); ++i) { | ||
442 | char modname[MAX_PATH]; | ||
443 | if (GetModuleFileNameEx(proc, mlist[i], modname, sizeof(modname))) { | ||
444 | if (strcasecmp(bb_basename(modname), exe) == 0) { | ||
445 | break; | ||
446 | } | ||
447 | } | ||
448 | } | ||
449 | |||
450 | if (i == needed/sizeof(HMODULE)) { | ||
451 | goto finish; | ||
452 | } | ||
453 | |||
454 | /* attempt to read the BusyBox version string */ | ||
455 | my_base = (char *)GetModuleHandle(NULL); | ||
456 | address = (char *)mlist[i] + ((char *)bb_banner - my_base); | ||
457 | if (!ReadProcessMemory(proc, address, buffer, 128, NULL)) { | ||
458 | goto finish; | ||
459 | } | ||
460 | |||
461 | if (memcmp(buffer, bb_banner, strlen(bb_banner)) != 0) { | ||
462 | /* version mismatch (or not BusyBox at all) */ | ||
463 | goto finish; | ||
464 | } | ||
465 | |||
466 | /* attempt to read the applet name */ | ||
467 | address = (char *)mlist[i] + ((char *)bb_applet_name - my_base); | ||
468 | if (!ReadProcessMemory(proc, address, buffer, 128, NULL)) { | ||
469 | goto finish; | ||
470 | } | ||
471 | |||
472 | /* check that the string really is an applet name */ | ||
473 | buffer[31] = '\0'; | ||
474 | if (find_applet_by_name(buffer) >= 0) { | ||
475 | name = auto_string(xstrdup(buffer)); | ||
476 | } | ||
477 | |||
478 | finish: | ||
479 | CloseHandle(proc); | ||
480 | return name; | ||
481 | } | ||
482 | |||
409 | /* POSIX version in libbb/procps.c */ | 483 | /* POSIX version in libbb/procps.c */ |
410 | procps_status_t* FAST_FUNC procps_scan(procps_status_t* sp, int flags | 484 | procps_status_t* FAST_FUNC procps_scan(procps_status_t* sp, int flags |
411 | #if !ENABLE_FEATURE_PS_TIME && !ENABLE_FEATURE_PS_LONG | 485 | #if !ENABLE_FEATURE_PS_TIME && !ENABLE_FEATURE_PS_LONG |
@@ -414,7 +488,8 @@ UNUSED_PARAM | |||
414 | ) | 488 | ) |
415 | { | 489 | { |
416 | PROCESSENTRY32 pe; | 490 | PROCESSENTRY32 pe; |
417 | const char *comm; | 491 | const char *comm, *name; |
492 | BOOL ret; | ||
418 | 493 | ||
419 | pe.dwSize = sizeof(pe); | 494 | pe.dwSize = sizeof(pe); |
420 | if (!sp) { | 495 | if (!sp) { |
@@ -424,18 +499,16 @@ UNUSED_PARAM | |||
424 | free(sp); | 499 | free(sp); |
425 | return NULL; | 500 | return NULL; |
426 | } | 501 | } |
427 | if (!Process32First(sp->snapshot, &pe)) { | 502 | ret = Process32First(sp->snapshot, &pe); |
428 | CloseHandle(sp->snapshot); | ||
429 | free(sp); | ||
430 | return NULL; | ||
431 | } | ||
432 | } | 503 | } |
433 | else { | 504 | else { |
434 | if (!Process32Next(sp->snapshot, &pe)) { | 505 | ret = Process32Next(sp->snapshot, &pe); |
435 | CloseHandle(sp->snapshot); | 506 | } |
436 | free(sp); | 507 | |
437 | return NULL; | 508 | if (!ret) { |
438 | } | 509 | CloseHandle(sp->snapshot); |
510 | free(sp); | ||
511 | return NULL; | ||
439 | } | 512 | } |
440 | 513 | ||
441 | memset(&sp->vsz, 0, sizeof(*sp) - offsetof(procps_status_t, vsz)); | 514 | memset(&sp->vsz, 0, sizeof(*sp) - offsetof(procps_status_t, vsz)); |
@@ -478,19 +551,17 @@ UNUSED_PARAM | |||
478 | sp->pid = pe.th32ProcessID; | 551 | sp->pid = pe.th32ProcessID; |
479 | sp->ppid = pe.th32ParentProcessID; | 552 | sp->ppid = pe.th32ParentProcessID; |
480 | 553 | ||
481 | comm = pe.szExeFile; | ||
482 | if (sp->pid == GetProcessId(GetCurrentProcess())) { | 554 | if (sp->pid == GetProcessId(GetCurrentProcess())) { |
483 | comm = applet_name; | 555 | comm = applet_name; |
484 | } | 556 | } |
557 | else if ((name=get_applet_name(pe.th32ProcessID, pe.szExeFile)) != NULL) { | ||
558 | comm = name; | ||
559 | } | ||
485 | else { | 560 | else { |
486 | char name[32], *value; | 561 | comm = pe.szExeFile; |
487 | |||
488 | sprintf(name, "BB_APPLET_%d", sp->pid); | ||
489 | if ((value=getenv(name)) != NULL) { | ||
490 | comm = value; | ||
491 | } | ||
492 | } | 562 | } |
493 | safe_strncpy(sp->comm, comm, COMM_LEN); | 563 | safe_strncpy(sp->comm, comm, COMM_LEN); |
564 | |||
494 | return sp; | 565 | return sp; |
495 | } | 566 | } |
496 | 567 | ||