diff options
author | Eric Andersen | 2001-07-06 04:26:23 +0000 |
---|---|---|
committer | Eric Andersen | 2001-07-06 04:26:23 +0000 |
commit | 3102ac4b582b144ad0e04c7cbe511c25c1175ee2 (patch) | |
tree | 4f6d1fa7ff379817afc74301bac06baf9d0d6bd7 /shell | |
parent | 5009f90ea24224638af6945552012ce60efb3cea (diff) | |
download | busybox-3102ac4b582b144ad0e04c7cbe511c25c1175ee2.zip busybox-3102ac4b582b144ad0e04c7cbe511c25c1175ee2.tar.gz |
This is vodz' latest ash update.
Diffstat (limited to 'shell')
-rw-r--r-- | shell/ash.c | 702 |
1 files changed, 131 insertions, 571 deletions
diff --git a/shell/ash.c b/shell/ash.c index e7f3516..99460d3 100644 --- a/shell/ash.c +++ b/shell/ash.c @@ -42,7 +42,7 @@ /* Enable job control. This allows you to run jobs in the background, * which is great when ash is being used as an interactive shell, but - * it completely useless for is all you are doing is running scripts. + * it completely useless for is all you are doing is running scripts. * This adds about 2.5k on an x86 system. */ #define JOBS @@ -79,6 +79,9 @@ * a little bit faster, but leaving this disabled will save you 2k. */ #undef ASH_BBAPPS_AS_BUILTINS +/* Optimize size vs speed as size */ +#define ASH_OPTIMIZE_FOR_SIZE + /* Enable this to compile in extra debugging noise. When debugging is * on, debugging info will be written to $HOME/trace and a quit signal * will generate a core dump. */ @@ -133,12 +136,6 @@ #include "busybox.h" #include "cmdedit.h" -/* if BB_PWD is defined, then disable ASH_PWD to save space */ -#ifdef BB_PWD -#undef ASH_PWD -#endif - - /* * This file was generated by the mksyntax program. */ @@ -230,7 +227,7 @@ #define _DIAGASSERT(x) -#define ATABSIZE 39 + #define S_DFL 1 /* default signal handling (SIG_DFL) */ #define S_CATCH 2 /* signal is caught */ @@ -258,7 +255,7 @@ /* flags passed to redirect */ #define REDIR_PUSH 01 /* save previous values of file descriptors */ -#define REDIR_BACKQ 02 /* save the command output in memory */ +#define REDIR_BACKQ 02 /* save the command output to pipe */ /* * BSD setjmp saves the signal mask, which violates ANSI C and takes time, @@ -302,13 +299,16 @@ static volatile int suppressint; static volatile int intpending; #define INTOFF suppressint++ -#ifdef ASH_BBAPPS_AS_BUILTINS +#ifndef ASH_OPTIMIZE_FOR_SIZE #define INTON { if (--suppressint == 0 && intpending) onint(); } +#define FORCEINTON {suppressint = 0; if (intpending) onint();} #else static void __inton (void); +static void forceinton (void); #define INTON __inton() +#define FORCEINTON forceinton() #endif -#define FORCEINTON {suppressint = 0; if (intpending) onint();} + #define CLEAR_PENDING_INT intpending = 0 #define int_pending() intpending @@ -326,6 +326,7 @@ static pointer stalloc (int); static void stunalloc (pointer); static void ungrabstackstr (char *, char *); static char * growstackstr(void); +static char * makestrspace(size_t newlen); static char *sstrdup (const char *); /* @@ -357,10 +358,13 @@ static int stacknleft = MINSIZE; #define stackblock() stacknxt #define stackblocksize() stacknleft #define STARTSTACKSTR(p) p = stackblock(), sstrnleft = stackblocksize() + #define STPUTC(c, p) (--sstrnleft >= 0? (*p++ = (c)) : (p = growstackstr(), *p++ = (c))) #define CHECKSTRSPACE(n, p) { if (sstrnleft < n) p = makestrspace(n); } -#define USTPUTC(c, p) (--sstrnleft, *p++ = (c)) #define STACKSTRNUL(p) (sstrnleft == 0? (p = growstackstr(), *p = '\0') : (*p = '\0')) + + +#define USTPUTC(c, p) (--sstrnleft, *p++ = (c)) #define STUNPUTC(p) (++sstrnleft, --p) #define STTOPC(p) p[-1] #define STADJUST(amount, p) (p += (amount), sstrnleft -= (amount)) @@ -368,7 +372,6 @@ static int stacknleft = MINSIZE; #define ckfree(p) free((pointer)(p)) -static char * makestrspace(size_t newlen); #ifdef DEBUG #define TRACE(param) trace param @@ -659,71 +662,18 @@ struct shparam { int optoff; /* used by getopts */ }; -struct output { -#ifdef USE_GLIBC_STDIO - FILE *stream; -#endif - char *nextc; - int nleft; - char *buf; - int bufsize; - int fd; - short flags; -}; - -#define OUTBUFSIZ BUFSIZ -#define MEM_OUT -3 /* output to dynamically allocated memory */ - - -#ifdef USE_GLIBC_STDIO -static struct output output = {NULL, NULL, 0, NULL, 0, 1, 0}; -static struct output errout = {NULL, NULL, 0, NULL, 0, 2, 0}; -static struct output memout = {NULL, NULL, 0, NULL, 0, MEM_OUT, 0}; -#else -static struct output output = {NULL, 0, NULL, OUTBUFSIZ, 1, 0}; -static struct output errout = {NULL, 0, NULL, 0, 2, 0}; -static struct output memout = {NULL, 0, NULL, 0, MEM_OUT, 0}; -#endif -static struct output *out1 = &output; -static struct output *out2 = &errout; - -#ifndef USE_GLIBC_STDIO -static void outcslow (char, struct output *); -#endif static void flushall (void); -static void flushout (struct output *); -static void freestdout (void); -static void outfmt (struct output *, const char *, ...) - __attribute__((__format__(__printf__,2,3))); +static void out2fmt (const char *, ...) + __attribute__((__format__(__printf__,1,2))); static void out1fmt (const char *, ...) __attribute__((__format__(__printf__,1,2))); -static void fmtstr (char *, size_t, const char *, ...) - __attribute__((__format__(__printf__,3,4))); -#ifndef USE_GLIBC_STDIO -static void doformat (struct output *, const char *, va_list); -#endif static int xwrite (int, const char *, int); -#ifdef USE_GLIBC_STDIO -static void initstreams (void); -static void openmemout (void); -static int __closememout (void); -#endif -static void outstr(const char *p, struct output *file); +static void outstr (const char *p, FILE *file) { fputs(p, file); } +static void out1str(const char *p) { outstr(p, stdout); } +static void out2str(const char *p) { outstr(p, stderr); } -#define OUTPUT_ERR 01 /* error occurred on output */ - -#ifdef USE_GLIBC_STDIO -#define outc(c, o) putc((c), (o)->stream) -#define doformat(d, f, a) vfprintf((d)->stream, (f), (a)) -#else -#define outc(c, file) (--(file)->nleft < 0? outcslow((c), (file)) : (*(file)->nextc = (c), (file)->nextc++)) -#endif -#define out1c(c) outc((c), out1) -#define out2c(c) outc((c), out2) -#define out1str(s) outstr((s), out1) -#define out2str(s) outstr((s), out2) -#define outerr(f) ((f)->flags & OUTPUT_ERR) +#define out2c(c) putc((c), stderr) /* syntax table used when not in quotes */ static const char basesyntax[257] = { @@ -1389,6 +1339,8 @@ static char *minusc; /* argument to -c option */ #define ALIASINUSE 1 #define ALIASDEAD 2 +#define ATABSIZE 39 + struct alias { struct alias *next; char *name; @@ -1508,7 +1460,7 @@ aliascmd(int argc, char **argv) while ((n = *++argv) != NULL) { if ((v = strchr(n+1, '=')) == NULL) { /* n+1: funny ksh stuff */ if ((ap = *__lookupalias(n)) == NULL) { - outfmt(out2, "%s: %s not found\n", "alias", n); + out2fmt("%s: %s not found\n", "alias", n); ret = 1; } else printalias(ap); @@ -1535,7 +1487,7 @@ unaliascmd(int argc, char **argv) } for (i = 0; *argptr; argptr++) { if (unalias(*argptr)) { - outfmt(out2, "%s: %s not found\n", "unalias", *argptr); + out2fmt("%s: %s not found\n", "unalias", *argptr); i = 1; } } @@ -1653,7 +1605,7 @@ static int histcmd (int, char **); static int hashcmd (int, char **); static int jobscmd (int, char **); static int localcmd (int, char **); -#ifdef ASH_PWD +#ifndef BB_PWD static int pwdcmd (int, char **); #endif static int readcmd (int, char **); @@ -1725,7 +1677,7 @@ static const struct builtincmd builtincmds[] = { { BUILTIN_REGULAR "bg", bgcmd }, #endif { BUILTIN_SPECIAL "break", breakcmd }, - { BUILTIN_SPECIAL "builtin", bltincmd }, /* Do not disable this builtin ever or bad things happen */ + { BUILTIN_SPECIAL "builtin", bltincmd }, { BUILTIN_REGULAR "cd", cdcmd }, #ifdef ASH_BBAPPS_AS_BUILTINS { BUILTIN_NOSPEC "chdir", cdcmd }, @@ -1760,7 +1712,7 @@ static const struct builtincmd builtincmds[] = { { BUILTIN_NOSPEC "let", expcmd }, #endif { BUILTIN_ASSIGN "local", localcmd }, -#ifdef ASH_PWD +#ifndef BB_PWD { BUILTIN_NOSPEC "pwd", pwdcmd }, #endif { BUILTIN_REGULAR "read", readcmd }, @@ -2049,7 +2001,7 @@ updatepwd(const char *dir) } -#ifdef ASH_PWD +#ifndef BB_PWD static int pwdcmd(argc, argv) int argc; @@ -2198,13 +2150,9 @@ exverror(int cond, const char *msg, va_list ap) #endif if (msg) { if (commandname) - outfmt(&errout, "%s: ", commandname); - doformat(&errout, msg, ap); -#if FLUSHERR - outc('\n', &errout); -#else - outcslow('\n', &errout); -#endif + out2fmt("%s: ", commandname); + vfprintf(stderr, msg, ap); + out2c('\n'); } flushall(); exraise(cond); @@ -2357,18 +2305,23 @@ errmsg(int e, int action) return strerror(e); } - fmtstr(buf, sizeof buf, "error %d", e); + snprintf(buf, sizeof buf, "error %d", e); return buf; } -#ifndef ASH_BBAPPS_AS_BUILTINS +#ifdef ASH_OPTIMIZE_FOR_SIZE static void __inton() { if (--suppressint == 0 && intpending) { onint(); } } +static void forceinton (void) { + suppressint = 0; + if (intpending) + onint(); +} #endif /* flags in argument to evaltree */ @@ -2394,11 +2347,7 @@ static void evalcase (union node *, int); static void evalsubshell (union node *, int); static void expredir (union node *); static void evalpipe (union node *); -#ifdef notyet -static void evalcommand (union node *, int, struct backcmd *); -#else static void evalcommand (union node *, int); -#endif static void prehash (union node *); static void eprintlist (struct strlist *); @@ -2545,7 +2494,7 @@ evaltree(n, flags) (bcmd = find_builtin(n->narg.text)) && IS_BUILTIN_SPECIAL(bcmd) ) { - outfmt(out2, "%s is a special built-in\n", n->narg.text); + out2fmt("%s is a special built-in\n", n->narg.text); exitstatus = 1; break; } @@ -2563,19 +2512,12 @@ evaltree(n, flags) checkexit = 1; break; case NCMD: -#ifdef notyet - evalcommand(n, flags, (struct backcmd *)NULL); -#else evalcommand(n, flags); -#endif checkexit = 1; break; #ifdef DEBUG default: out1fmt("Node type = %d\n", n->type); -#ifndef USE_GLIBC_STDIO - flushout(out1); -#endif break; #endif } @@ -2726,7 +2668,6 @@ evalsubshell(n, flags) } - /* * Compute the names of the files in a redirection list. */ @@ -2855,38 +2796,24 @@ evalbackcmd(union node *n, struct backcmd *result) exitstatus = 0; goto out; } -#ifdef notyet - /* - * For now we disable executing builtins in the same - * context as the shell, because we are not keeping - * enough state to recover from changes that are - * supposed only to affect subshells. eg. echo "`cd /`" - */ - if (n->type == NCMD) { - exitstatus = oexitstatus; - evalcommand(n, EV_BACKCMD, result); - } else -#endif - { - exitstatus = 0; - if (pipe(pip) < 0) - error("Pipe call failed"); - jp = makejob(n, 1); - if (forkshell(jp, n, FORK_NOJOB) == 0) { - FORCEINTON; - close(pip[0]); - if (pip[1] != 1) { - close(1); - dup_as_newfd(pip[1], 1); - close(pip[1]); - } - eflag = 0; - evaltree(n, EV_EXIT); + exitstatus = 0; + if (pipe(pip) < 0) + error("Pipe call failed"); + jp = makejob(n, 1); + if (forkshell(jp, n, FORK_NOJOB) == 0) { + FORCEINTON; + close(pip[0]); + if (pip[1] != 1) { + close(1); + dup_as_newfd(pip[1], 1); + close(pip[1]); } - close(pip[1]); - result->fd = pip[0]; - result->jp = jp; + eflag = 0; + evaltree(n, EV_EXIT); } + close(pip[1]); + result->fd = pip[0]; + result->jp = jp; out: popstackmark(&smark); TRACE(("evalbackcmd done: fd=%d buf=0x%x nleft=%d jp=0x%x\n", @@ -2913,16 +2840,7 @@ isassignment(const char *word) { } static void -#ifdef notyet -evalcommand(cmd, flags, backcmd) - union node *cmd; - int flags; - struct backcmd *backcmd; -#else -evalcommand(cmd, flags) - union node *cmd; - int flags; -#endif +evalcommand(union node *cmd, int flags) { struct stackmark smark; union node *argp; @@ -2933,9 +2851,6 @@ evalcommand(cmd, flags) char **envp; struct strlist *sp; int mode; -#ifdef notyet - int pip[2]; -#endif struct cmdentry cmdentry; struct job *jp; char *volatile savecmdname; @@ -3006,19 +2921,10 @@ evalcommand(cmd, flags) /* Print the command if xflag is set. */ if (xflag) { -#ifdef FLUSHERR - outc('+', &errout); -#else - outcslow('+', &errout); -#endif + out2c('+'); eprintlist(varlist.list); eprintlist(arglist.list); -#ifdef FLUSHERR - outc('\n', &errout); - flushout(&errout); -#else - outcslow('\n', &errout); -#endif + out2c('\n'); } /* Now locate the command. */ @@ -3046,9 +2952,6 @@ evalcommand(cmd, flags) find_command(argv[0], &cmdentry, findflag, path); if (cmdentry.cmdtype == CMDUNKNOWN) { /* command not found */ exitstatus = 127; -#ifdef FLUSHERR - flushout(&errout); -#endif goto out; } /* implement bltin and command here */ @@ -3066,11 +2969,8 @@ evalcommand(cmd, flags) if (--argc == 0) goto found; if (!(bcmd = find_builtin(*argv))) { - outfmt(&errout, "%s: not found\n", *argv); + out2fmt("%s: not found\n", *argv); exitstatus = 127; -#ifdef FLUSHERR - flushout(&errout); -#endif goto out; } cmdentry.u.cmd = bcmd; @@ -3110,35 +3010,11 @@ found: /* Fork off a child process if necessary. */ if (cmd->ncmd.backgnd || (cmdentry.cmdtype == CMDNORMAL && (flags & EV_EXIT) == 0) -#ifdef notyet - || ((flags & EV_BACKCMD) != 0 - && (cmdentry.cmdtype != CMDBUILTIN - || cmdentry.u.bcmd == DOTCMD - || cmdentry.u.bcmd == EVALCMD)) -#endif ) { jp = makejob(cmd, 1); mode = cmd->ncmd.backgnd; -#ifdef notyet - if (flags & EV_BACKCMD) { - mode = FORK_NOJOB; - if (pipe(pip) < 0) - error("Pipe call failed"); - } -#endif if (forkshell(jp, cmd, mode) != 0) goto parent; /* at end of routine */ -#ifdef notyet - if (flags & EV_BACKCMD) { - FORCEINTON; - close(pip[0]); - if (pip[1] != 1) { - close(1); - dup_as_newfd(pip[1], 1); - close(pip[1]); - } - } -#endif flags |= EV_EXIT; } @@ -3201,18 +3077,6 @@ found: trputs("builtin command: "); trargs(argv); #endif mode = (cmdentry.u.cmd == EXECCMD)? 0 : REDIR_PUSH; -#ifdef notyet - if (flags == EV_BACKCMD) { -#ifdef USE_GLIBC_STDIO - openmemout(); -#else - memout.nleft = 0; - memout.nextc = memout.buf; - memout.bufsize = 64; -#endif - mode |= REDIR_BACKQ; - } -#endif redirect(cmd->ncmd.redirect, mode); savecmdname = commandname; if (IS_BUILTIN_SPECIAL(firstbltin)) { @@ -3234,10 +3098,6 @@ found: exitstatus = (*cmdentry.u.cmd->builtinfunc)(argc, argv); flushall(); cmddone: - exitstatus |= outerr(out1); - out1 = &output; - out2 = &errout; - freestdout(); cmdenviron = NULL; if (e != EXSHELLPROC) { commandname = savecmdname; @@ -3256,23 +3116,6 @@ cmddone: } if (cmdentry.u.cmd != EXECCMD) popredir(); -#ifdef notyet - if (flags == EV_BACKCMD) { - INTOFF; -#ifdef USE_GLIBC_STDIO - if (__closememout()) - error("__closememout() failed: %m"); -#endif - backcmd->buf = memout.buf; -#ifdef USE_GLIBC_STDIO - backcmd->nleft = memout.bufsize; -#else - backcmd->nleft = memout.nextc - memout.buf; -#endif - memout.buf = NULL; - INTON; - } -#endif } else { #ifdef DEBUG trputs("normal command: "); trargs(argv); @@ -3291,12 +3134,6 @@ parent: /* parent process gets here (if we forked) */ INTOFF; exitstatus = waitforjob(jp); INTON; -#ifdef notyet - } else if (mode == 2) { - backcmd->fd = pip[0]; - close(pip[1]); - backcmd->jp = jp; -#endif } out: @@ -3477,7 +3314,7 @@ static void eprintlist(struct strlist *sp) { for (; sp; sp = sp->next) { - outfmt(&errout, " %s",sp->text); + out2fmt(" %s",sp->text); } } /* @@ -3653,7 +3490,7 @@ static int preadfd (void); * Nul characters in the input are silently discarded. */ -#ifdef ASH_BBAPPS_AS_BUILTINS +#ifndef ASH_OPTIMIZE_FOR_SIZE #define pgetc_macro() (--parsenleft >= 0? *parsenextc++ : preadbuffer()) static int pgetc(void) @@ -3793,6 +3630,21 @@ tryexec(cmd, argv, envp) { int e; +#ifdef BB_FEATURE_SH_STANDALONE_SHELL + char *name = cmd; + char** argv_l=argv; + int argc_l; +#ifdef BB_FEATURE_SH_APPLETS_ALWAYS_WIN + name = get_last_path_component(name); +#endif + argv_l=envp; + for(argc_l=0;*argv_l!=NULL; argv_l++, argc_l++) + putenv(*argv_l); + argv_l=argv; + for(argc_l=0;*argv_l!=NULL; argv_l++, argc_l++); + optind = 1; + run_applet_by_name(name, argc_l, argv); +#endif execve(cmd, argv, envp); e = errno; if (e == ENOEXEC) { @@ -4126,7 +3978,7 @@ loop: if (cmdp && updatetbl) delete_cmd_entry(); if (act & DO_ERR) - outfmt(out2, "%s: %s\n", name, errmsg(e, E_EXEC)); + out2fmt("%s: %s\n", name, errmsg(e, E_EXEC)); entry->cmdtype = CMDUNKNOWN; return; @@ -4515,7 +4367,7 @@ describe_command(char *command, int verbose) } out: - out1c('\n'); + putchar('\n'); return 0; } #endif @@ -4543,16 +4395,16 @@ commandcmd(argc, argv) verbose_verify_only = 1; break; default: - outfmt(out2, + out2fmt( "command: nextopt returned character code 0%o\n", c); return EX_SOFTWARE; } if (default_path + verify_only + verbose_verify_only > 1 || !*argptr) { - outfmt(out2, + out2fmt( "command [-p] command [arg ...]\n"); - outfmt(out2, + out2fmt( "command {-v|-V} command\n"); return EX_USAGE; } @@ -4940,7 +4792,7 @@ expari(int flag) if (quotes) rmescapes(p+2); result = arith(p+2); - fmtstr(p, 12, "%d", result); + snprintf(p, 12, "%d", result); while (*p++) ; @@ -5099,7 +4951,7 @@ subevalvar(p, str, strloc, subtype, startloc, varflags, quotes) case VSQUESTION: if (*p != CTLENDVAR) { - outfmt(&errout, snlfmt, startp); + out2fmt(snlfmt, startp); error((char *)NULL); } error("%.*s: parameter %snot set", p - str - 1, @@ -6260,13 +6112,6 @@ init(void) { basepf.nextc = basepf.buf = basebuf; } - /* from output.c: */ - { -#ifdef USE_GLIBC_STDIO - initstreams(); -#endif - } - /* from var.c: */ { char **envp; @@ -6279,7 +6124,7 @@ init(void) { } } - fmtstr(ppid, sizeof(ppid), "%d", (int) getppid()); + snprintf(ppid, sizeof(ppid), "%d", (int) getppid()); setvar("PPID", ppid, 0); } } @@ -6328,19 +6173,6 @@ reset(void) { popredir(); } - /* from output.c: */ - { - out1 = &output; - out2 = &errout; -#ifdef USE_GLIBC_STDIO - if (memout.stream != NULL) - __closememout(); -#endif - if (memout.buf != NULL) { - ckfree(memout.buf); - memout.buf = NULL; - } - } } @@ -6513,10 +6345,7 @@ preadbuffer(void) } if (parsenleft == EOF_NLEFT || parsefile->buf == NULL) return PEOF; - flushout(&output); -#ifdef FLUSHERR - flushout(&errout); -#endif + flushall(); again: if (parselleft <= 0) { @@ -6557,9 +6386,6 @@ check: if (vflag) { out2str(parsenextc); -#ifdef FLUSHERR - flushout(out2); -#endif } *q = savec; @@ -6665,11 +6491,6 @@ fd0_redirected_p () { return fd0_redirected != 0; } -/* - * We also keep track of where fileno2 goes. - */ -static int fileno2 = 2; - static int openredirect (union node *); static void dupredirect (union node *, int, char[10 ]); static int openhere (union node *); @@ -6699,9 +6520,9 @@ static void setjobctl(int enable) if (enable) { do { /* while we are in the background */ #ifdef OLD_TTY_DRIVER - if (ioctl(fileno2, TIOCGPGRP, (char *)&initialpgrp) < 0) { + if (ioctl(2, TIOCGPGRP, (char *)&initialpgrp) < 0) { #else - initialpgrp = tcgetpgrp(fileno2); + initialpgrp = tcgetpgrp(2); if (initialpgrp < 0) { #endif out2str("sh: can't access tty; job cenabletrol turned off\n"); @@ -6716,7 +6537,7 @@ static void setjobctl(int enable) } } while (0); #ifdef OLD_TTY_DRIVER - if (ioctl(fileno2, TIOCGETD, (char *)&ldisc) < 0 || ldisc != NTTYDISC) { + if (ioctl(2, TIOCGETD, (char *)&ldisc) < 0 || ldisc != NTTYDISC) { out2str("sh: need new tty driver to run job cenabletrol; job cenabletrol turned off\n"); mflag = 0; return; @@ -6727,16 +6548,16 @@ static void setjobctl(int enable) setsignal(SIGTTIN); setpgid(0, rootpid); #ifdef OLD_TTY_DRIVER - ioctl(fileno2, TIOCSPGRP, (char *)&rootpid); + ioctl(2, TIOCSPGRP, (char *)&rootpid); #else - tcsetpgrp(fileno2, rootpid); + tcsetpgrp(2, rootpid); #endif } else { /* turning job cenabletrol off */ setpgid(0, initialpgrp); #ifdef OLD_TTY_DRIVER - ioctl(fileno2, TIOCSPGRP, (char *)&initialpgrp); + ioctl(2, TIOCSPGRP, (char *)&initialpgrp); #else - tcsetpgrp(fileno2, initialpgrp); + tcsetpgrp(2, initialpgrp); #endif setsignal(SIGTSTP); setsignal(SIGTTOU); @@ -6924,9 +6745,9 @@ fgcmd(argc, argv) error("job not created under job control"); pgrp = jp->ps[0].pid; #ifdef OLD_TTY_DRIVER - ioctl(fileno2, TIOCSPGRP, (char *)&pgrp); + ioctl(2, TIOCSPGRP, (char *)&pgrp); #else - tcsetpgrp(fileno2, pgrp); + tcsetpgrp(2, pgrp); #endif restartjob(jp); INTOFF; @@ -7022,10 +6843,10 @@ showjobs(change) procno = jp->nprocs; for (ps = jp->ps ; ; ps++) { /* for each process */ if (ps == jp->ps) - fmtstr(s, 64, "[%d] %ld ", jobno, + snprintf(s, 64, "[%d] %ld ", jobno, (long)ps->pid); else - fmtstr(s, 64, " %ld ", + snprintf(s, 64, " %ld ", (long)ps->pid); out1str(s); col = strlen(s); @@ -7033,7 +6854,7 @@ showjobs(change) if (ps->status == -1) { /* don't print anything */ } else if (WIFEXITED(ps->status)) { - fmtstr(s, 64, "Exit %d", + snprintf(s, 64, "Exit %d", WEXITSTATUS(ps->status)); } else { #ifdef JOBS @@ -7045,7 +6866,7 @@ showjobs(change) if ((i & 0x7F) < NSIG && sys_siglist[i & 0x7F]) strcpy(s, sys_siglist[i & 0x7F]); else - fmtstr(s, 64, "Signal %d", i & 0x7F); + snprintf(s, 64, "Signal %d", i & 0x7F); if (WCOREDUMP(ps->status)) strcat(s, " (core dumped)"); } @@ -7315,10 +7136,10 @@ forkshell(struct job *jp, union node *n, int mode) if (mode == FORK_FG) { /*** this causes superfluous TIOCSPGRPS ***/ #ifdef OLD_TTY_DRIVER - if (ioctl(fileno2, TIOCSPGRP, (char *)&pgrp) < 0) + if (ioctl(2, TIOCSPGRP, (char *)&pgrp) < 0) error("TIOCSPGRP failed, errno=%d", errno); #else - if (tcsetpgrp(fileno2, pgrp) < 0) + if (tcsetpgrp(2, pgrp) < 0) error("tcsetpgrp failed, errno=%d", errno); #endif } @@ -7436,10 +7257,10 @@ waitforjob(jp) #ifdef JOBS if (jp->jobctl) { #ifdef OLD_TTY_DRIVER - if (ioctl(fileno2, TIOCSPGRP, (char *)&mypgrp) < 0) + if (ioctl(2, TIOCSPGRP, (char *)&mypgrp) < 0) error("TIOCSPGRP failed, errno=%d\n", errno); #else - if (tcsetpgrp(fileno2, mypgrp) < 0) + if (tcsetpgrp(2, mypgrp) < 0) error("tcsetpgrp failed, errno=%d\n", errno); #endif } @@ -7549,22 +7370,19 @@ dowait(block, job) if (sig != 0 && sig != SIGINT && sig != SIGPIPE) { if (thisjob != job) - outfmt(out2, "%d: ", pid); + out2fmt("%d: ", pid); #ifdef JOBS if (sig == SIGTSTP && rootshell && iflag) - outfmt(out2, "%%%ld ", + out2fmt("%%%ld ", (long)(job - jobtab + 1)); #endif if (sig < NSIG && sys_siglist[sig]) out2str(sys_siglist[sig]); else - outfmt(out2, "Signal %d", sig); + out2fmt("Signal %d", sig); if (core) out2str(" - core dumped"); out2c('\n'); -#ifdef FLUSHERR - flushout(&errout); -#endif } else { TRACE(("Not printing status: status=%d, sig=%d\n", status, sig)); @@ -7889,10 +7707,8 @@ chkmail(int silent) if (stat(p, &statb) < 0) statb.st_size = 0; if (statb.st_size > mailtime[i] && ! silent) { - outfmt( - &errout, snlfmt, - pathopt? pathopt : "you have mail" - ); + out2fmt(snlfmt, + pathopt? pathopt : "you have mail"); } mailtime[i] = statb.st_size; } @@ -7980,9 +7796,6 @@ shell_main(argc, argv) reset(); if (exception == EXINT) { out2c('\n'); -#ifdef FLUSHERR - flushout(out2); -#endif } popstackmark(&smark); FORCEINTON; /* enable interrupts */ @@ -8079,7 +7892,7 @@ cmdloop(int top) inter++; showjobs(1); chkmail(0); - flushout(&output); + flushall(); } n = parsecmd(inter); /* showtree(n); DEBUG */ @@ -9607,7 +9420,7 @@ atend: err |= setvarsafe("OPTARG", s, 0); } else { - outfmt(&errout, "Illegal option -%c\n", c); + out2fmt("Illegal option -%c\n", c); (void) unsetvar("OPTARG"); } c = '?'; @@ -9626,7 +9439,7 @@ atend: c = ':'; } else { - outfmt(&errout, "No arg for -%c option\n", c); + out2fmt("No arg for -%c option\n", c); (void) unsetvar("OPTARG"); c = '?'; } @@ -9648,7 +9461,7 @@ bad: p = NULL; out: *optoff = p ? p - *(optnext - 1) : -1; - fmtstr(s, sizeof(s), "%d", *myoptind); + snprintf(s, sizeof(s), "%d", *myoptind); err |= setvarsafe("OPTIND", s, VNOFUNC); s[0] = c; s[1] = '\0'; @@ -9707,249 +9520,33 @@ nextopt(optstring) return c; } - -/* - * Shell output routines. We use our own output routines because: - * When a builtin command is interrupted we have to discard - * any pending output. - * When a builtin command appears in back quotes, we want to - * save the output of the command in a region obtained - * via malloc, rather than doing a fork and reading the - * output of the command via a pipe. - * Our output routines may be smaller than the stdio routines. - */ - - - -#ifndef USE_GLIBC_STDIO -static void __outstr (const char *, size_t, struct output*); -#endif - - -#ifndef USE_GLIBC_STDIO -static void -__outstr(const char *p, size_t len, struct output *dest) { - if (!dest->bufsize) { - dest->nleft = 0; - } else if (dest->buf == NULL) { - if (len > dest->bufsize && dest->fd == MEM_OUT) { - dest->bufsize = len; - } - INTOFF; - dest->buf = ckmalloc(dest->bufsize); - dest->nextc = dest->buf; - dest->nleft = dest->bufsize; - INTON; - } else if (dest->fd == MEM_OUT) { - int offset; - - offset = dest->bufsize; - INTOFF; - if (dest->bufsize >= len) { - dest->bufsize <<= 1; - } else { - dest->bufsize += len; - } - dest->buf = ckrealloc(dest->buf, dest->bufsize); - dest->nleft = dest->bufsize - offset; - dest->nextc = dest->buf + offset; - INTON; - } else { - flushout(dest); - } - - if (len < dest->nleft) { - dest->nleft -= len; - memcpy(dest->nextc, p, len); - dest->nextc += len; - return; - } - - if (xwrite(dest->fd, p, len) < len) - dest->flags |= OUTPUT_ERR; -} -#endif - - -static void -outstr(const char *p, struct output *file) -{ -#ifdef USE_GLIBC_STDIO - INTOFF; - fputs(p, file->stream); - INTON; -#else - size_t len; - - if (!*p) { - return; - } - len = strlen(p); - if ((file->nleft -= len) > 0) { - memcpy(file->nextc, p, len); - file->nextc += len; - return; - } - __outstr(p, len, file); -#endif -} - - -#ifndef USE_GLIBC_STDIO - - -static void -outcslow(c, dest) - char c; - struct output *dest; - { - __outstr(&c, 1, dest); -} -#endif - - static void flushall() { - flushout(&output); -#ifdef FLUSHERR - flushout(&errout); -#endif -} - - -static void -flushout(dest) - struct output *dest; - { -#ifdef USE_GLIBC_STDIO INTOFF; - fflush(dest->stream); + fflush(stdout); INTON; -#else - size_t len; - - len = dest->nextc - dest->buf; - if (dest->buf == NULL || !len || dest->fd < 0) - return; - dest->nextc = dest->buf; - dest->nleft = dest->bufsize; - if (xwrite(dest->fd, dest->buf, len) < len) - dest->flags |= OUTPUT_ERR; -#endif -} - - -static void -freestdout() { - if (output.buf) { - INTOFF; - ckfree(output.buf); - output.buf = NULL; - output.nleft = 0; - INTON; - } - output.flags = 0; } static void -#ifdef __STDC__ -outfmt(struct output *file, const char *fmt, ...) -#else -static void -outfmt(va_alist) - va_dcl -#endif +out2fmt(const char *fmt, ...) { va_list ap; -#ifndef __STDC__ - struct output *file; - const char *fmt; - - va_start(ap); - file = va_arg(ap, struct output *); - fmt = va_arg(ap, const char *); -#else va_start(ap, fmt); -#endif - doformat(file, fmt, ap); + vfprintf(stderr, fmt, ap); va_end(ap); } static void -#ifdef __STDC__ out1fmt(const char *fmt, ...) -#else -out1fmt(va_alist) - va_dcl -#endif { va_list ap; -#ifndef __STDC__ - const char *fmt; - - va_start(ap); - fmt = va_arg(ap, const char *); -#else va_start(ap, fmt); -#endif - doformat(out1, fmt, ap); + vfprintf(stdout, fmt, ap); va_end(ap); } -static void -#ifdef __STDC__ -fmtstr(char *outbuf, size_t length, const char *fmt, ...) -#else -fmtstr(va_alist) - va_dcl -#endif -{ - va_list ap; -#ifndef __STDC__ - char *outbuf; - size_t length; - const char *fmt; - - va_start(ap); - outbuf = va_arg(ap, char *); - length = va_arg(ap, size_t); - fmt = va_arg(ap, const char *); -#else - va_start(ap, fmt); -#endif - INTOFF; - vsnprintf(outbuf, length, fmt, ap); - INTON; -} - -#ifndef USE_GLIBC_STDIO - -static void -doformat(struct output *dest, const char *f, va_list ap) -{ - char *pm; - int size = BUFSIZ; - - while(size) { - int nchars; - - pm = xmalloc(size); - nchars = vsnprintf(pm, size, f, ap); - if(nchars > -1) { - outstr(pm, dest); - size = 0; - } - else - size *= 2; - free(pm); - } -} -#endif - - - /* * Version of write which resumes after a signal is caught. */ @@ -9980,29 +9577,6 @@ xwrite(int fd, const char *buf, int nbytes) } -#ifdef USE_GLIBC_STDIO -static void initstreams() { - output.stream = stdout; - errout.stream = stderr; -} - - -static void -openmemout() { - INTOFF; - memout.stream = open_memstream(&memout.buf, &memout.bufsize); - INTON; -} - - -static int -__closememout() { - int error; - error = fclose(memout.stream); - memout.stream = NULL; - return error; -} -#endif /* * Shell command parser. */ @@ -10722,7 +10296,9 @@ xxreadtoken() { c = pgetc_macro(); switch (c) { case ' ': case '\t': +#ifdef ASH_ALIAS case PEOA: +#endif continue; case '#': while ((c = pgetc()) != '\n' && c != PEOF); @@ -10969,9 +10545,11 @@ readtoken1(firstc, syntax, eofmark, striptabs) default: if (varnest == 0) goto endword; /* exit outer loop */ - if (c != PEOA) { +#ifdef ASH_ALIAS + if (c != PEOA) +#endif USTPUTC(c, out); - } + } c = pgetc_macro(); } @@ -11459,10 +11037,10 @@ synexpect(token) char msg[64]; if (token >= 0) { - fmtstr(msg, 64, "%s unexpected (expecting %s)", + snprintf(msg, 64, "%s unexpected (expecting %s)", tokname[lasttoken], tokname[token]); } else { - fmtstr(msg, 64, "%s unexpected", tokname[lasttoken]); + snprintf(msg, 64, "%s unexpected", tokname[lasttoken]); } synerror(msg); /* NOTREACHED */ @@ -11473,8 +11051,8 @@ static void synerror(const char *msg) { if (commandname) - outfmt(&errout, "%s: %d: ", commandname, startlinno); - outfmt(&errout, "Syntax error: %s\n", msg); + out2fmt("%s: %d: ", commandname, startlinno); + out2fmt("Syntax error: %s\n", msg); error((char *)NULL); /* NOTREACHED */ } @@ -11484,7 +11062,7 @@ synerror(const char *msg) * called by editline -- any expansions to the prompt * should be added here. */ -static const char * +static inline const char * getprompt(void *unused) { switch (whichprompt) { @@ -11525,7 +11103,7 @@ setprompt(int which) * old file descriptors are stashed away so that the redirection can be * undone by calling popredir. If the REDIR_BACKQ flag is set, then the * standard output, and the standard error if it becomes a duplicate of - * stdout, is saved in memory. + * stdout. */ static void @@ -11560,8 +11138,7 @@ redirect(redir, flags) INTOFF; newfd = openredirect(n); - if (((flags & REDIR_PUSH) && sv->renamed[fd] == EMPTY) || - (fd == fileno2)) { + if ((flags & REDIR_PUSH) && sv->renamed[fd] == EMPTY) { if (newfd == fd) { try++; } else if ((i = fcntl(fd, F_DUPFD, 10)) == -1) { @@ -11587,9 +11164,6 @@ redirect(redir, flags) if (flags & REDIR_PUSH) { sv->renamed[fd] = i; } - if (fd == fileno2) { - fileno2 = i; - } } } else if (fd != newfd) { close(fd); @@ -11600,10 +11174,6 @@ redirect(redir, flags) dupredirect(n, newfd, memory); INTON; } - if (memory[1]) - out1 = &memout; - if (memory[2]) - out2 = &memout; } @@ -11765,9 +11335,6 @@ popredir(void) dup_as_newfd(rp->renamed[i], i); close(rp->renamed[i]); } - if (rp->renamed[i] == fileno2) { - fileno2 = i; - } } } redirlist = rp->next; @@ -11788,17 +11355,10 @@ clearredir(void) { for (i = 0 ; i < 10 ; i++) { if (rp->renamed[i] >= 0) { close(rp->renamed[i]); - if (rp->renamed[i] == fileno2) { - fileno2 = -1; - } } rp->renamed[i] = EMPTY; } } - if (fileno2 != 2 && fileno2 >= 0) { - close(fileno2); - fileno2 = -1; - } } @@ -13528,7 +13088,7 @@ findvar(struct var **vpp, const char *name) /* * Copyright (c) 1999 Herbert Xu <herbert@debian.org> * This file contains code for the times builtin. - * $Id: ash.c,v 1.5 2001/07/05 05:24:12 andersen Exp $ + * $Id: ash.c,v 1.6 2001/07/06 04:26:23 andersen Exp $ */ static int timescmd (int argc, char **argv) { |