diff options
| author | Ron Yorston <rmy@pobox.com> | 2020-06-09 16:25:49 +0100 |
|---|---|---|
| committer | Ron Yorston <rmy@pobox.com> | 2020-06-09 16:25:49 +0100 |
| commit | 4fe76647b356a85810fa3d355d7ad0512be1210c (patch) | |
| tree | 80f760e239a2013aadaecfc92ad7652129bd3ebf /shell/ash.c | |
| parent | 0656b8730855833567bf305b930442f50cbd44b4 (diff) | |
| download | busybox-w32-4fe76647b356a85810fa3d355d7ad0512be1210c.tar.gz busybox-w32-4fe76647b356a85810fa3d355d7ad0512be1210c.tar.bz2 busybox-w32-4fe76647b356a85810fa3d355d7ad0512be1210c.zip | |
ash: minimise work when a forkshell process is started
There's no need to create or initialise the global data structures
when a forkshell is being started: they'll soon be replaced by
data from the forkshell data block.
Move the call to forkshell_init() to the top of ash_main() along
with some initialisation that's common to forkshell shells and
ordinary shells. Add the minimum necessary initialisation to
forkshell_init().
Diffstat (limited to 'shell/ash.c')
| -rw-r--r-- | shell/ash.c | 46 |
1 files changed, 27 insertions, 19 deletions
diff --git a/shell/ash.c b/shell/ash.c index f57819810..e21131b01 100644 --- a/shell/ash.c +++ b/shell/ash.c | |||
| @@ -391,7 +391,6 @@ enum { | |||
| 391 | 391 | ||
| 392 | static struct forkshell* forkshell_prepare(struct forkshell *fs); | 392 | static struct forkshell* forkshell_prepare(struct forkshell *fs); |
| 393 | static void forkshell_init(const char *idstr); | 393 | static void forkshell_init(const char *idstr); |
| 394 | static void forkshell_child(struct forkshell *fs); | ||
| 395 | static void sticky_free(void *p); | 394 | static void sticky_free(void *p); |
| 396 | # define free(p) sticky_free(p) | 395 | # define free(p) sticky_free(p) |
| 397 | #if !JOBS | 396 | #if !JOBS |
| @@ -15254,12 +15253,27 @@ int ash_main(int argc UNUSED_PARAM, char **argv) | |||
| 15254 | int login_sh; | 15253 | int login_sh; |
| 15255 | #if ENABLE_PLATFORM_MINGW32 | 15254 | #if ENABLE_PLATFORM_MINGW32 |
| 15256 | char *sd; | 15255 | char *sd; |
| 15257 | int is_forkshell; | 15256 | |
| 15257 | INIT_G_memstack(); | ||
| 15258 | |||
| 15259 | /* from init() */ | ||
| 15260 | basepf.next_to_pgetc = basepf.buf = ckmalloc(IBUFSIZ); | ||
| 15261 | basepf.linno = 1; | ||
| 15262 | |||
| 15263 | hSIGINT = CreateEvent(NULL, TRUE, FALSE, NULL); | ||
| 15264 | |||
| 15265 | if (argc == 3 && !strcmp(argv[1], "--fs")) { | ||
| 15266 | forkshell_init(argv[2]); | ||
| 15267 | /* only reached in case of error */ | ||
| 15268 | bb_error_msg_and_die("forkshell failed"); | ||
| 15269 | } | ||
| 15258 | #endif | 15270 | #endif |
| 15259 | 15271 | ||
| 15260 | /* Initialize global data */ | 15272 | /* Initialize global data */ |
| 15261 | INIT_G_misc(); | 15273 | INIT_G_misc(); |
| 15274 | #if !ENABLE_PLATFORM_MINGW32 | ||
| 15262 | INIT_G_memstack(); | 15275 | INIT_G_memstack(); |
| 15276 | #endif | ||
| 15263 | INIT_G_var(); | 15277 | INIT_G_var(); |
| 15264 | #if ENABLE_ASH_ALIAS | 15278 | #if ENABLE_ASH_ALIAS |
| 15265 | INIT_G_alias(); | 15279 | INIT_G_alias(); |
| @@ -15303,27 +15317,13 @@ int ash_main(int argc UNUSED_PARAM, char **argv) | |||
| 15303 | rootpid = getpid(); | 15317 | rootpid = getpid(); |
| 15304 | 15318 | ||
| 15305 | #if ENABLE_PLATFORM_MINGW32 | 15319 | #if ENABLE_PLATFORM_MINGW32 |
| 15306 | /* we will never free this */ | ||
| 15307 | basepf.next_to_pgetc = basepf.buf = ckmalloc(IBUFSIZ); | ||
| 15308 | basepf.linno = 1; | ||
| 15309 | |||
| 15310 | winxp = (argv[1] != NULL && strcmp(argv[1], "-X") == 0); | 15320 | winxp = (argv[1] != NULL && strcmp(argv[1], "-X") == 0); |
| 15311 | is_forkshell = (argc == 3 && !strcmp(argv[1], "--fs")); | ||
| 15312 | if (!is_forkshell) | ||
| 15313 | #endif | 15321 | #endif |
| 15314 | init(); | 15322 | init(); |
| 15315 | setstackmark(&smark); | 15323 | setstackmark(&smark); |
| 15316 | 15324 | ||
| 15317 | #if ENABLE_PLATFORM_MINGW32 | 15325 | #if ENABLE_PLATFORM_MINGW32 |
| 15318 | hSIGINT = CreateEvent(NULL, TRUE, FALSE, NULL); | ||
| 15319 | SetConsoleCtrlHandler(ctrl_handler, TRUE); | 15326 | SetConsoleCtrlHandler(ctrl_handler, TRUE); |
| 15320 | |||
| 15321 | if (is_forkshell) { | ||
| 15322 | forkshell_init(argv[2]); | ||
| 15323 | |||
| 15324 | /* only reached in case of error */ | ||
| 15325 | bb_error_msg_and_die("forkshell failed"); | ||
| 15326 | } | ||
| 15327 | #endif | 15327 | #endif |
| 15328 | 15328 | ||
| 15329 | #if NUM_SCRIPTS > 0 | 15329 | #if NUM_SCRIPTS > 0 |
| @@ -16301,7 +16301,6 @@ forkshell_prepare(struct forkshell *fs) | |||
| 16301 | return new; | 16301 | return new; |
| 16302 | } | 16302 | } |
| 16303 | 16303 | ||
| 16304 | #undef exception_handler | ||
| 16305 | #undef trap | 16304 | #undef trap |
| 16306 | #undef trap_ptr | 16305 | #undef trap_ptr |
| 16307 | static void *sticky_mem_start, *sticky_mem_end; | 16306 | static void *sticky_mem_start, *sticky_mem_end; |
| @@ -16316,6 +16315,7 @@ forkshell_init(const char *idstr) | |||
| 16316 | int i; | 16315 | int i; |
| 16317 | char **ptr; | 16316 | char **ptr; |
| 16318 | char *lrelocate; | 16317 | char *lrelocate; |
| 16318 | struct jmploc jmploc; | ||
| 16319 | 16319 | ||
| 16320 | if (sscanf(idstr, "%p", &map_handle) != 1) | 16320 | if (sscanf(idstr, "%p", &map_handle) != 1) |
| 16321 | return; | 16321 | return; |
| @@ -16348,11 +16348,10 @@ forkshell_init(const char *idstr) | |||
| 16348 | e = e->next; | 16348 | e = e->next; |
| 16349 | } | 16349 | } |
| 16350 | } | 16350 | } |
| 16351 | fs->gmp->exception_handler = ash_ptr_to_globals_misc->exception_handler; | ||
| 16352 | memset(fs->gmp->trap, 0, sizeof(fs->gmp->trap[0])*NSIG); | 16351 | memset(fs->gmp->trap, 0, sizeof(fs->gmp->trap[0])*NSIG); |
| 16353 | /* fs->gmp->trap_ptr = fs->gmp->trap; */ | 16352 | /* fs->gmp->trap_ptr = fs->gmp->trap; */ |
| 16354 | 16353 | ||
| 16355 | /* Switch global variables */ | 16354 | /* Set global variables */ |
| 16356 | gvpp = (struct globals_var **)&ash_ptr_to_globals_var; | 16355 | gvpp = (struct globals_var **)&ash_ptr_to_globals_var; |
| 16357 | *gvpp = fs->gvp; | 16356 | *gvpp = fs->gvp; |
| 16358 | gmpp = (struct globals_misc **)&ash_ptr_to_globals_misc; | 16357 | gmpp = (struct globals_misc **)&ash_ptr_to_globals_misc; |
| @@ -16374,6 +16373,12 @@ forkshell_init(const char *idstr) | |||
| 16374 | 16373 | ||
| 16375 | reinitvar(); | 16374 | reinitvar(); |
| 16376 | 16375 | ||
| 16376 | if (setjmp(jmploc.loc)) { | ||
| 16377 | exitreset(); | ||
| 16378 | exitshell(); | ||
| 16379 | } | ||
| 16380 | exception_handler = &jmploc; | ||
| 16381 | |||
| 16377 | shlvl++; | 16382 | shlvl++; |
| 16378 | if (fs->mode == FORK_BG) { | 16383 | if (fs->mode == FORK_BG) { |
| 16379 | SetConsoleCtrlHandler(NULL, TRUE); | 16384 | SetConsoleCtrlHandler(NULL, TRUE); |
| @@ -16383,6 +16388,9 @@ forkshell_init(const char *idstr) | |||
| 16383 | ash_msg_and_raise_perror("can't open '%s'", bb_dev_null); | 16388 | ash_msg_and_raise_perror("can't open '%s'", bb_dev_null); |
| 16384 | } | 16389 | } |
| 16385 | } | 16390 | } |
| 16391 | else { | ||
| 16392 | SetConsoleCtrlHandler(ctrl_handler, TRUE); | ||
| 16393 | } | ||
| 16386 | forkshell_child(fs); | 16394 | forkshell_child(fs); |
| 16387 | } | 16395 | } |
| 16388 | 16396 | ||
