X-Git-Url: https://git.librecmc.org/?a=blobdiff_plain;f=shell%2Fhush.c;h=e83d49a86e8761487fc61d5bd82c7c9684f030e0;hb=032e2cbf20bd54a7b5ded482ed1ba9d3deb574f9;hp=08b3b295f671d60be22070ab185a8ccd524b37ed;hpb=4c9b68f0e013b0b7554a3278e078177f955d39f4;p=oweals%2Fbusybox.git diff --git a/shell/hush.c b/shell/hush.c index 08b3b295f..e83d49a86 100644 --- a/shell/hush.c +++ b/shell/hush.c @@ -9,14 +9,16 @@ * * Credits: * The parser routines proper are all original material, first - * written Dec 2000 and Jan 2001 by Larry Doolittle. - * The execution engine, the builtins, and much of the underlying - * support has been adapted from busybox-0.49pre's lash, - * which is Copyright (C) 2000 by Lineo, Inc., and - * written by Erik Andersen , . - * That, in turn, is based in part on ladsh.c, by Michael K. Johnson and - * Erik W. Troan, which they placed in the public domain. I don't know - * how much of the Johnson/Troan code has survived the repeated rewrites. + * written Dec 2000 and Jan 2001 by Larry Doolittle. The + * execution engine, the builtins, and much of the underlying + * support has been adapted from busybox-0.49pre's lash, which is + * Copyright (C) 1999-2004 by Erik Andersen + * written by Erik Andersen . That, in turn, + * is based in part on ladsh.c, by Michael K. Johnson and Erik W. + * Troan, which they placed in the public domain. I don't know + * how much of the Johnson/Troan code has survived the repeated + * rewrites. + * * Other credits: * simple_itoa() was lifted from boa-0.93.15 * b_addchr() derived from similar w_addchar function in glibc-2.2 @@ -106,11 +108,11 @@ /* #include */ /* #define DEBUG_SHELL */ -#ifdef BB_VER +#if 1 #include "busybox.h" #include "cmdedit.h" #else -#define applet_name "hush" +#define bb_applet_name "hush" #include "standalone.h" #define hush_main main #undef CONFIG_FEATURE_SH_FANCY_PROMPT @@ -131,7 +133,7 @@ typedef enum { /* The descrip member of this structure is only used to make debugging * output pretty */ -struct {int mode; int default_fd; char *descrip;} redir_table[] = { +static const struct {int mode; int default_fd; const char *descrip;} redir_table[] = { { 0, 0, "()" }, { O_RDONLY, 0, "<" }, { O_CREAT|O_TRUNC|O_WRONLY, 1, ">" }, @@ -195,7 +197,7 @@ struct redir_struct { redir_type type; /* type of redirection */ int fd; /* file descriptor being redirected */ int dup; /* -1, or file descriptor being duplicated */ - struct redir_struct *next; /* pointer to the next redirect in the list */ + struct redir_struct *next; /* pointer to the next redirect in the list */ glob_t word; /* *word.gl_pathv is the filename */ }; @@ -242,11 +244,11 @@ struct variables { /* globals, connect us to the outside world * the first three support $?, $#, and $1 */ -char **global_argv; -unsigned int global_argc; -unsigned int last_return_code; +static char **global_argv; +static unsigned int global_argc; +static unsigned int last_return_code; extern char **environ; /* This is in , but protected with __USE_GNU */ - + /* "globals" within this file */ static char *ifs; static char map[256]; @@ -260,8 +262,8 @@ static unsigned int last_jobid; static unsigned int shell_terminal; static char *PS1; static char *PS2; -struct variables shell_ver = { "HUSH_VERSION", "0.01", 1, 1, 0 }; -struct variables *top_vars = &shell_ver; +static struct variables shell_ver = { "HUSH_VERSION", "0.01", 1, 1, 0 }; +static struct variables *top_vars = &shell_ver; #define B_CHUNK (100) @@ -295,8 +297,8 @@ struct in_str { #define JOB_STATUS_FORMAT "[%d] %-22s %.40s\n" struct built_in_command { - char *cmd; /* name */ - char *descr; /* description */ + const char *cmd; /* name */ + const char *descr; /* description */ int (*function) (struct child_prog *); /* function ptr */ }; @@ -320,7 +322,7 @@ static inline void debug_printf(const char *format, ...) { } #define final_printf debug_printf static void __syntax(char *file, int line) { - error_msg("syntax error %s:%d", file, line); + bb_error_msg("syntax error %s:%d", file, line); } #define syntax() __syntax(__FILE__, __LINE__) @@ -412,14 +414,14 @@ static int set_local_var(const char *s, int flg_export); * in the parent shell process. If forked, of course they can not. * For example, 'unset foo | whatever' will parse and run, but foo will * still be set at the end. */ -static struct built_in_command bltins[] = { +static const struct built_in_command bltins[] = { {"bg", "Resume a job in the background", builtin_fg_bg}, {"break", "Exit for, while or until loop", builtin_not_written}, {"cd", "Change working directory", builtin_cd}, {"continue", "Continue for, while or until loop", builtin_not_written}, {"env", "Print all environment variables", builtin_env}, {"eval", "Construct and run shell command", builtin_eval}, - {"exec", "Exec command, replacing this shell with the exec'd process", + {"exec", "Exec command, replacing this shell with the exec'd process", builtin_exec}, {"exit", "Exit from shell()", builtin_exit}, {"export", "Set environment variable", builtin_export}, @@ -441,11 +443,11 @@ static struct built_in_command bltins[] = { static const char *set_cwd(void) { - if(cwd==unknown) + if(cwd==bb_msg_unknown) cwd = NULL; /* xgetcwd(arg) called free(arg) */ cwd = xgetcwd((char *)cwd); if (!cwd) - cwd = unknown; + cwd = bb_msg_unknown; return cwd; } @@ -454,10 +456,10 @@ static int builtin_eval(struct child_prog *child) { char *str = NULL; int rcode = EXIT_SUCCESS; - + if (child->argv[1]) { str = make_string(child->argv + 1); - parse_string_outer(str, FLAG_EXIT_FROM_LOOP | + parse_string_outer(str, FLAG_EXIT_FROM_LOOP | FLAG_PARSE_SEMICOLON); free(str); rcode = last_return_code; @@ -548,7 +550,7 @@ static int builtin_export(struct child_prog *child) } } if (res<0) - perror_msg("export"); + bb_perror_msg("export"); else if(res==0) res = set_local_var(name, 1); else @@ -573,12 +575,12 @@ static int builtin_fg_bg(struct child_prog *child) } } if (!pi) { - error_msg("%s: no current job", child->argv[0]); + bb_error_msg("%s: no current job", child->argv[0]); return EXIT_FAILURE; } } else { if (sscanf(child->argv[1], "%%%d", &jobnum) != 1) { - error_msg("%s: bad argument '%s'", child->argv[0], child->argv[1]); + bb_error_msg("%s: bad argument '%s'", child->argv[0], child->argv[1]); return EXIT_FAILURE; } for (pi = job_list; pi; pi = pi->next) { @@ -587,7 +589,7 @@ static int builtin_fg_bg(struct child_prog *child) } } if (!pi) { - error_msg("%s: %d: no such job", child->argv[0], jobnum); + bb_error_msg("%s: %d: no such job", child->argv[0], jobnum); return EXIT_FAILURE; } } @@ -605,7 +607,7 @@ static int builtin_fg_bg(struct child_prog *child) if (i == ESRCH) { remove_bg_job(pi); } else { - perror_msg("kill (SIGCONT)"); + bb_perror_msg("kill (SIGCONT)"); } } @@ -616,7 +618,7 @@ static int builtin_fg_bg(struct child_prog *child) /* built-in 'help' handler */ static int builtin_help(struct child_prog *dummy) { - struct built_in_command *x; + const struct built_in_command *x; printf("\nBuilt-in commands:\n"); printf("-------------------\n"); @@ -728,7 +730,7 @@ static int builtin_source(struct child_prog *child) /* XXX search through $PATH is missing */ input = fopen(child->argv[1], "r"); if (!input) { - error_msg("Couldn't open file '%s'", child->argv[1]); + bb_error_msg("Couldn't open file '%s'", child->argv[1]); return EXIT_FAILURE; } @@ -810,7 +812,7 @@ static void b_reset(o_string *o) static void b_free(o_string *o) { b_reset(o); - if (o->data != NULL) free(o->data); + free(o->data); o->data = NULL; o->maxlen = 0; } @@ -829,7 +831,7 @@ static int b_addqchr(o_string *o, int ch, int quote) } /* belongs in utility.c */ -char *simple_itoa(unsigned int i) +static char *simple_itoa(unsigned int i) { /* 21 digits plus null terminator, good for 64-bit or smaller ints */ static char local[22]; @@ -871,7 +873,7 @@ static inline void cmdedit_set_initial_prompt(void) PS1 = getenv("PS1"); if(PS1==0) PS1 = "\\w \\$ "; -#endif +#endif } static inline void setup_prompt_string(int promptmode, char **prompt_str) @@ -880,8 +882,7 @@ static inline void setup_prompt_string(int promptmode, char **prompt_str) #ifndef CONFIG_FEATURE_SH_FANCY_PROMPT /* Set up the prompt */ if (promptmode == 1) { - if (PS1) - free(PS1); + free(PS1); PS1=xmalloc(strlen(cwd)+4); sprintf(PS1, "%s %s", cwd, ( geteuid() != 0 ) ? "$ ":"# "); *prompt_str = PS1; @@ -918,7 +919,7 @@ static void get_user_input(struct in_str *i) i->p = the_command; } -/* This is the magic location that prints prompts +/* This is the magic location that prints prompts * and gets data back from the user */ static int file_get(struct in_str *i) { @@ -997,7 +998,7 @@ static void mark_closed(int fd) { struct close_me *tmp; if (close_me_head == NULL || close_me_head->fd != fd) - error_msg_and_die("corrupt close_me"); + bb_error_msg_and_die("corrupt close_me"); tmp = close_me_head; close_me_head = close_me_head->next; free(tmp); @@ -1030,7 +1031,7 @@ static int setup_redirects(struct child_prog *prog, int squirrel[]) if (openfd < 0) { /* this could get lost if stderr has been redirected, but bash and ash both lose it as well (though zsh doesn't!) */ - perror_msg("error opening %s", redir->word.gl_pathv[0]); + bb_perror_msg("error opening %s", redir->word.gl_pathv[0]); return 1; } } else { @@ -1075,7 +1076,7 @@ static void pseudo_exec(struct child_prog *child) { int i, rcode; char *p; - struct built_in_command *x; + const struct built_in_command *x; if (child->argv) { for (i=0; is_assignment(child->argv[i]); i++) { debug_printf("pid %d environment modification: %s\n",getpid(),child->argv[i]); @@ -1109,32 +1110,20 @@ static void pseudo_exec(struct child_prog *child) } /* Check if the command matches any busybox internal commands - * ("applets") here. + * ("applets") here. * FIXME: This feature is not 100% safe, since * BusyBox is not fully reentrant, so we have no guarantee the things * from the .bss are still zeroed, or that things from .data are still * at their defaults. We could exec ourself from /proc/self/exe, but I * really dislike relying on /proc for things. We could exec ourself * from global_argv[0], but if we are in a chroot, we may not be able - * to find ourself... */ + * to find ourself... */ #ifdef CONFIG_FEATURE_SH_STANDALONE_SHELL { int argc_l; char** argv_l=child->argv; char *name = child->argv[0]; -#ifdef CONFIG_FEATURE_SH_APPLETS_ALWAYS_WIN - /* Following discussions from November 2000 on the busybox mailing - * list, the default configuration, (without - * get_last_path_component()) lets the user force use of an - * external command by specifying the full (with slashes) filename. - * If you enable CONFIG_FEATURE_SH_APPLETS_ALWAYS_WIN, then applets - * _aways_ override external commands, so if you want to run - * /bin/cat, it will use BusyBox cat even if /bin/cat exists on the - * filesystem and is _not_ busybox. Some systems may want this, - * most do not. */ - name = get_last_path_component(name); -#endif /* Count argc for use in a second... */ for(argc_l=0;*argv_l!=NULL; argv_l++, argc_l++); optind = 1; @@ -1144,7 +1133,7 @@ static void pseudo_exec(struct child_prog *child) #endif debug_printf("exec of %s\n",child->argv[0]); execvp(child->argv[0],child->argv); - perror_msg("couldn't exec: %s",child->argv[0]); + bb_perror_msg("couldn't exec: %s",child->argv[0]); _exit(1); } else if (child->group) { debug_printf("runtime nesting to group\n"); @@ -1195,7 +1184,7 @@ static void insert_bg_job(struct pipe *pi) } } - /* we don't wait for background thejobs to return -- append it + /* we don't wait for background thejobs to return -- append it to the list of backgrounded thejobs and leave it alone */ printf("[%d] %d\n", thejob->jobid, thejob->progs[0].pid); last_bg_pid = thejob->progs[0].pid; @@ -1225,7 +1214,7 @@ static void remove_bg_job(struct pipe *pi) free(pi); } -/* Checks to see if any processes have exited -- if they +/* Checks 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) { @@ -1245,7 +1234,7 @@ static int checkjobs(struct pipe* fg_pipe) int i, rcode = 0; for (i=0; i < fg_pipe->num_progs; i++) { if (fg_pipe->progs[i].pid == childpid) { - if (i==fg_pipe->num_progs-1) + if (i==fg_pipe->num_progs-1) rcode=WEXITSTATUS(status); (fg_pipe->num_progs)--; return(rcode); @@ -1288,16 +1277,16 @@ static int checkjobs(struct pipe* fg_pipe) if (pi->stopped_progs == pi->num_progs) { printf("\n"JOB_STATUS_FORMAT, pi->jobid, "Stopped", pi->text); } -#endif +#endif } } if (childpid == -1 && errno != ECHILD) - perror_msg("waitpid"); + bb_perror_msg("waitpid"); /* move the shell to the foreground */ //if (interactive && tcsetpgrp(shell_terminal, getpgid(0))) - // perror_msg("tcsetpgrp-2"); + // bb_perror_msg("tcsetpgrp-2"); return -1; } @@ -1306,7 +1295,8 @@ static int checkjobs(struct pipe* fg_pipe) * we belong to the foreground process group associated with * that tty. The value of shell_terminal is needed in order to call * tcsetpgrp(shell_terminal, ...); */ -void controlling_tty(int check_pgrp) +#if 0 +static void controlling_tty(int check_pgrp) { pid_t curpgrp; @@ -1324,6 +1314,7 @@ shell_terminal_error: shell_terminal = -1; return; } +#endif /* run_pipe_real() starts all the jobs, but doesn't wait for anything * to finish. See checkjobs(). @@ -1347,7 +1338,7 @@ static int run_pipe_real(struct pipe *pi) int nextin, nextout; int pipefds[2]; /* pipefds[0] is for reading */ struct child_prog *child; - struct built_in_command *x; + const struct built_in_command *x; char *p; nextin = 0; @@ -1377,12 +1368,12 @@ static int run_pipe_real(struct pipe *pi) /* Ok, this case is tricky. We have to decide if this is a * local variable, or an already exported variable. If it is * already exported, we have to export the new value. If it is - * not exported, we need only set this as a local variable. + * not exported, we need only set this as a local variable. * This junk is all to decide whether or not to export this * variable. */ int export_me=0; char *name, *value; - name = xstrdup(child->argv[i]); + name = bb_xstrdup(child->argv[i]); debug_printf("Local environment set: %s\n", name); value = strchr(name, '='); if (value) @@ -1407,7 +1398,7 @@ static int run_pipe_real(struct pipe *pi) } if (child->sp) { char * str = NULL; - + str = make_string((child->argv + i)); parse_string_outer(str, FLAG_EXIT_FROM_LOOP | FLAG_REPARSING); free(str); @@ -1442,7 +1433,7 @@ static int run_pipe_real(struct pipe *pi) /* pipes are inserted between pairs of commands */ if ((i + 1) < pi->num_progs) { - if (pipe(pipefds)<0) perror_msg_and_die("pipe"); + if (pipe(pipefds)<0) bb_perror_msg_and_die("pipe"); nextout = pipefds[1]; } else { nextout=1; @@ -1450,10 +1441,10 @@ static int run_pipe_real(struct pipe *pi) } /* XXX test for failed fork()? */ -#if !defined(__UCLIBC__) || defined(__UCLIBC_HAS_MMU__) +#if !defined(__UCLIBC__) || defined(__ARCH_HAS_MMU__) if (!(child->pid = fork())) #else - if (!(child->pid = vfork())) + if (!(child->pid = vfork())) #endif { /* Set the handling for job control signals back to the default. */ @@ -1464,7 +1455,7 @@ static int run_pipe_real(struct pipe *pi) signal(SIGTTIN, SIG_DFL); signal(SIGTTOU, SIG_DFL); signal(SIGCHLD, SIG_DFL); - + close_all(); if (nextin != 0) { @@ -1496,7 +1487,7 @@ static int run_pipe_real(struct pipe *pi) pseudo_exec(child); } - + /* put our child in the process group whose leader is the first process in this pipe */ @@ -1512,7 +1503,7 @@ static int run_pipe_real(struct pipe *pi) if (nextout != 1) close(nextout); - /* If there isn't another process, nextin is garbage + /* If there isn't another process, nextin is garbage but it doesn't matter */ nextin = pipefds[0]; } @@ -1538,12 +1529,12 @@ static int run_list_real(struct pipe *pi) (rpipe->next == NULL)) { syntax(); return 1; - } - if ((rpipe->r_mode == RES_IN && - (rpipe->next->r_mode == RES_IN && + } + if ((rpipe->r_mode == RES_IN && + (rpipe->next->r_mode == RES_IN && rpipe->next->progs->argv != NULL))|| (rpipe->r_mode == RES_FOR && - rpipe->next->r_mode != RES_IN)) { + rpipe->next->r_mode != RES_IN)) { syntax(); return 1; } @@ -1568,10 +1559,10 @@ static int run_list_real(struct pipe *pi) if (rmode == RES_THEN || rmode == RES_ELSE) if_code = next_if_code; if (rmode == RES_THEN && if_code) continue; if (rmode == RES_ELSE && !if_code) continue; - if (rmode == RES_ELIF && !if_code) continue; + if (rmode == RES_ELIF && !if_code) break; if (rmode == RES_FOR && pi->num_progs) { if (!list) { - /* if no variable values after "in" we skip "for" */ + /* if no variable values after "in" we skip "for" */ if (!pi->next->progs->argv) continue; /* create list of variable values */ list = make_list_in(pi->next->progs->argv, @@ -1580,7 +1571,7 @@ static int run_list_real(struct pipe *pi) save_name = pi->progs->argv[0]; pi->progs->argv[0] = NULL; flag_rep = 1; - } + } if (!(*list)) { free(pi->progs->argv[0]); free(save_list); @@ -1590,26 +1581,26 @@ static int run_list_real(struct pipe *pi) pi->progs->glob_result.gl_pathv[0] = pi->progs->argv[0]; continue; - } else { + } else { /* insert new value from list for variable */ - if (pi->progs->argv[0]) + 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) continue; if (rmode == RES_DO) { if (!flag_rep) continue; - } + } if ((rmode == RES_DONE)) { if (flag_rep) { flag_restore = 1; } else { rpipe = NULL; } - } + } if (pi->num_progs == 0) continue; save_num_progs = pi->num_progs; /* save number of programs */ rcode = run_pipe_real(pi); @@ -1627,11 +1618,11 @@ static int run_list_real(struct pipe *pi) if (interactive) { /* move the new process group into the foreground */ if (tcsetpgrp(shell_terminal, pi->pgrp) && errno != ENOTTY) - perror_msg("tcsetpgrp-3"); + bb_perror_msg("tcsetpgrp-3"); rcode = checkjobs(pi); /* move the shell to the foreground */ if (tcsetpgrp(shell_terminal, getpgid(0)) && errno != ENOTTY) - perror_msg("tcsetpgrp-4"); + bb_perror_msg("tcsetpgrp-4"); } else { rcode = checkjobs(pi); } @@ -1641,9 +1632,9 @@ static int run_list_real(struct pipe *pi) pi->num_progs = save_num_progs; /* restore number of programs */ if ( rmode == RES_IF || rmode == RES_ELIF ) next_if_code=rcode; /* can be overwritten a number of times */ - if (rmode == RES_WHILE) + if (rmode == RES_WHILE) flag_rep = !last_return_code; - if (rmode == RES_UNTIL) + if (rmode == RES_UNTIL) flag_rep = last_return_code; if ( (rcode==EXIT_SUCCESS && pi->followup==PIPE_OR) || (rcode!=EXIT_SUCCESS && pi->followup==PIPE_AND) ) @@ -1722,7 +1713,7 @@ static int free_pipe_list(struct pipe *head, int indent) pi->next=NULL; free(pi); } - return rcode; + return rcode; } /* Select which version we will use */ @@ -1731,7 +1722,7 @@ static int run_list(struct pipe *pi) int rcode=0; if (fake_mode==0) { rcode = run_list_real(pi); - } + } /* free_pipe_list has the side effect of clearing memory * In the long run that function can be merged with run_list_real, * but doing that now would hobble the debugging effort. */ @@ -1826,9 +1817,9 @@ static int xglob(o_string *dest, int flags, glob_t *pglob) debug_printf("globhack returned %d\n",gr); } if (gr == GLOB_NOSPACE) - error_msg_and_die("out of memory during glob"); + bb_error_msg_and_die("out of memory during glob"); if (gr != 0) { /* GLOB_ABORTED ? */ - error_msg("glob(3) error %d",gr); + bb_error_msg("glob(3) error %d",gr); } /* globprint(glob_target); */ return gr; @@ -1861,7 +1852,7 @@ static int set_local_var(const char *s, int flg_export) /* Assume when we enter this function that we are already in * NAME=VALUE format. So the first order of business is to - * split 's' on the '=' into 'name' and 'value' */ + * split 's' on the '=' into 'name' and 'value' */ value = strchr(name, '='); if (value==0 && ++value==0) { free(name); @@ -1882,7 +1873,7 @@ static int set_local_var(const char *s, int flg_export) result++; } else { if(cur->flg_read_only) { - error_msg("%s: readonly variable", name); + bb_error_msg("%s: readonly variable", name); result = -1; } else { if(flg_export>0 || cur->flg_export>1) @@ -1936,7 +1927,7 @@ static void unset_local_var(const char *name) if(cur!=0) { struct variables *next = top_vars; if(cur->flg_read_only) { - error_msg("%s: readonly variable", name); + bb_error_msg("%s: readonly variable", name); return; } else { if(cur->flg_export) @@ -1990,7 +1981,7 @@ static int setup_redirect(struct p_context *ctx, int fd, redir_type style, debug_printf("Redirect type %d%s\n", redir->fd, redir_table[style].descrip); - /* Check for a '2>&1' type redirect */ + /* Check for a '2>&1' type redirect */ redir->dup = redirect_dup_num(input); if (redir->dup == -2) return 1; /* syntax error */ if (redir->dup != -1) { @@ -2009,13 +2000,14 @@ static int setup_redirect(struct p_context *ctx, int fd, redir_type style, return 0; } -struct pipe *new_pipe(void) { +static struct pipe *new_pipe(void) { struct pipe *pi; pi = xmalloc(sizeof(struct pipe)); pi->num_progs = 0; pi->progs = NULL; pi->next = NULL; pi->followup = 0; /* invalid */ + pi->r_mode = RES_NONE; return pi; } @@ -2037,7 +2029,7 @@ static void initialize_context(struct p_context *ctx) * should handle if, then, elif, else, fi, for, while, until, do, done. * case, function, and select are obnoxious, save those for later. */ -int reserved_word(o_string *dest, struct p_context *ctx) +static int reserved_word(o_string *dest, struct p_context *ctx) { struct reserved_combo { char *literal; @@ -2140,7 +2132,7 @@ static int done_word(o_string *dest, struct p_context *ctx) if (ctx->pending_redirect) { ctx->pending_redirect=NULL; if (glob_target->gl_pathc != 1) { - error_msg("ambiguous redirect"); + bb_error_msg("ambiguous redirect"); return 1; } } else { @@ -2232,7 +2224,7 @@ static int redirect_dup_num(struct in_str *input) } if (ok) return d; - error_msg("ambiguous redirect"); + bb_error_msg("ambiguous redirect"); return -2; } @@ -2263,19 +2255,19 @@ static int redirect_opt_num(o_string *o) return num; } -FILE *generate_stream_from_list(struct pipe *head) +static FILE *generate_stream_from_list(struct pipe *head) { FILE *pf; #if 1 int pid, channel[2]; - if (pipe(channel)<0) perror_msg_and_die("pipe"); -#if !defined(__UCLIBC__) || defined(__UCLIBC_HAS_MMU__) + if (pipe(channel)<0) bb_perror_msg_and_die("pipe"); +#if !defined(__UCLIBC__) || defined(__ARCH_HAS_MMU__) pid=fork(); #else pid=vfork(); #endif if (pid<0) { - perror_msg_and_die("fork"); + bb_perror_msg_and_die("fork"); } else if (pid==0) { close(channel[0]); if (channel[1] != 1) { @@ -2376,9 +2368,9 @@ static int parse_group(o_string *dest, struct p_context *ctx, static char *lookup_param(char *src) { char *p=NULL; - if (src) { + if (src) { p = getenv(src); - if (!p) + if (!p) p = get_local_var(src); } return p; @@ -2451,7 +2443,7 @@ static int handle_dollar(o_string *dest, struct p_context *ctx, struct in_str *i case '-': case '_': /* still unhandled, but should be eventually */ - error_msg("unhandled syntax: $%c",ch); + bb_error_msg("unhandled syntax: $%c",ch); return 1; break; default: @@ -2498,7 +2490,7 @@ int parse_stream(o_string *dest, struct p_context *ctx, if (m==2) { /* unquoted IFS */ if (done_word(dest, ctx)) { return 1; - } + } /* If we aren't performing a substitution, treat a newline as a * command separator. */ if (end_trigger != '\0' && ch=='\n') @@ -2623,7 +2615,7 @@ int parse_stream(o_string *dest, struct p_context *ctx, } /* complain if quote? No, maybe we just finished a command substitution * that was quoted. Example: - * $ echo "`cat foo` plus more" + * $ echo "`cat foo` plus more" * and we just got the EOF generated by the subshell that ran "cat foo" * The only real complaint is if we got an EOF when end_trigger != '\0', * that is, we were really supposed to get end_trigger, and never got @@ -2634,13 +2626,13 @@ int parse_stream(o_string *dest, struct p_context *ctx, return 0; } -void mapset(const unsigned char *set, int code) +static void mapset(const unsigned char *set, int code) { const unsigned char *s; for (s=set; *s; s++) map[*s] = code; } -void update_ifs_map(void) +static void update_ifs_map(void) { /* char *ifs and char map[256] are both globals. */ ifs = getenv("IFS"); @@ -2657,7 +2649,7 @@ void update_ifs_map(void) mapset(ifs, 2); /* also flow through if quoted */ } -/* most recursion does not come through here, the exeception is +/* most recursion does not come through here, the exception is * from builtin_source() */ int parse_stream_outer(struct in_str *inp, int flag) { @@ -2683,7 +2675,7 @@ int parse_stream_outer(struct in_str *inp, int flag) if (ctx.old_flag != 0) { free(ctx.stack); b_reset(&temp); - } + } temp.nonnull = 0; temp.quote = 0; inp->p = NULL; @@ -2747,9 +2739,9 @@ int hush_main(int argc, char **argv) /* XXX what should these be while sourcing /etc/profile? */ global_argc = argc; global_argv = argv; - + /* (re?) initialize globals. Sometimes hush_main() ends up calling - * hush_main(), therefore we cannot rely on the BSS to zero out this + * hush_main(), therefore we cannot rely on the BSS to zero out this * stuff. Reset these to 0 every time. */ ifs = NULL; /* map[] is taken care of with call to update_ifs_map() */ @@ -2769,7 +2761,7 @@ int hush_main(int argc, char **argv) #endif PS2 = "> "; - /* initialize our shell local variables with the values + /* initialize our shell local variables with the values * currently living in the environment */ if (e) { for (; *e; e++) @@ -2789,7 +2781,7 @@ int hush_main(int argc, char **argv) } } input=stdin; - + while ((opt = getopt(argc, argv, "c:xif")) > 0) { switch (opt) { case 'c': @@ -2812,7 +2804,7 @@ int hush_main(int argc, char **argv) " or: sh -c command [args]...\n\n"); exit(EXIT_FAILURE); #else - show_usage(); + bb_show_usage(); #endif } } @@ -2824,20 +2816,20 @@ int hush_main(int argc, char **argv) * standard output is a terminal * Refer to Posix.2, the description of the `sh' utility. */ if (argv[optind]==NULL && input==stdin && - isatty(fileno(stdin)) && isatty(fileno(stdout))) { + isatty(STDIN_FILENO) && isatty(STDOUT_FILENO)) { interactive++; } debug_printf("\ninteractive=%d\n", interactive); if (interactive) { /* Looks like they want an interactive shell */ -#ifndef CONFIG_FEATURE_SH_EXTRA_QUIET +#ifndef CONFIG_FEATURE_SH_EXTRA_QUIET printf( "\n\n" BB_BANNER " hush - the humble shell v0.01 (testing)\n"); printf( "Enter 'help' for a list of built-in commands.\n\n"); #endif setup_job_control(); } - + if (argv[optind]==NULL) { opt=parse_file_outer(stdin); goto final_return; @@ -2846,12 +2838,12 @@ int hush_main(int argc, char **argv) debug_printf("\nrunning script '%s'\n", argv[optind]); global_argv = argv+optind; global_argc = argc-optind; - input = xfopen(argv[optind], "r"); + input = bb_xfopen(argv[optind], "r"); opt = parse_file_outer(input); #ifdef CONFIG_FEATURE_CLEAN_UP fclose(input); - if (cwd && cwd != unknown) + if (cwd && cwd != bb_msg_unknown) free((char*)cwd); { struct variables *cur, *tmp; @@ -2876,7 +2868,7 @@ static char *insert_var_value(char *inp) int len; int done = 0; char *p, *p1, *res_str = NULL; - + while ((p = strchr(inp, SPECIAL_VAR_SYMBOL))) { if (p != inp) { len = p - inp; @@ -2892,7 +2884,7 @@ static char *insert_var_value(char *inp) res_str = xrealloc(res_str, (1 + len)); strcpy((res_str + res_str_len), p1); res_str_len = len; - } + } *p = SPECIAL_VAR_SYMBOL; inp = ++p; done = 1; @@ -2914,8 +2906,8 @@ static char **make_list_in(char **inp, char *name) int n = 0; char **list; char *p1, *p2, *p3; - - /* create list of variable values */ + + /* create list of variable values */ list = xmalloc(sizeof(*list)); for (i = 0; inp[i]; i++) { p3 = insert_var_value(inp[i]); @@ -2927,13 +2919,13 @@ static char **make_list_in(char **inp, char *name) } if ((p2 = strchr(p1, ' '))) { len = p2 - p1; - } else { + } else { len = strlen(p1); p2 = p1 + len; } - /* we use n + 2 in realloc for list,because we add + /* we use n + 2 in realloc for list,because we add * new element and then we will add NULL element */ - list = xrealloc(list, sizeof(*list) * (n + 2)); + list = xrealloc(list, sizeof(*list) * (n + 2)); list[n] = xmalloc(2 + name_len + len); strcpy(list[n], name); strcat(list[n], "="); @@ -2945,7 +2937,7 @@ static char **make_list_in(char **inp, char *name) } list[n] = NULL; return list; -} +} /* Make new string for parser */ static char * make_string(char ** inp)