hush: small code shrink; style fixes
This commit is contained in:
parent
f6250a3bee
commit
5f786c24e4
@ -86,6 +86,7 @@ set fd# 255 foreground process group to first child's one
|
|||||||
block only CHLD
|
block only CHLD
|
||||||
block only CHLD
|
block only CHLD
|
||||||
block only CHLD
|
block only CHLD
|
||||||
|
/* note: because shell is not in foreground now, e.g. Ctrl-C will send INT to children only! */
|
||||||
wait4 for children to die or stop - first child exits
|
wait4 for children to die or stop - first child exits
|
||||||
wait4 for children to die or stop - second child exits
|
wait4 for children to die or stop - second child exits
|
||||||
block CHLD TSTP TTIN TTOU
|
block CHLD TSTP TTIN TTOU
|
||||||
|
108
shell/hush.c
108
shell/hush.c
@ -140,19 +140,21 @@ typedef enum {
|
|||||||
RES_IN = 12,
|
RES_IN = 12,
|
||||||
RES_SNTX = 13
|
RES_SNTX = 13
|
||||||
} reserved_style;
|
} reserved_style;
|
||||||
#define FLAG_END (1<<RES_NONE)
|
enum {
|
||||||
#define FLAG_IF (1<<RES_IF)
|
FLAG_END = (1 << RES_NONE ),
|
||||||
#define FLAG_THEN (1<<RES_THEN)
|
FLAG_IF = (1 << RES_IF ),
|
||||||
#define FLAG_ELIF (1<<RES_ELIF)
|
FLAG_THEN = (1 << RES_THEN ),
|
||||||
#define FLAG_ELSE (1<<RES_ELSE)
|
FLAG_ELIF = (1 << RES_ELIF ),
|
||||||
#define FLAG_FI (1<<RES_FI)
|
FLAG_ELSE = (1 << RES_ELSE ),
|
||||||
#define FLAG_FOR (1<<RES_FOR)
|
FLAG_FI = (1 << RES_FI ),
|
||||||
#define FLAG_WHILE (1<<RES_WHILE)
|
FLAG_FOR = (1 << RES_FOR ),
|
||||||
#define FLAG_UNTIL (1<<RES_UNTIL)
|
FLAG_WHILE = (1 << RES_WHILE),
|
||||||
#define FLAG_DO (1<<RES_DO)
|
FLAG_UNTIL = (1 << RES_UNTIL),
|
||||||
#define FLAG_DONE (1<<RES_DONE)
|
FLAG_DO = (1 << RES_DO ),
|
||||||
#define FLAG_IN (1<<RES_IN)
|
FLAG_DONE = (1 << RES_DONE ),
|
||||||
#define FLAG_START (1<<RES_XXXX)
|
FLAG_IN = (1 << RES_IN ),
|
||||||
|
FLAG_START = (1 << RES_XXXX ),
|
||||||
|
};
|
||||||
|
|
||||||
/* This holds pointers to the various results of parsing */
|
/* This holds pointers to the various results of parsing */
|
||||||
struct p_context {
|
struct p_context {
|
||||||
@ -468,6 +470,7 @@ static int builtin_cd(struct child_prog *child)
|
|||||||
/* built-in 'env' handler */
|
/* built-in 'env' handler */
|
||||||
static int builtin_env(struct child_prog *dummy ATTRIBUTE_UNUSED)
|
static int builtin_env(struct child_prog *dummy ATTRIBUTE_UNUSED)
|
||||||
{
|
{
|
||||||
|
/* TODO: call env applet's code instead */
|
||||||
char **e = environ;
|
char **e = environ;
|
||||||
if (e == NULL)
|
if (e == NULL)
|
||||||
return EXIT_FAILURE;
|
return EXIT_FAILURE;
|
||||||
@ -490,9 +493,13 @@ static int builtin_exec(struct child_prog *child)
|
|||||||
/* built-in 'exit' handler */
|
/* built-in 'exit' handler */
|
||||||
static int builtin_exit(struct child_prog *child)
|
static int builtin_exit(struct child_prog *child)
|
||||||
{
|
{
|
||||||
|
/* bash prints "exit\n" here, then: */
|
||||||
if (child->argv[1] == NULL)
|
if (child->argv[1] == NULL)
|
||||||
exit(last_return_code);
|
exit(last_return_code);
|
||||||
exit(atoi(child->argv[1]));
|
/* mimic bash: exit 123abc == exit 255 + error msg */
|
||||||
|
xfunc_error_retval = 255;
|
||||||
|
/* bash: exit -2 == exit 254, no error msg */
|
||||||
|
exit(xatoi(child->argv[1]));
|
||||||
}
|
}
|
||||||
|
|
||||||
/* built-in 'export VAR=value' handler */
|
/* built-in 'export VAR=value' handler */
|
||||||
@ -1217,19 +1224,18 @@ static int checkjobs(struct pipe* fg_pipe)
|
|||||||
|
|
||||||
for (pi = job_list; pi; pi = pi->next) {
|
for (pi = job_list; pi; pi = pi->next) {
|
||||||
prognum = 0;
|
prognum = 0;
|
||||||
while (prognum < pi->num_progs && pi->progs[prognum].pid != childpid) {
|
while (prognum < pi->num_progs) {
|
||||||
|
if (pi->progs[prognum].pid == childpid)
|
||||||
|
goto found_pi_and_prognum;
|
||||||
prognum++;
|
prognum++;
|
||||||
}
|
}
|
||||||
if (prognum < pi->num_progs)
|
|
||||||
break;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
if (pi == NULL) {
|
/* Happens when shell is used as init process (init=/bin/sh) */
|
||||||
debug_printf("checkjobs: pid %d was not in our list!\n",
|
debug_printf("checkjobs: pid %d was not in our list!\n", childpid);
|
||||||
childpid);
|
continue;
|
||||||
continue;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
found_pi_and_prognum:
|
||||||
if (WIFEXITED(status) || WIFSIGNALED(status)) {
|
if (WIFEXITED(status) || WIFSIGNALED(status)) {
|
||||||
/* child exited */
|
/* child exited */
|
||||||
pi->running_progs--;
|
pi->running_progs--;
|
||||||
@ -1539,13 +1545,12 @@ static int run_list_real(struct pipe *pi)
|
|||||||
pi->progs->argv[0] = save_name;
|
pi->progs->argv[0] = save_name;
|
||||||
pi->progs->glob_result.gl_pathv[0] = pi->progs->argv[0];
|
pi->progs->glob_result.gl_pathv[0] = pi->progs->argv[0];
|
||||||
continue;
|
continue;
|
||||||
} else {
|
|
||||||
/* insert new value from list for variable */
|
|
||||||
if (pi->progs->argv[0])
|
|
||||||
free(pi->progs->argv[0]);
|
|
||||||
pi->progs->argv[0] = *list++;
|
|
||||||
pi->progs->glob_result.gl_pathv[0] = pi->progs->argv[0];
|
|
||||||
}
|
}
|
||||||
|
/* insert new value from list for variable */
|
||||||
|
if (pi->progs->argv[0])
|
||||||
|
free(pi->progs->argv[0]);
|
||||||
|
pi->progs->argv[0] = *list++;
|
||||||
|
pi->progs->glob_result.gl_pathv[0] = pi->progs->argv[0];
|
||||||
}
|
}
|
||||||
if (rmode == RES_IN)
|
if (rmode == RES_IN)
|
||||||
continue;
|
continue;
|
||||||
@ -1553,7 +1558,7 @@ static int run_list_real(struct pipe *pi)
|
|||||||
if (!flag_rep)
|
if (!flag_rep)
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
if ((rmode == RES_DONE)) {
|
if (rmode == RES_DONE) {
|
||||||
if (flag_rep) {
|
if (flag_rep) {
|
||||||
flag_restore = 1;
|
flag_restore = 1;
|
||||||
} else {
|
} else {
|
||||||
@ -1590,7 +1595,7 @@ static int run_list_real(struct pipe *pi)
|
|||||||
}
|
}
|
||||||
last_return_code = rcode;
|
last_return_code = rcode;
|
||||||
pi->num_progs = save_num_progs; /* restore number of programs */
|
pi->num_progs = save_num_progs; /* restore number of programs */
|
||||||
if ( rmode == RES_IF || rmode == RES_ELIF )
|
if (rmode == RES_IF || rmode == RES_ELIF)
|
||||||
next_if_code = rcode; /* can be overwritten a number of times */
|
next_if_code = rcode; /* can be overwritten a number of times */
|
||||||
if (rmode == RES_WHILE)
|
if (rmode == RES_WHILE)
|
||||||
flag_rep = !last_return_code;
|
flag_rep = !last_return_code;
|
||||||
@ -1663,7 +1668,7 @@ static int free_pipe_list(struct pipe *head, int indent)
|
|||||||
rcode = free_pipe(pi, indent);
|
rcode = free_pipe(pi, indent);
|
||||||
final_printf("%s pipe followup code %d\n", indenter(indent), pi->followup);
|
final_printf("%s pipe followup code %d\n", indenter(indent), pi->followup);
|
||||||
next = pi->next;
|
next = pi->next;
|
||||||
pi->next = NULL;
|
/*pi->next = NULL;*/
|
||||||
free(pi);
|
free(pi);
|
||||||
}
|
}
|
||||||
return rcode;
|
return rcode;
|
||||||
@ -1700,7 +1705,8 @@ static int globhack(const char *src, int flags, glob_t *pglob)
|
|||||||
cnt++;
|
cnt++;
|
||||||
}
|
}
|
||||||
dest = malloc(cnt);
|
dest = malloc(cnt);
|
||||||
if (!dest) return GLOB_NOSPACE;
|
if (!dest)
|
||||||
|
return GLOB_NOSPACE;
|
||||||
if (!(flags & GLOB_APPEND)) {
|
if (!(flags & GLOB_APPEND)) {
|
||||||
pglob->gl_pathv = NULL;
|
pglob->gl_pathv = NULL;
|
||||||
pglob->gl_pathc = 0;
|
pglob->gl_pathc = 0;
|
||||||
@ -1709,7 +1715,8 @@ static int globhack(const char *src, int flags, glob_t *pglob)
|
|||||||
}
|
}
|
||||||
pathc = ++pglob->gl_pathc;
|
pathc = ++pglob->gl_pathc;
|
||||||
pglob->gl_pathv = realloc(pglob->gl_pathv, (pathc+1)*sizeof(*pglob->gl_pathv));
|
pglob->gl_pathv = realloc(pglob->gl_pathv, (pathc+1)*sizeof(*pglob->gl_pathv));
|
||||||
if (pglob->gl_pathv == NULL) return GLOB_NOSPACE;
|
if (pglob->gl_pathv == NULL)
|
||||||
|
return GLOB_NOSPACE;
|
||||||
pglob->gl_pathv[pathc-1] = dest;
|
pglob->gl_pathv[pathc-1] = dest;
|
||||||
pglob->gl_pathv[pathc] = NULL;
|
pglob->gl_pathv[pathc] = NULL;
|
||||||
for (s = src; s && *s; s++, dest++) {
|
for (s = src; s && *s; s++, dest++) {
|
||||||
@ -1857,15 +1864,12 @@ static int set_local_var(const char *s, int flg_export)
|
|||||||
|
|
||||||
static void unset_local_var(const char *name)
|
static void unset_local_var(const char *name)
|
||||||
{
|
{
|
||||||
struct variables *cur;
|
struct variables *cur, *next;
|
||||||
|
|
||||||
if (name) {
|
if (!name)
|
||||||
for (cur = top_vars; cur; cur = cur->next) {
|
return;
|
||||||
if (strcmp(cur->name, name) == 0)
|
for (cur = top_vars; cur; cur = cur->next) {
|
||||||
break;
|
if (strcmp(cur->name, name) == 0) {
|
||||||
}
|
|
||||||
if (cur != 0) {
|
|
||||||
struct variables *next = top_vars;
|
|
||||||
if (cur->flg_read_only) {
|
if (cur->flg_read_only) {
|
||||||
bb_error_msg("%s: readonly variable", name);
|
bb_error_msg("%s: readonly variable", name);
|
||||||
return;
|
return;
|
||||||
@ -1874,10 +1878,12 @@ static void unset_local_var(const char *name)
|
|||||||
unsetenv(cur->name);
|
unsetenv(cur->name);
|
||||||
free((char*)cur->name);
|
free((char*)cur->name);
|
||||||
free((char*)cur->value);
|
free((char*)cur->value);
|
||||||
|
next = top_vars;
|
||||||
while (next->next != cur)
|
while (next->next != cur)
|
||||||
next = next->next;
|
next = next->next;
|
||||||
next->next = cur->next;
|
next->next = cur->next;
|
||||||
free(cur);
|
free(cur);
|
||||||
|
return;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -1974,9 +1980,9 @@ static void initialize_context(struct p_context *ctx)
|
|||||||
static int reserved_word(o_string *dest, struct p_context *ctx)
|
static int reserved_word(o_string *dest, struct p_context *ctx)
|
||||||
{
|
{
|
||||||
struct reserved_combo {
|
struct reserved_combo {
|
||||||
const char *literal;
|
char literal[7];
|
||||||
int code;
|
unsigned char code;
|
||||||
long flag;
|
int flag;
|
||||||
};
|
};
|
||||||
/* Mostly a list of accepted follow-up reserved words.
|
/* Mostly a list of accepted follow-up reserved words.
|
||||||
* FLAG_END means we are done with the sequence, and are ready
|
* FLAG_END means we are done with the sequence, and are ready
|
||||||
@ -2223,7 +2229,7 @@ static FILE *generate_stream_from_list(struct pipe *head)
|
|||||||
}
|
}
|
||||||
debug_printf("forked child %d\n", pid);
|
debug_printf("forked child %d\n", pid);
|
||||||
close(channel[1]);
|
close(channel[1]);
|
||||||
pf = fdopen(channel[0],"r");
|
pf = fdopen(channel[0], "r");
|
||||||
debug_printf("pipe on FILE *%p\n", pf);
|
debug_printf("pipe on FILE *%p\n", pf);
|
||||||
return pf;
|
return pf;
|
||||||
}
|
}
|
||||||
@ -2333,7 +2339,7 @@ static int handle_dollar(o_string *dest, struct p_context *ctx, struct in_str *i
|
|||||||
}
|
}
|
||||||
b_addchr(dest, SPECIAL_VAR_SYMBOL);
|
b_addchr(dest, SPECIAL_VAR_SYMBOL);
|
||||||
} else if (isdigit(ch)) {
|
} else if (isdigit(ch)) {
|
||||||
i = ch-'0'; /* XXX is $0 special? */
|
i = ch - '0'; /* XXX is $0 special? */
|
||||||
if (i < global_argc) {
|
if (i < global_argc) {
|
||||||
parse_string(dest, ctx, global_argv[i]); /* recursion */
|
parse_string(dest, ctx, global_argv[i]); /* recursion */
|
||||||
}
|
}
|
||||||
@ -2403,7 +2409,7 @@ static int handle_dollar(o_string *dest, struct p_context *ctx, struct in_str *i
|
|||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
int parse_string(o_string *dest, struct p_context *ctx, const char *src)
|
static int parse_string(o_string *dest, struct p_context *ctx, const char *src)
|
||||||
{
|
{
|
||||||
struct in_str foo;
|
struct in_str foo;
|
||||||
setup_string_in_str(&foo, src);
|
setup_string_in_str(&foo, src);
|
||||||
@ -2411,7 +2417,7 @@ int parse_string(o_string *dest, struct p_context *ctx, const char *src)
|
|||||||
}
|
}
|
||||||
|
|
||||||
/* return code is 0 for normal exit, 1 for syntax error */
|
/* return code is 0 for normal exit, 1 for syntax error */
|
||||||
int parse_stream(o_string *dest, struct p_context *ctx,
|
static int parse_stream(o_string *dest, struct p_context *ctx,
|
||||||
struct in_str *input, int end_trigger)
|
struct in_str *input, int end_trigger)
|
||||||
{
|
{
|
||||||
int ch, m;
|
int ch, m;
|
||||||
@ -2599,7 +2605,7 @@ static void update_ifs_map(void)
|
|||||||
|
|
||||||
/* most recursion does not come through here, the exception is
|
/* most recursion does not come through here, the exception is
|
||||||
* from builtin_source() */
|
* from builtin_source() */
|
||||||
int parse_stream_outer(struct in_str *inp, int flag)
|
static int parse_stream_outer(struct in_str *inp, int flag)
|
||||||
{
|
{
|
||||||
struct p_context ctx;
|
struct p_context ctx;
|
||||||
o_string temp = NULL_O_STRING;
|
o_string temp = NULL_O_STRING;
|
||||||
@ -2736,8 +2742,8 @@ int hush_main(int argc, char **argv)
|
|||||||
while ((opt = getopt(argc, argv, "c:xif")) > 0) {
|
while ((opt = getopt(argc, argv, "c:xif")) > 0) {
|
||||||
switch (opt) {
|
switch (opt) {
|
||||||
case 'c':
|
case 'c':
|
||||||
global_argv = argv+optind;
|
global_argv = argv + optind;
|
||||||
global_argc = argc-optind;
|
global_argc = argc - optind;
|
||||||
opt = parse_string_outer(optarg, FLAG_PARSE_SEMICOLON);
|
opt = parse_string_outer(optarg, FLAG_PARSE_SEMICOLON);
|
||||||
goto final_return;
|
goto final_return;
|
||||||
case 'i':
|
case 'i':
|
||||||
|
Loading…
Reference in New Issue
Block a user