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:
parent
da463fb007
commit
27c56f1267
111
shell/hush.c
111
shell/hush.c
@ -1344,11 +1344,14 @@ static void hush_exit(int exitcode)
|
||||
/* Prevent recursion:
|
||||
* 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.exiting = 1;
|
||||
builtin_eval(argv);
|
||||
free(argv[1]);
|
||||
/* free(argv[1]); - why bother */
|
||||
}
|
||||
|
||||
#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[sig][0]) {
|
||||
/* 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;
|
||||
builtin_eval(argv);
|
||||
free(argv[1]);
|
||||
G.last_exitcode = save_rcode;
|
||||
} /* else: "" trap, ignoring signal */
|
||||
continue;
|
||||
@ -1439,13 +1444,11 @@ static const char *get_cwd(int force)
|
||||
/*
|
||||
* 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 *cur;
|
||||
int len;
|
||||
|
||||
len = strlen(name);
|
||||
pp = &G.top_var;
|
||||
while ((cur = *pp) != NULL) {
|
||||
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;
|
||||
}
|
||||
|
||||
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)
|
||||
{
|
||||
struct variable **vpp;
|
||||
unsigned len = strlen(name);
|
||||
|
||||
if (G.expanded_assignments) {
|
||||
char **cpp = G.expanded_assignments;
|
||||
int len = strlen(name);
|
||||
while (*cpp) {
|
||||
char *cp = *cpp;
|
||||
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)
|
||||
return strchr((*vpp)->varstr, '=') + 1;
|
||||
return (*vpp)->varstr + len + 1;
|
||||
|
||||
if (strcmp(name, "PPID") == 0)
|
||||
return utoa(G.root_ppid);
|
||||
// bash compat: UID? EUID?
|
||||
#if ENABLE_HUSH_RANDOM_SUPPORT
|
||||
if (strcmp(name, "RANDOM") == 0) {
|
||||
if (strcmp(name, "RANDOM") == 0)
|
||||
return utoa(next_random(&G.random_gen));
|
||||
}
|
||||
#endif
|
||||
return NULL;
|
||||
}
|
||||
@ -1738,9 +1732,7 @@ static struct variable *set_vars_and_save_old(char **strings)
|
||||
|
||||
eq = strchr(*s, '=');
|
||||
if (eq) {
|
||||
*eq = '\0';
|
||||
var_pp = get_ptr_to_local_var(*s);
|
||||
*eq = '=';
|
||||
var_pp = get_ptr_to_local_var(*s, eq - *s);
|
||||
if (var_pp) {
|
||||
/* Remove variable from global linked list */
|
||||
var_p = *var_pp;
|
||||
@ -2500,33 +2492,36 @@ static char **o_finalize_list(o_string *o, int n)
|
||||
list[--n] = NULL;
|
||||
while (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;
|
||||
}
|
||||
|
||||
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 */
|
||||
static void free_pipe(struct pipe *pi)
|
||||
/* Returns pi->next - next pipe in the list */
|
||||
static struct pipe *free_pipe(struct pipe *pi)
|
||||
{
|
||||
char **p;
|
||||
struct command *command;
|
||||
struct redir_struct *r, *rnext;
|
||||
int a, i;
|
||||
struct pipe *next;
|
||||
int i;
|
||||
|
||||
if (pi->stopped_cmds > 0) /* why? */
|
||||
return;
|
||||
debug_printf_clean("run pipe: (pid %d)\n", getpid());
|
||||
debug_printf_clean("free_pipe (pid %d)\n", getpid());
|
||||
for (i = 0; i < pi->num_cmds; i++) {
|
||||
struct command *command;
|
||||
struct redir_struct *r, *rnext;
|
||||
|
||||
command = &pi->cmds[i];
|
||||
debug_printf_clean(" command %d:\n", i);
|
||||
if (command->argv) {
|
||||
for (a = 0, p = command->argv; *p; a++, p++) {
|
||||
debug_printf_clean(" argv[%d] = %s\n", a, *p);
|
||||
if (DEBUG_CLEAN) {
|
||||
int a;
|
||||
char **p;
|
||||
for (a = 0, p = command->argv; *p; a++, p++) {
|
||||
debug_printf_clean(" argv[%d] = %s\n", a, *p);
|
||||
}
|
||||
}
|
||||
free_strings(command->argv);
|
||||
command->argv = NULL;
|
||||
//command->argv = NULL;
|
||||
}
|
||||
/* not "else if": on syntax error, we may have both! */
|
||||
if (command->group) {
|
||||
@ -2534,7 +2529,7 @@ static void free_pipe(struct pipe *pi)
|
||||
command->cmd_type);
|
||||
free_pipe_list(command->group);
|
||||
debug_printf_clean(" end group\n");
|
||||
command->group = NULL;
|
||||
//command->group = NULL;
|
||||
}
|
||||
/* else is crucial here.
|
||||
* If group != NULL, child_func is meaningless */
|
||||
@ -2546,7 +2541,7 @@ static void free_pipe(struct pipe *pi)
|
||||
#endif
|
||||
#if !BB_MMU
|
||||
free(command->group_as_string);
|
||||
command->group_as_string = NULL;
|
||||
//command->group_as_string = NULL;
|
||||
#endif
|
||||
for (r = command->redirects; r; r = rnext) {
|
||||
debug_printf_clean(" redirect %d%s",
|
||||
@ -2555,35 +2550,34 @@ static void free_pipe(struct pipe *pi)
|
||||
if (r->rd_filename) {
|
||||
debug_printf_clean(" fname:'%s'\n", 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);
|
||||
rnext = r->next;
|
||||
free(r);
|
||||
}
|
||||
command->redirects = NULL;
|
||||
//command->redirects = NULL;
|
||||
}
|
||||
free(pi->cmds); /* children are an array, they get freed all at once */
|
||||
pi->cmds = NULL;
|
||||
//pi->cmds = NULL;
|
||||
#if ENABLE_HUSH_JOB
|
||||
free(pi->cmdtext);
|
||||
pi->cmdtext = NULL;
|
||||
//pi->cmdtext = NULL;
|
||||
#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;
|
||||
|
||||
for (pi = head; pi; pi = next) {
|
||||
while (pi) {
|
||||
#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
|
||||
free_pipe(pi);
|
||||
debug_printf_clean("pipe followup code %d\n", pi->followup);
|
||||
next = pi->next;
|
||||
/*pi->next = NULL;*/
|
||||
free(pi);
|
||||
pi = free_pipe(pi);
|
||||
}
|
||||
}
|
||||
|
||||
@ -6184,15 +6178,13 @@ static void remove_bg_job(struct pipe *pi)
|
||||
static void delete_finished_bg_job(struct pipe *pi)
|
||||
{
|
||||
remove_bg_job(pi);
|
||||
pi->stopped_cmds = 0;
|
||||
free_pipe(pi);
|
||||
free(pi);
|
||||
}
|
||||
#endif /* JOB */
|
||||
|
||||
/* Check to see if any processes have exited -- if they
|
||||
* 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 status;
|
||||
@ -7879,13 +7871,16 @@ static void helper_export_local(char **argv, int exp, int lvl)
|
||||
{
|
||||
do {
|
||||
char *name = *argv;
|
||||
char *name_end = strchrnul(name, '=');
|
||||
|
||||
/* So far we do not check that name is valid (TODO?) */
|
||||
|
||||
if (strchr(name, '=') == NULL) {
|
||||
struct variable *var;
|
||||
if (*name_end == '\0') {
|
||||
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? */
|
||||
/* export -n NAME (without =VALUE) */
|
||||
if (var) {
|
||||
|
Loading…
Reference in New Issue
Block a user