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>
This commit is contained in:
Denys Vlasenko 2010-09-07 09:56:34 +02:00
parent da463fb007
commit 27c56f1267

@ -1344,11 +1344,14 @@ static void hush_exit(int exitcode)
/* Prevent recursion: /* Prevent recursion:
* trap "echo Hi; exit" EXIT; exit * trap "echo Hi; exit" EXIT; exit
*/ */
char *argv[] = { NULL, G.traps[0], NULL }; char *argv[3];
/* argv[0] is unused */
argv[1] = G.traps[0];
argv[2] = NULL;
G.traps[0] = NULL; G.traps[0] = NULL;
G.exiting = 1; G.exiting = 1;
builtin_eval(argv); builtin_eval(argv);
free(argv[1]); /* free(argv[1]); - why bother */
} }
#if ENABLE_HUSH_JOB #if ENABLE_HUSH_JOB
@ -1376,10 +1379,12 @@ static int check_and_run_traps(int sig)
if (G.traps && G.traps[sig]) { if (G.traps && G.traps[sig]) {
if (G.traps[sig][0]) { if (G.traps[sig][0]) {
/* We have user-defined handler */ /* We have user-defined handler */
char *argv[] = { NULL, xstrdup(G.traps[sig]), NULL }; char *argv[3];
/* argv[0] is unused */
argv[1] = G.traps[sig];
argv[2] = NULL;
save_rcode = G.last_exitcode; save_rcode = G.last_exitcode;
builtin_eval(argv); builtin_eval(argv);
free(argv[1]);
G.last_exitcode = save_rcode; G.last_exitcode = save_rcode;
} /* else: "" trap, ignoring signal */ } /* else: "" trap, ignoring signal */
continue; continue;
@ -1439,13 +1444,11 @@ static const char *get_cwd(int force)
/* /*
* Shell and environment variable support * Shell and environment variable support
*/ */
static struct variable **get_ptr_to_local_var(const char *name) static struct variable **get_ptr_to_local_var(const char *name, unsigned len)
{ {
struct variable **pp; struct variable **pp;
struct variable *cur; struct variable *cur;
int len;
len = strlen(name);
pp = &G.top_var; pp = &G.top_var;
while ((cur = *pp) != NULL) { while ((cur = *pp) != NULL) {
if (strncmp(cur->varstr, name, len) == 0 && cur->varstr[len] == '=') 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)
return NULL; return NULL;
} }
static struct variable *get_local_var(const char *name)
{
struct variable **pp = get_ptr_to_local_var(name);
if (pp)
return *pp;
return NULL;
}
static const char* FAST_FUNC get_local_var_value(const char *name) static const char* FAST_FUNC get_local_var_value(const char *name)
{ {
struct variable **vpp; struct variable **vpp;
unsigned len = strlen(name);
if (G.expanded_assignments) { if (G.expanded_assignments) {
char **cpp = G.expanded_assignments; char **cpp = G.expanded_assignments;
int len = strlen(name);
while (*cpp) { while (*cpp) {
char *cp = *cpp; char *cp = *cpp;
if (strncmp(cp, name, len) == 0 && cp[len] == '=') if (strncmp(cp, name, len) == 0 && cp[len] == '=')
@ -1478,17 +1473,16 @@ static const char* FAST_FUNC get_local_var_value(const char *name)
} }
} }
vpp = get_ptr_to_local_var(name); vpp = get_ptr_to_local_var(name, len);
if (vpp) if (vpp)
return strchr((*vpp)->varstr, '=') + 1; return (*vpp)->varstr + len + 1;
if (strcmp(name, "PPID") == 0) if (strcmp(name, "PPID") == 0)
return utoa(G.root_ppid); return utoa(G.root_ppid);
// bash compat: UID? EUID? // bash compat: UID? EUID?
#if ENABLE_HUSH_RANDOM_SUPPORT #if ENABLE_HUSH_RANDOM_SUPPORT
if (strcmp(name, "RANDOM") == 0) { if (strcmp(name, "RANDOM") == 0)
return utoa(next_random(&G.random_gen)); return utoa(next_random(&G.random_gen));
}
#endif #endif
return NULL; return NULL;
} }
@ -1738,9 +1732,7 @@ static struct variable *set_vars_and_save_old(char **strings)
eq = strchr(*s, '='); eq = strchr(*s, '=');
if (eq) { if (eq) {
*eq = '\0'; var_pp = get_ptr_to_local_var(*s, eq - *s);
var_pp = get_ptr_to_local_var(*s);
*eq = '=';
if (var_pp) { if (var_pp) {
/* Remove variable from global linked list */ /* Remove variable from global linked list */
var_p = *var_pp; var_p = *var_pp;
@ -2500,33 +2492,36 @@ static char **o_finalize_list(o_string *o, int n)
list[--n] = NULL; list[--n] = NULL;
while (n) { while (n) {
n--; n--;
list[n] = o->data + (int)(ptrdiff_t)list[n] + string_start; list[n] = o->data + (int)(uintptr_t)list[n] + string_start;
} }
return list; return list;
} }
static void free_pipe_list(struct pipe *head); static void free_pipe_list(struct pipe *pi);
/* Return code is the exit status of the pipe */ /* Returns pi->next - next pipe in the list */
static void free_pipe(struct pipe *pi) static struct pipe *free_pipe(struct pipe *pi)
{ {
char **p; struct pipe *next;
int i;
debug_printf_clean("free_pipe (pid %d)\n", getpid());
for (i = 0; i < pi->num_cmds; i++) {
struct command *command; struct command *command;
struct redir_struct *r, *rnext; struct redir_struct *r, *rnext;
int a, i;
if (pi->stopped_cmds > 0) /* why? */
return;
debug_printf_clean("run pipe: (pid %d)\n", getpid());
for (i = 0; i < pi->num_cmds; i++) {
command = &pi->cmds[i]; command = &pi->cmds[i];
debug_printf_clean(" command %d:\n", i); debug_printf_clean(" command %d:\n", i);
if (command->argv) { if (command->argv) {
if (DEBUG_CLEAN) {
int a;
char **p;
for (a = 0, p = command->argv; *p; a++, p++) { for (a = 0, p = command->argv; *p; a++, p++) {
debug_printf_clean(" argv[%d] = %s\n", a, *p); debug_printf_clean(" argv[%d] = %s\n", a, *p);
} }
}
free_strings(command->argv); free_strings(command->argv);
command->argv = NULL; //command->argv = NULL;
} }
/* not "else if": on syntax error, we may have both! */ /* not "else if": on syntax error, we may have both! */
if (command->group) { if (command->group) {
@ -2534,7 +2529,7 @@ static void free_pipe(struct pipe *pi)
command->cmd_type); command->cmd_type);
free_pipe_list(command->group); free_pipe_list(command->group);
debug_printf_clean(" end group\n"); debug_printf_clean(" end group\n");
command->group = NULL; //command->group = NULL;
} }
/* else is crucial here. /* else is crucial here.
* If group != NULL, child_func is meaningless */ * If group != NULL, child_func is meaningless */
@ -2546,7 +2541,7 @@ static void free_pipe(struct pipe *pi)
#endif #endif
#if !BB_MMU #if !BB_MMU
free(command->group_as_string); free(command->group_as_string);
command->group_as_string = NULL; //command->group_as_string = NULL;
#endif #endif
for (r = command->redirects; r; r = rnext) { for (r = command->redirects; r; r = rnext) {
debug_printf_clean(" redirect %d%s", debug_printf_clean(" redirect %d%s",
@ -2555,35 +2550,34 @@ static void free_pipe(struct pipe *pi)
if (r->rd_filename) { if (r->rd_filename) {
debug_printf_clean(" fname:'%s'\n", r->rd_filename); debug_printf_clean(" fname:'%s'\n", r->rd_filename);
free(r->rd_filename); free(r->rd_filename);
r->rd_filename = NULL; //r->rd_filename = NULL;
} }
debug_printf_clean(" rd_dup:%d\n", r->rd_dup); debug_printf_clean(" rd_dup:%d\n", r->rd_dup);
rnext = r->next; rnext = r->next;
free(r); free(r);
} }
command->redirects = NULL; //command->redirects = NULL;
} }
free(pi->cmds); /* children are an array, they get freed all at once */ free(pi->cmds); /* children are an array, they get freed all at once */
pi->cmds = NULL; //pi->cmds = NULL;
#if ENABLE_HUSH_JOB #if ENABLE_HUSH_JOB
free(pi->cmdtext); free(pi->cmdtext);
pi->cmdtext = NULL; //pi->cmdtext = NULL;
#endif #endif
next = pi->next;
free(pi);
return next;
} }
static void free_pipe_list(struct pipe *head) static void free_pipe_list(struct pipe *pi)
{ {
struct pipe *pi, *next; while (pi) {
for (pi = head; pi; pi = next) {
#if HAS_KEYWORDS #if HAS_KEYWORDS
debug_printf_clean(" pipe reserved word %d\n", pi->res_word); debug_printf_clean("pipe reserved word %d\n", pi->res_word);
#endif #endif
free_pipe(pi);
debug_printf_clean("pipe followup code %d\n", pi->followup); debug_printf_clean("pipe followup code %d\n", pi->followup);
next = pi->next; pi = free_pipe(pi);
/*pi->next = NULL;*/
free(pi);
} }
} }
@ -6184,15 +6178,13 @@ static void remove_bg_job(struct pipe *pi)
static void delete_finished_bg_job(struct pipe *pi) static void delete_finished_bg_job(struct pipe *pi)
{ {
remove_bg_job(pi); remove_bg_job(pi);
pi->stopped_cmds = 0;
free_pipe(pi); free_pipe(pi);
free(pi);
} }
#endif /* JOB */ #endif /* JOB */
/* Check to see if any processes have exited -- if they /* Check to see if any processes have exited -- if they
* have, figure out why and see if a job has completed */ * have, figure out why and see if a job has completed */
static int checkjobs(struct pipe* fg_pipe) static int checkjobs(struct pipe *fg_pipe)
{ {
int attributes; int attributes;
int status; int status;
@ -7879,13 +7871,16 @@ static void helper_export_local(char **argv, int exp, int lvl)
{ {
do { do {
char *name = *argv; char *name = *argv;
char *name_end = strchrnul(name, '=');
/* So far we do not check that name is valid (TODO?) */ /* So far we do not check that name is valid (TODO?) */
if (strchr(name, '=') == NULL) { if (*name_end == '\0') {
struct variable *var; struct variable *var, **vpp;
vpp = get_ptr_to_local_var(name, name_end - name);
var = vpp ? *vpp : NULL;
var = get_local_var(name);
if (exp == -1) { /* unexporting? */ if (exp == -1) { /* unexporting? */
/* export -n NAME (without =VALUE) */ /* export -n NAME (without =VALUE) */
if (var) { if (var) {