diff options
author | Denys Vlasenko <dvlasenk@redhat.com> | 2010-09-07 09:56:34 +0200 |
---|---|---|
committer | Denys Vlasenko <dvlasenk@redhat.com> | 2010-09-07 09:56:34 +0200 |
commit | 27c56f12670295286a881bbb87d506f0a5bfd40e (patch) | |
tree | ab6ad76e938a50b46388d695f273590444f059ff | |
parent | da463fb007dafe6c83c3aaf52358fabc9707ded1 (diff) | |
download | busybox-w32-27c56f12670295286a881bbb87d506f0a5bfd40e.tar.gz busybox-w32-27c56f12670295286a881bbb87d506f0a5bfd40e.tar.bz2 busybox-w32-27c56f12670295286a881bbb87d506f0a5bfd40e.zip |
hush: a few relatively trivial simplifications
function old new delta
helper_export_local 130 135 +5
set_vars_and_save_old 89 85 -4
expand_variables 147 141 -6
get_ptr_to_local_var 77 70 -7
get_local_var_value 171 164 -7
delete_finished_bg_job 31 16 -15
hush_exit 101 84 -17
free_pipe_list 31 12 -19
check_and_run_traps 232 205 -27
free_pipe 205 130 -75
------------------------------------------------------------------------------
(add/remove: 0/0 grow/shrink: 1/9 up/down: 5/-177) Total: -172 bytes
Signed-off-by: Denys Vlasenko <dvlasenk@redhat.com>
-rw-r--r-- | shell/hush.c | 111 |
1 files changed, 53 insertions, 58 deletions
diff --git a/shell/hush.c b/shell/hush.c index 54aee882e..ae2876ac7 100644 --- a/shell/hush.c +++ b/shell/hush.c | |||
@@ -1344,11 +1344,14 @@ static void hush_exit(int exitcode) | |||
1344 | /* Prevent recursion: | 1344 | /* Prevent recursion: |
1345 | * trap "echo Hi; exit" EXIT; exit | 1345 | * trap "echo Hi; exit" EXIT; exit |
1346 | */ | 1346 | */ |
1347 | char *argv[] = { NULL, G.traps[0], NULL }; | 1347 | char *argv[3]; |
1348 | /* argv[0] is unused */ | ||
1349 | argv[1] = G.traps[0]; | ||
1350 | argv[2] = NULL; | ||
1348 | G.traps[0] = NULL; | 1351 | G.traps[0] = NULL; |
1349 | G.exiting = 1; | 1352 | G.exiting = 1; |
1350 | builtin_eval(argv); | 1353 | builtin_eval(argv); |
1351 | free(argv[1]); | 1354 | /* free(argv[1]); - why bother */ |
1352 | } | 1355 | } |
1353 | 1356 | ||
1354 | #if ENABLE_HUSH_JOB | 1357 | #if ENABLE_HUSH_JOB |
@@ -1376,10 +1379,12 @@ static int check_and_run_traps(int sig) | |||
1376 | if (G.traps && G.traps[sig]) { | 1379 | if (G.traps && G.traps[sig]) { |
1377 | if (G.traps[sig][0]) { | 1380 | if (G.traps[sig][0]) { |
1378 | /* We have user-defined handler */ | 1381 | /* We have user-defined handler */ |
1379 | char *argv[] = { NULL, xstrdup(G.traps[sig]), NULL }; | 1382 | char *argv[3]; |
1383 | /* argv[0] is unused */ | ||
1384 | argv[1] = G.traps[sig]; | ||
1385 | argv[2] = NULL; | ||
1380 | save_rcode = G.last_exitcode; | 1386 | save_rcode = G.last_exitcode; |
1381 | builtin_eval(argv); | 1387 | builtin_eval(argv); |
1382 | free(argv[1]); | ||
1383 | G.last_exitcode = save_rcode; | 1388 | G.last_exitcode = save_rcode; |
1384 | } /* else: "" trap, ignoring signal */ | 1389 | } /* else: "" trap, ignoring signal */ |
1385 | continue; | 1390 | continue; |
@@ -1439,13 +1444,11 @@ static const char *get_cwd(int force) | |||
1439 | /* | 1444 | /* |
1440 | * Shell and environment variable support | 1445 | * Shell and environment variable support |
1441 | */ | 1446 | */ |
1442 | static struct variable **get_ptr_to_local_var(const char *name) | 1447 | static struct variable **get_ptr_to_local_var(const char *name, unsigned len) |
1443 | { | 1448 | { |
1444 | struct variable **pp; | 1449 | struct variable **pp; |
1445 | struct variable *cur; | 1450 | struct variable *cur; |
1446 | int len; | ||
1447 | 1451 | ||
1448 | len = strlen(name); | ||
1449 | pp = &G.top_var; | 1452 | pp = &G.top_var; |
1450 | while ((cur = *pp) != NULL) { | 1453 | while ((cur = *pp) != NULL) { |
1451 | if (strncmp(cur->varstr, name, len) == 0 && cur->varstr[len] == '=') | 1454 | if (strncmp(cur->varstr, name, len) == 0 && cur->varstr[len] == '=') |
@@ -1455,21 +1458,13 @@ static struct variable **get_ptr_to_local_var(const char *name) | |||
1455 | return NULL; | 1458 | return NULL; |
1456 | } | 1459 | } |
1457 | 1460 | ||
1458 | static struct variable *get_local_var(const char *name) | ||
1459 | { | ||
1460 | struct variable **pp = get_ptr_to_local_var(name); | ||
1461 | if (pp) | ||
1462 | return *pp; | ||
1463 | return NULL; | ||
1464 | } | ||
1465 | |||
1466 | static const char* FAST_FUNC get_local_var_value(const char *name) | 1461 | static const char* FAST_FUNC get_local_var_value(const char *name) |
1467 | { | 1462 | { |
1468 | struct variable **vpp; | 1463 | struct variable **vpp; |
1464 | unsigned len = strlen(name); | ||
1469 | 1465 | ||
1470 | if (G.expanded_assignments) { | 1466 | if (G.expanded_assignments) { |
1471 | char **cpp = G.expanded_assignments; | 1467 | char **cpp = G.expanded_assignments; |
1472 | int len = strlen(name); | ||
1473 | while (*cpp) { | 1468 | while (*cpp) { |
1474 | char *cp = *cpp; | 1469 | char *cp = *cpp; |
1475 | if (strncmp(cp, name, len) == 0 && cp[len] == '=') | 1470 | if (strncmp(cp, name, len) == 0 && cp[len] == '=') |
@@ -1478,17 +1473,16 @@ static const char* FAST_FUNC get_local_var_value(const char *name) | |||
1478 | } | 1473 | } |
1479 | } | 1474 | } |
1480 | 1475 | ||
1481 | vpp = get_ptr_to_local_var(name); | 1476 | vpp = get_ptr_to_local_var(name, len); |
1482 | if (vpp) | 1477 | if (vpp) |
1483 | return strchr((*vpp)->varstr, '=') + 1; | 1478 | return (*vpp)->varstr + len + 1; |
1484 | 1479 | ||
1485 | if (strcmp(name, "PPID") == 0) | 1480 | if (strcmp(name, "PPID") == 0) |
1486 | return utoa(G.root_ppid); | 1481 | return utoa(G.root_ppid); |
1487 | // bash compat: UID? EUID? | 1482 | // bash compat: UID? EUID? |
1488 | #if ENABLE_HUSH_RANDOM_SUPPORT | 1483 | #if ENABLE_HUSH_RANDOM_SUPPORT |
1489 | if (strcmp(name, "RANDOM") == 0) { | 1484 | if (strcmp(name, "RANDOM") == 0) |
1490 | return utoa(next_random(&G.random_gen)); | 1485 | return utoa(next_random(&G.random_gen)); |
1491 | } | ||
1492 | #endif | 1486 | #endif |
1493 | return NULL; | 1487 | return NULL; |
1494 | } | 1488 | } |
@@ -1738,9 +1732,7 @@ static struct variable *set_vars_and_save_old(char **strings) | |||
1738 | 1732 | ||
1739 | eq = strchr(*s, '='); | 1733 | eq = strchr(*s, '='); |
1740 | if (eq) { | 1734 | if (eq) { |
1741 | *eq = '\0'; | 1735 | var_pp = get_ptr_to_local_var(*s, eq - *s); |
1742 | var_pp = get_ptr_to_local_var(*s); | ||
1743 | *eq = '='; | ||
1744 | if (var_pp) { | 1736 | if (var_pp) { |
1745 | /* Remove variable from global linked list */ | 1737 | /* Remove variable from global linked list */ |
1746 | var_p = *var_pp; | 1738 | var_p = *var_pp; |
@@ -2500,33 +2492,36 @@ static char **o_finalize_list(o_string *o, int n) | |||
2500 | list[--n] = NULL; | 2492 | list[--n] = NULL; |
2501 | while (n) { | 2493 | while (n) { |
2502 | n--; | 2494 | n--; |
2503 | list[n] = o->data + (int)(ptrdiff_t)list[n] + string_start; | 2495 | list[n] = o->data + (int)(uintptr_t)list[n] + string_start; |
2504 | } | 2496 | } |
2505 | return list; | 2497 | return list; |
2506 | } | 2498 | } |
2507 | 2499 | ||
2508 | static void free_pipe_list(struct pipe *head); | 2500 | static void free_pipe_list(struct pipe *pi); |
2509 | 2501 | ||
2510 | /* Return code is the exit status of the pipe */ | 2502 | /* Returns pi->next - next pipe in the list */ |
2511 | static void free_pipe(struct pipe *pi) | 2503 | static struct pipe *free_pipe(struct pipe *pi) |
2512 | { | 2504 | { |
2513 | char **p; | 2505 | struct pipe *next; |
2514 | struct command *command; | 2506 | int i; |
2515 | struct redir_struct *r, *rnext; | ||
2516 | int a, i; | ||
2517 | 2507 | ||
2518 | if (pi->stopped_cmds > 0) /* why? */ | 2508 | debug_printf_clean("free_pipe (pid %d)\n", getpid()); |
2519 | return; | ||
2520 | debug_printf_clean("run pipe: (pid %d)\n", getpid()); | ||
2521 | for (i = 0; i < pi->num_cmds; i++) { | 2509 | for (i = 0; i < pi->num_cmds; i++) { |
2510 | struct command *command; | ||
2511 | struct redir_struct *r, *rnext; | ||
2512 | |||
2522 | command = &pi->cmds[i]; | 2513 | command = &pi->cmds[i]; |
2523 | debug_printf_clean(" command %d:\n", i); | 2514 | debug_printf_clean(" command %d:\n", i); |
2524 | if (command->argv) { | 2515 | if (command->argv) { |
2525 | for (a = 0, p = command->argv; *p; a++, p++) { | 2516 | if (DEBUG_CLEAN) { |
2526 | debug_printf_clean(" argv[%d] = %s\n", a, *p); | 2517 | int a; |
2518 | char **p; | ||
2519 | for (a = 0, p = command->argv; *p; a++, p++) { | ||
2520 | debug_printf_clean(" argv[%d] = %s\n", a, *p); | ||
2521 | } | ||
2527 | } | 2522 | } |
2528 | free_strings(command->argv); | 2523 | free_strings(command->argv); |
2529 | command->argv = NULL; | 2524 | //command->argv = NULL; |
2530 | } | 2525 | } |
2531 | /* not "else if": on syntax error, we may have both! */ | 2526 | /* not "else if": on syntax error, we may have both! */ |
2532 | if (command->group) { | 2527 | if (command->group) { |
@@ -2534,7 +2529,7 @@ static void free_pipe(struct pipe *pi) | |||
2534 | command->cmd_type); | 2529 | command->cmd_type); |
2535 | free_pipe_list(command->group); | 2530 | free_pipe_list(command->group); |
2536 | debug_printf_clean(" end group\n"); | 2531 | debug_printf_clean(" end group\n"); |
2537 | command->group = NULL; | 2532 | //command->group = NULL; |
2538 | } | 2533 | } |
2539 | /* else is crucial here. | 2534 | /* else is crucial here. |
2540 | * If group != NULL, child_func is meaningless */ | 2535 | * If group != NULL, child_func is meaningless */ |
@@ -2546,7 +2541,7 @@ static void free_pipe(struct pipe *pi) | |||
2546 | #endif | 2541 | #endif |
2547 | #if !BB_MMU | 2542 | #if !BB_MMU |
2548 | free(command->group_as_string); | 2543 | free(command->group_as_string); |
2549 | command->group_as_string = NULL; | 2544 | //command->group_as_string = NULL; |
2550 | #endif | 2545 | #endif |
2551 | for (r = command->redirects; r; r = rnext) { | 2546 | for (r = command->redirects; r; r = rnext) { |
2552 | debug_printf_clean(" redirect %d%s", | 2547 | debug_printf_clean(" redirect %d%s", |
@@ -2555,35 +2550,34 @@ static void free_pipe(struct pipe *pi) | |||
2555 | if (r->rd_filename) { | 2550 | if (r->rd_filename) { |
2556 | debug_printf_clean(" fname:'%s'\n", r->rd_filename); | 2551 | debug_printf_clean(" fname:'%s'\n", r->rd_filename); |
2557 | free(r->rd_filename); | 2552 | free(r->rd_filename); |
2558 | r->rd_filename = NULL; | 2553 | //r->rd_filename = NULL; |
2559 | } | 2554 | } |
2560 | debug_printf_clean(" rd_dup:%d\n", r->rd_dup); | 2555 | debug_printf_clean(" rd_dup:%d\n", r->rd_dup); |
2561 | rnext = r->next; | 2556 | rnext = r->next; |
2562 | free(r); | 2557 | free(r); |
2563 | } | 2558 | } |
2564 | command->redirects = NULL; | 2559 | //command->redirects = NULL; |
2565 | } | 2560 | } |
2566 | free(pi->cmds); /* children are an array, they get freed all at once */ | 2561 | free(pi->cmds); /* children are an array, they get freed all at once */ |
2567 | pi->cmds = NULL; | 2562 | //pi->cmds = NULL; |
2568 | #if ENABLE_HUSH_JOB | 2563 | #if ENABLE_HUSH_JOB |
2569 | free(pi->cmdtext); | 2564 | free(pi->cmdtext); |
2570 | pi->cmdtext = NULL; | 2565 | //pi->cmdtext = NULL; |
2571 | #endif | 2566 | #endif |
2567 | |||
2568 | next = pi->next; | ||
2569 | free(pi); | ||
2570 | return next; | ||
2572 | } | 2571 | } |
2573 | 2572 | ||
2574 | static void free_pipe_list(struct pipe *head) | 2573 | static void free_pipe_list(struct pipe *pi) |
2575 | { | 2574 | { |
2576 | struct pipe *pi, *next; | 2575 | while (pi) { |
2577 | |||
2578 | for (pi = head; pi; pi = next) { | ||
2579 | #if HAS_KEYWORDS | 2576 | #if HAS_KEYWORDS |
2580 | debug_printf_clean(" pipe reserved word %d\n", pi->res_word); | 2577 | debug_printf_clean("pipe reserved word %d\n", pi->res_word); |
2581 | #endif | 2578 | #endif |
2582 | free_pipe(pi); | ||
2583 | debug_printf_clean("pipe followup code %d\n", pi->followup); | 2579 | debug_printf_clean("pipe followup code %d\n", pi->followup); |
2584 | next = pi->next; | 2580 | pi = free_pipe(pi); |
2585 | /*pi->next = NULL;*/ | ||
2586 | free(pi); | ||
2587 | } | 2581 | } |
2588 | } | 2582 | } |
2589 | 2583 | ||
@@ -6184,15 +6178,13 @@ static void remove_bg_job(struct pipe *pi) | |||
6184 | static void delete_finished_bg_job(struct pipe *pi) | 6178 | static void delete_finished_bg_job(struct pipe *pi) |
6185 | { | 6179 | { |
6186 | remove_bg_job(pi); | 6180 | remove_bg_job(pi); |
6187 | pi->stopped_cmds = 0; | ||
6188 | free_pipe(pi); | 6181 | free_pipe(pi); |
6189 | free(pi); | ||
6190 | } | 6182 | } |
6191 | #endif /* JOB */ | 6183 | #endif /* JOB */ |
6192 | 6184 | ||
6193 | /* Check to see if any processes have exited -- if they | 6185 | /* Check to see if any processes have exited -- if they |
6194 | * have, figure out why and see if a job has completed */ | 6186 | * have, figure out why and see if a job has completed */ |
6195 | static int checkjobs(struct pipe* fg_pipe) | 6187 | static int checkjobs(struct pipe *fg_pipe) |
6196 | { | 6188 | { |
6197 | int attributes; | 6189 | int attributes; |
6198 | int status; | 6190 | int status; |
@@ -7879,13 +7871,16 @@ static void helper_export_local(char **argv, int exp, int lvl) | |||
7879 | { | 7871 | { |
7880 | do { | 7872 | do { |
7881 | char *name = *argv; | 7873 | char *name = *argv; |
7874 | char *name_end = strchrnul(name, '='); | ||
7882 | 7875 | ||
7883 | /* So far we do not check that name is valid (TODO?) */ | 7876 | /* So far we do not check that name is valid (TODO?) */ |
7884 | 7877 | ||
7885 | if (strchr(name, '=') == NULL) { | 7878 | if (*name_end == '\0') { |
7886 | struct variable *var; | 7879 | struct variable *var, **vpp; |
7880 | |||
7881 | vpp = get_ptr_to_local_var(name, name_end - name); | ||
7882 | var = vpp ? *vpp : NULL; | ||
7887 | 7883 | ||
7888 | var = get_local_var(name); | ||
7889 | if (exp == -1) { /* unexporting? */ | 7884 | if (exp == -1) { /* unexporting? */ |
7890 | /* export -n NAME (without =VALUE) */ | 7885 | /* export -n NAME (without =VALUE) */ |
7891 | if (var) { | 7886 | if (var) { |