diff options
author | Denis Vlasenko <vda.linux@googlemail.com> | 2007-02-20 01:43:01 +0300 |
---|---|---|
committer | Denis Vlasenko <vda.linux@googlemail.com> | 2007-02-20 01:43:01 +0300 |
commit | b012b10dbd1d0a476de8674e195eb008e505e608 (patch) | |
tree | f74c91ae2b86de78c148cb6288baa1a23d288b49 /shell | |
parent | e5570da2cffbec12b99d99a11d20c5f2371d5b0f (diff) |
ash: rearrange code to reduce forward references, rename some functions
Diffstat (limited to 'shell')
-rw-r--r-- | shell/ash.c | 1225 |
1 files changed, 568 insertions, 657 deletions
diff --git a/shell/ash.c b/shell/ash.c index 242e3b765..ffe29e066 100644 --- a/shell/ash.c +++ b/shell/ash.c @@ -31,7 +31,6 @@ * */ - /* * The follow should be set to reflect the type of system you have: * JOBS -> 1 if you have Berkeley job control, 0 otherwise. @@ -43,55 +42,29 @@ * a quit signal will generate a core dump. */ #define DEBUG 0 - - #define IFS_BROKEN - #define PROFILE 0 - -#include "busybox.h" +#if ENABLE_ASH_JOB_CONTROL +#define JOBS 1 +#else +#define JOBS 0 +#endif #if DEBUG #define _GNU_SOURCE #endif - -#include <sys/types.h> -#include <sys/ioctl.h> -#include <sys/param.h> -#include <sys/resource.h> -#include <sys/stat.h> -#include <sys/wait.h> - -#include <stdio.h> -#include <stdlib.h> -#include <string.h> -#include <unistd.h> - -#include <stdarg.h> -#include <stddef.h> -#include <assert.h> -#include <ctype.h> -#include <dirent.h> -#include <errno.h> -#include <fcntl.h> -#include <limits.h> +#include "busybox.h" #include <paths.h> #include <setjmp.h> -#include <signal.h> -/*#include <stdint.h>*/ -#include <time.h> #include <fnmatch.h> - -#if ENABLE_ASH_JOB_CONTROL -#define JOBS 1 -#else -#define JOBS 0 -#endif - #if JOBS || ENABLE_ASH_READ_NCHARS #include <termios.h> #endif +#if defined(__uClinux__) +#error "Do not even bother, ash will not run on uClinux" +#endif + #ifdef __GLIBC__ /* glibc sucks */ @@ -100,59 +73,90 @@ static int *dash_errno; #define errno (*dash_errno) #endif -#if defined(__uClinux__) -#error "Do not even bother, ash will not run on uClinux" -#endif - -#if DEBUG -#define _DIAGASSERT(assert_expr) assert(assert_expr) -#else -#define _DIAGASSERT(assert_expr) -#endif - #if ENABLE_ASH_ALIAS -/* alias.h */ - -#define ALIASINUSE 1 -#define ALIASDEAD 2 - +#define ALIASINUSE 1 +#define ALIASDEAD 2 struct alias { struct alias *next; char *name; char *val; int flag; }; - -static struct alias *lookupalias(const char *, int); static int aliascmd(int, char **); static int unaliascmd(int, char **); -static void rmaliases(void); -static int unalias(const char *); static void printalias(const struct alias *); #endif -/* cd.h */ +/* ============ Shell options */ -static void setpwd(const char *, int); +static const char *const optletters_optnames[] = { + "e" "errexit", + "f" "noglob", + "I" "ignoreeof", + "i" "interactive", + "m" "monitor", + "n" "noexec", + "s" "stdin", + "x" "xtrace", + "v" "verbose", + "C" "noclobber", + "a" "allexport", + "b" "notify", + "u" "nounset", + "\0" "vi", +#if DEBUG + "\0" "nolog", + "\0" "debug", +#endif +}; -/* error.h */ +#define optletters(n) optletters_optnames[(n)][0] +#define optnames(n) (&optletters_optnames[(n)][1]) +#define NOPTS (sizeof(optletters_optnames)/sizeof(optletters_optnames[0])) -/* - * Types of operations (passed to the errmsg routine). - */ +static char optlist[NOPTS]; +#define eflag optlist[0] +#define fflag optlist[1] +#define Iflag optlist[2] +#define iflag optlist[3] +#define mflag optlist[4] +#define nflag optlist[5] +#define sflag optlist[6] +#define xflag optlist[7] +#define vflag optlist[8] +#define Cflag optlist[9] +#define aflag optlist[10] +#define bflag optlist[11] +#define uflag optlist[12] +#define viflag optlist[13] +#if DEBUG +#define nolog optlist[14] +#define debug optlist[15] +#endif -static const char not_found_msg[] = "%s: not found"; +/* ============ Misc data */ -#define E_OPEN "No such file" /* opening a file */ -#define E_CREAT "Directory nonexistent" /* creating a file */ -#define E_EXEC not_found_msg+4 /* executing a program */ +/* pid of main shell */ +static int rootpid; +/* shell level: 0 for the main shell, 1 for its children, and so on */ +static int shlvl; +#define rootshell (!shlvl) +/* trap handler commands */ +static char *trap[NSIG]; +/* current value of signal */ +static char sigmode[NSIG - 1]; +/* indicates specified signal received */ +static char gotsig[NSIG - 1]; +static char *arg0; /* value of $0 */ -/* + +/* ============ Interrupts / exceptions + * * We enclose jmp_buf in a structure so that we can declare pointers to * jump locations. The global variable handler contains the location to * jump to when an exception occurs, and the global variable exception @@ -161,16 +165,11 @@ static const char not_found_msg[] = "%s: not found"; * to an inner scope, set handler to point to a jmploc structure for the * inner scope, and restore handler on exit from the scope. */ - struct jmploc { jmp_buf loc; }; - static struct jmploc *handler; static int exception; -static volatile int suppressint; -static volatile sig_atomic_t intpending; - /* exceptions */ #define EXINT 0 /* SIGINT received */ #define EXERROR 1 /* a generic error */ @@ -178,8 +177,8 @@ static volatile sig_atomic_t intpending; #define EXEXEC 3 /* command execution failed */ #define EXEXIT 4 /* exit the shell */ #define EXSIG 5 /* trapped signal in wait(1) */ - - +static volatile int suppressint; +static volatile sig_atomic_t intpending; /* do we generate EXSIG events */ static int exsig; /* last pending signal */ @@ -191,73 +190,323 @@ static volatile sig_atomic_t pendingsigs; * much more efficient and portable. (But hacking the kernel is so much * more fun than worrying about efficiency and portability. :-)) */ - #define xbarrier() ({ __asm__ __volatile__ ("": : :"memory"); }) -#define INTOFF \ +#define INT_OFF \ ({ \ suppressint++; \ xbarrier(); \ 0; \ }) -#define SAVEINT(v) ((v) = suppressint) -#define RESTOREINT(v) \ - ({ \ - xbarrier(); \ - suppressint = (v); \ - if (suppressint == 0 && intpending) onint(); \ - 0; \ - }) -#define EXSIGON() \ - ({ \ - exsig++; \ - xbarrier(); \ - if (pendingsigs) \ - exraise(EXSIG); \ - 0; \ - }) -/* EXSIG is turned off by evalbltin(). */ +/* + * Called to raise an exception. Since C doesn't include exceptions, we + * just do a longjmp to the exception handler. The type of exception is + * stored in the global variable "exception". + */ +static void raise_exception(int) ATTRIBUTE_NORETURN; +static void +raise_exception(int e) +{ +#if DEBUG + if (handler == NULL) + abort(); +#endif + INT_OFF; + exception = e; + longjmp(handler->loc, 1); +} -static void exraise(int) ATTRIBUTE_NORETURN; -static void onint(void) ATTRIBUTE_NORETURN; - -static void sh_error(const char *, ...) ATTRIBUTE_NORETURN; -static void exerror(int, const char *, ...) ATTRIBUTE_NORETURN; +/* + * Called from trap.c when a SIGINT is received. (If the user specifies + * that SIGINT is to be trapped or ignored using the trap builtin, then + * this routine is not called.) Suppressint is nonzero when interrupts + * are held using the INT_OFF macro. (The test for iflag is just + * defensive programming.) + */ +static void raise_interrupt(void) ATTRIBUTE_NORETURN; +static void +raise_interrupt(void) +{ + int i; -static void sh_warnx(const char *, ...); + intpending = 0; + i = EXSIG; + if (gotsig[SIGINT - 1] && !trap[SIGINT]) { + if (!(rootshell && iflag)) { + signal(SIGINT, SIG_DFL); + raise(SIGINT); + } + i = EXINT; + } + raise_exception(i); + /* NOTREACHED */ +} #if ENABLE_ASH_OPTIMIZE_FOR_SIZE -static void -inton(void) +static void int_on(void) { if (--suppressint == 0 && intpending) { - onint(); + raise_interrupt(); } } -#define INTON inton() -static void forceinton(void) +#define INT_ON int_on() +static void force_int_on(void) { suppressint = 0; if (intpending) - onint(); + raise_interrupt(); } -#define FORCEINTON forceinton() +#define FORCE_INT_ON force_int_on() #else -#define INTON \ +#define INT_ON \ ({ \ xbarrier(); \ - if (--suppressint == 0 && intpending) onint(); \ + if (--suppressint == 0 && intpending) raise_interrupt(); \ 0; \ }) -#define FORCEINTON \ +#define FORCE_INT_ON \ ({ \ xbarrier(); \ suppressint = 0; \ - if (intpending) onint(); \ + if (intpending) raise_interrupt(); \ 0; \ }) #endif /* ASH_OPTIMIZE_FOR_SIZE */ +#define SAVE_INT(v) ((v) = suppressint) + +#define RESTORE_INT(v) \ + ({ \ + xbarrier(); \ + suppressint = (v); \ + if (suppressint == 0 && intpending) raise_interrupt(); \ + 0; \ + }) + +#define EXSIGON \ + ({ \ + exsig++; \ + xbarrier(); \ + if (pendingsigs) \ + raise_exception(EXSIG); \ + 0; \ + }) +/* EXSIG is turned off by evalbltin(). */ + + +/* ============ stdout/stderr output */ + +static void +outstr(const char *p, FILE *file) +{ + INT_OFF; + fputs(p, file); + INT_ON; +} + +static void +flush_stdout_stderr(void) +{ + INT_OFF; + fflush(stdout); + fflush(stderr); + INT_ON; +} + +static void +flush_stderr(void) +{ + INT_OFF; + fflush(stderr); + INT_ON; +} + +static void +outcslow(int c, FILE *dest) +{ + INT_OFF; + putc(c, dest); + fflush(dest); + INT_ON; +} + +static int out1fmt(const char *, ...) __attribute__((__format__(__printf__,1,2))); +static int +out1fmt(const char *fmt, ...) +{ + va_list ap; + int r; + + INT_OFF; + va_start(ap, fmt); + r = vprintf(fmt, ap); + va_end(ap); + INT_ON; + return r; +} + +static int fmtstr(char *, size_t, const char *, ...) __attribute__((__format__(__printf__,3,4))); +static int +fmtstr(char *outbuf, size_t length, const char *fmt, ...) +{ + va_list ap; + int ret; + + va_start(ap, fmt); + INT_OFF; + ret = vsnprintf(outbuf, length, fmt, ap); + va_end(ap); + INT_ON; + return ret; +} + +static void +out1str(const char *p) +{ + outstr(p, stdout); +} + +static void +out2str(const char *p) +{ + outstr(p, stderr); + flush_stderr(); +} + + +/* ============ Parser data + * + * ash_vmsg() needs parsefile->fd, hence parsefile definition is moved up. + */ + +struct strpush { + struct strpush *prev; /* preceding string on stack */ + char *prevstring; + int prevnleft; +#if ENABLE_ASH_ALIAS + struct alias *ap; /* if push was associated with an alias */ +#endif + char *string; /* remember the string since it may change */ +}; + +struct parsefile { + struct parsefile *prev; /* preceding file on stack */ + int linno; /* current line */ + int fd; /* file descriptor (or -1 if string) */ + int nleft; /* number of chars left in this line */ + int lleft; /* number of chars left in this buffer */ + char *nextc; /* next char in buffer */ + char *buf; /* input buffer */ + struct strpush *strpush; /* for pushing strings at this level */ + struct strpush basestrpush; /* so pushing one is fast */ +}; + +static struct parsefile basepf; /* top level input file */ +static struct parsefile *parsefile = &basepf; /* current input file */ +static int startlinno; /* line # where last token started */ +static char *commandname; /* currently executing command */ +static struct strlist *cmdenviron; /* environment for builtin command */ +static int exitstatus; /* exit status of last command */ +static int back_exitstatus; /* exit status of backquoted command */ + + +/* ============ Message printing */ + +static void +ash_vmsg(const char *msg, va_list ap) +{ + fprintf(stderr, "%s: ", arg0); + if (commandname) { + const char *fmt = (!iflag || parsefile->fd) ? + "%s: %d: " : "%s: "; + fprintf(stderr, fmt, commandname, startlinno); + } + vfprintf(stderr, msg, ap); + outcslow('\n', stderr); +} + +/* + * Exverror is called to raise the error exception. If the second argument + * is not NULL then error prints an error message using printf style + * formatting. It then raises the error exception. + */ +static void ash_vmsg_and_raise(int, const char *, va_list) ATTRIBUTE_NORETURN; +static void +ash_vmsg_and_raise(int cond, const char *msg, va_list ap) +{ +#if DEBUG + if (msg) { + TRACE(("ash_vmsg_and_raise(%d, \"", cond)); + TRACEV((msg, ap)); + TRACE(("\") pid=%d\n", getpid())); + } else + TRACE(("ash_vmsg_and_raise(%d, NULL) pid=%d\n", cond, getpid())); + if (msg) +#endif + ash_vmsg(msg, ap); + + flush_stdout_stderr(); + raise_exception(cond); + /* NOTREACHED */ +} + +static void ash_msg_and_raise_error(const char *, ...) ATTRIBUTE_NORETURN; +static void +ash_msg_and_raise_error(const char *msg, ...) +{ + va_list ap; + + va_start(ap, msg); + ash_vmsg_and_raise(EXERROR, msg, ap); + /* NOTREACHED */ + va_end(ap); +} + +static void ash_msg_and_raise(int, const char *, ...) ATTRIBUTE_NORETURN; +static void +ash_msg_and_raise(int cond, const char *msg, ...) +{ + va_list ap; + + va_start(ap, msg); + ash_vmsg_and_raise(cond, msg, ap); + /* NOTREACHED */ + va_end(ap); +} + +/* + * error/warning routines for external builtins + */ +static void +ash_msg(const char *fmt, ...) +{ + va_list ap; + + va_start(ap, fmt); + ash_vmsg(fmt, ap); + va_end(ap); +} + +/* + * Return a string describing an error. The returned string may be a + * pointer to a static buffer that will be overwritten on the next call. + * Action describes the operation that got the error. + */ +static const char * +errmsg(int e, const char *em) +{ + if (e == ENOENT || e == ENOTDIR) { + return em; + } + return strerror(e); +} + + +/* ============ Unsorted yet */ + + +static void setpwd(const char *, int); + /* expand.h */ struct strlist { @@ -297,10 +546,6 @@ static void expari(int); /* eval.h */ -static char *commandname; /* currently executing command */ -static struct strlist *cmdenviron; /* environment for builtin command */ -static int exitstatus; /* exit status of last command */ -static int back_exitstatus; /* exit status of backquoted command */ struct backcmd { /* result of evalbackcmd */ @@ -511,31 +756,7 @@ static int parselleft; /* copy of parsefile->lleft */ /* next character in input buffer */ static char *parsenextc; /* copy of parsefile->nextc */ -struct strpush { - struct strpush *prev; /* preceding string on stack */ - char *prevstring; - int prevnleft; -#if ENABLE_ASH_ALIAS - struct alias *ap; /* if push was associated with an alias */ -#endif - char *string; /* remember the string since it may change */ -}; - -struct parsefile { - struct parsefile *prev; /* preceding file on stack */ - int linno; /* current line */ - int fd; /* file descriptor (or -1 if string) */ - int nleft; /* number of chars left in this line */ - int lleft; /* number of chars left in this buffer */ - char *nextc; /* next char in buffer */ - char *buf; /* input buffer */ - struct strpush *strpush; /* for pushing strings at this level */ - struct strpush basestrpush; /* so pushing one is fast */ -}; - -static struct parsefile basepf; /* top level input file */ #define basebuf bb_common_bufsiz1 /* buffer for top level input file */ -static struct parsefile *parsefile = &basepf; /* current input file */ static int tokpushback; /* last token pushed back */ @@ -550,7 +771,6 @@ static struct nodelist *backquotelist; static union node *redirnode; static struct heredoc *heredoc; static int quoteflag; /* set if (part of) last token was quoted */ -static int startlinno; /* line # where last token started */ static union node *parsecmd(int); static void fixredir(union node *, const char *, int); @@ -1597,32 +1817,10 @@ static int nullredirs; extern char **environ; -/* output.h */ - - -static void outstr(const char *, FILE *); -static void outcslow(int, FILE *); -static void flushall(void); -static void flusherr(void); -static int out1fmt(const char *, ...) - __attribute__((__format__(__printf__,1,2))); -static int fmtstr(char *, size_t, const char *, ...) - __attribute__((__format__(__printf__,3,4))); static int preverrout_fd; /* save fd2 before print debug if xflag is set. */ -static void out1str(const char *p) -{ - outstr(p, stdout); -} - -static void out2str(const char *p) -{ - outstr(p, stderr); - flusherr(); -} - /* * Initialization code. */ @@ -1790,12 +1988,6 @@ static void showjobs(FILE *, int); /* main.h */ -/* pid of main shell */ -static int rootpid; -/* shell level: 0 for the main shell, 1 for its children, and so on */ -static int shlvl; -#define rootshell (!shlvl) - static void readcmdfile(char *); static int cmdloop(int); @@ -1871,8 +2063,6 @@ static char *_STPUTC(int c, char *p) #define ungrabstackstr(s, p) stunalloc((s)) #define stackstrend() ((void *)sstrend) -#define ckfree(p) free((pointer)(p)) - /* mystring.h */ @@ -1900,59 +2090,6 @@ struct shparam { }; -#define eflag optlist[0] -#define fflag optlist[1] -#define Iflag optlist[2] -#define iflag optlist[3] -#define mflag optlist[4] -#define nflag optlist[5] -#define sflag optlist[6] -#define xflag optlist[7] -#define vflag optlist[8] -#define Cflag optlist[9] -#define aflag optlist[10] -#define bflag optlist[11] -#define uflag optlist[12] -#define viflag optlist[13] - -#if DEBUG -#define nolog optlist[14] -#define debug optlist[15] -#endif - -/* options.c */ - - -static const char *const optletters_optnames[] = { - "e" "errexit", - "f" "noglob", - "I" "ignoreeof", - "i" "interactive", - "m" "monitor", - "n" "noexec", - "s" "stdin", - "x" "xtrace", - "v" "verbose", - "C" "noclobber", - "a" "allexport", - "b" "notify", - "u" "nounset", - "\0" "vi", -#if DEBUG - "\0" "nolog", - "\0" "debug", -#endif -}; - -#define optletters(n) optletters_optnames[(n)][0] -#define optnames(n) (&optletters_optnames[(n)][1]) - -#define NOPTS (sizeof(optletters_optnames)/sizeof(optletters_optnames[0])) - -static char optlist[NOPTS]; - - -static char *arg0; /* value of $0 */ static struct shparam shellparam; /* $@ current positional parameters */ static char **argptr; /* argument list for builtin commands */ static char *optionarg; /* set by nextopt (like getopt) */ @@ -1998,13 +2135,6 @@ static void opentrace(void); /* trap.h */ -/* trap handler commands */ -static char *trap[NSIG]; -/* current value of signal */ -static char sigmode[NSIG - 1]; -/* indicates specified signal received */ -static char gotsig[NSIG - 1]; - static void clear_traps(void); static void setsignal(int); static void ignoresig(int); @@ -2094,10 +2224,10 @@ setalias(const char *name, const char *val) app = __lookupalias(name); ap = *app; - INTOFF; + INT_OFF; if (ap) { if (!(ap->flag & ALIASINUSE)) { - ckfree(ap->val); + free(ap->val); } ap->val = savestr(val); ap->flag &= ~ALIASDEAD; @@ -2110,7 +2240,7 @@ setalias(const char *name, const char *val) ap->next = 0; *app = ap; } - INTON; + INT_ON; } static int @@ -2121,9 +2251,9 @@ unalias(const char *name) app = __lookupalias(name); if (*app) { - INTOFF; + INT_OFF; *app = freealias(*app); - INTON; + INT_ON; return 0; } @@ -2136,7 +2266,7 @@ rmaliases(void) struct alias *ap, **app; int i; - INTOFF; + INT_OFF; for (i = 0; i < ATABSIZE; i++) { app = &atab[i]; for (ap = *app; ap; ap = *app) { @@ -2146,7 +2276,7 @@ rmaliases(void) } } } - INTON; + INT_ON; } static struct alias * @@ -2228,9 +2358,9 @@ freealias(struct alias *ap) } next = ap->next; - ckfree(ap->name); - ckfree(ap->val); - ckfree(ap); + free(ap->name); + free(ap->val); + free(ap); return next; } @@ -2356,7 +2486,7 @@ cdcmd(int argc, char **argv) break; } } while (path); - sh_error("can't cd to %s", dest); + ash_msg_and_raise_error("can't cd to %s", dest); /* NOTREACHED */ out: if (flags & CD_PRINT) @@ -2438,7 +2568,7 @@ docd(const char *dest, int flags) TRACE(("docd(\"%s\", %d) called\n", dest, flags)); - INTOFF; + INT_OFF; if (!(flags & CD_PHYSICAL)) { dir = updatepwd(dest); if (dir) @@ -2450,7 +2580,7 @@ docd(const char *dest, int flags) setpwd(dir, 1); hashcd(); out: - INTON; + INT_ON; return err; } @@ -2490,7 +2620,7 @@ setpwd(const char *val, int setold) if (setold) { setvar("OLDPWD", oldcur, VEXPORT); } - INTOFF; + INT_OFF; if (physdir != nullstr) { if (physdir != oldcur) free(physdir); @@ -2507,161 +2637,10 @@ setpwd(const char *val, int setold) free(oldcur); } curdir = dir; - INTON; + INT_ON; setvar("PWD", dir, VEXPORT); } -/* error.c */ - -/* - * Errors and exceptions. - */ - -/* - * Code to handle exceptions in C. - */ - - -static void exverror(int, const char *, va_list) ATTRIBUTE_NORETURN; - -/* - * Called to raise an exception. Since C doesn't include exceptions, we - * just do a longjmp to the exception handler. The type of exception is - * stored in the global variable "exception". - */ -static void -exraise(int e) -{ -#if DEBUG - if (handler == NULL) - abort(); -#endif - INTOFF; - - exception = e; - longjmp(handler->loc, 1); -} - - -/* - * Called from trap.c when a SIGINT is received. (If the user specifies - * that SIGINT is to be trapped or ignored using the trap builtin, then - * this routine is not called.) Suppressint is nonzero when interrupts - * are held using the INTOFF macro. (The test for iflag is just - * defensive programming.) - */ -static void -onint(void) -{ - int i; - - intpending = 0; - i = EXSIG; - if (gotsig[SIGINT - 1] && !trap[SIGINT]) { - if (!(rootshell && iflag)) { - signal(SIGINT, SIG_DFL); - raise(SIGINT); - } - i = EXINT; - } - exraise(i); - /* NOTREACHED */ -} - -static void -exvwarning(const char *msg, va_list ap) -{ - FILE *errs; - - errs = stderr; - fprintf(errs, "%s: ", arg0); - if (commandname) { - const char *fmt = (!iflag || parsefile->fd) ? - "%s: %d: " : "%s: "; - fprintf(errs, fmt, commandname, startlinno); - } - vfprintf(errs, msg, ap); - outcslow('\n', errs); -} - -/* - * Exverror is called to raise the error exception. If the second argument - * is not NULL then error prints an error message using printf style - * formatting. It then raises the error exception. - */ -static void -exverror(int cond, const char *msg, va_list ap) -{ -#if DEBUG - if (msg) { - TRACE(("exverror(%d, \"", cond)); - TRACEV((msg, ap)); - TRACE(("\") pid=%d\n", getpid())); - } else - TRACE(("exverror(%d, NULL) pid=%d\n", cond, getpid())); - if (msg) -#endif - exvwarning(msg, ap); - - flushall(); - exraise(cond); - /* NOTREACHED */ -} - - -static void -sh_error(const char *msg, ...) -{ - va_list ap; - - va_start(ap, msg); - exverror(EXERROR, msg, ap); - /* NOTREACHED */ - va_end(ap); -} - - -static void -exerror(int cond, const char *msg, ...) -{ - va_list ap; - - va_start(ap, msg); - exverror(cond, msg, ap); - /* NOTREACHED */ - va_end(ap); -} - - -/* - * error/warning routines for external builtins - */ -static void -sh_warnx(const char *fmt, ...) -{ - va_list ap; - - va_start(ap, fmt); - exvwarning(fmt, ap); - va_end(ap); -} - - -/* - * Return a string describing an error. The returned string may be a - * pointer to a static buffer that will be overwritten on the next call. - * Action describes the operation that got the error. - */ -static const char * -errmsg(int e, const char *em) -{ - if (e == ENOENT || e == ENOTDIR) { - return em; - } - return strerror(e); -} - - /* eval.c */ /* @@ -2870,7 +2849,7 @@ evaltree(union node *n, int flags) if (flags & EV_EXIT) { exexit: - exraise(EXEXIT); + raise_exception(EXEXIT); } } @@ -2998,10 +2977,10 @@ evalsubshell(union node *n, int flags) expredir(n->nredir.redirect); if (!backgnd && flags & EV_EXIT && !trap[0]) goto nofork; - INTOFF; + INT_OFF; jp = makejob(n, 1); if (forkshell(jp, n, backgnd) == 0) { - INTON; + INT_ON; flags |= EV_EXIT; if (backgnd) flags &=~ EV_TESTED; @@ -3014,7 +2993,7 @@ nofork: if (! backgnd) status = waitforjob(jp); exitstatus = status; - INTON; + INT_ON; } @@ -3046,7 +3025,7 @@ expredir(union node *n) if (fn.list != NULL) fixredir(redir, fn.list->text, 1); else - sh_error("redir error"); + ash_msg_and_raise_error("redir error"); } break; } @@ -3074,7 +3053,7 @@ evalpipe(union node *n, int flags) for (lp = n->npipe.cmdlist ; lp ; lp = lp->next) pipelen++; flags |= EV_EXIT; - INTOFF; + INT_OFF; jp = makejob(n, pipelen); prevfd = -1; for (lp = n->npipe.cmdlist ; lp ; lp = lp->next) { @@ -3083,11 +3062,11 @@ evalpipe(union node *n, int flags) if (lp->next) { if (pipe(pip) < 0) { close(prevfd); - sh_error("Pipe call failed"); + ash_msg_and_raise_error("Pipe call failed"); } } if (forkshell(jp, lp->n, n->npipe.backgnd) == 0) { - INTON; + INT_ON; if (pip[1] >= 0) { close(pip[0]); } @@ -3111,7 +3090,7 @@ evalpipe(union node *n, int flags) exitstatus = waitforjob(jp); TRACE(("evalpipe: job done exit status %d\n", exitstatus)); } - INTON; + INT_ON; } @@ -3142,10 +3121,10 @@ evalbackcmd(union node *n, struct backcmd *result) struct job *jp; if (pipe(pip) < 0) - sh_error("Pipe call failed"); + ash_msg_and_raise_error("Pipe call failed"); jp = makejob(n, 1); if (forkshell(jp, n, FORK_NOJOB) == 0) { - FORCEINTON; + FORCE_INT_ON; close(pip[0]); if (pip[1] != 1) { close(1); @@ -3250,8 +3229,7 @@ evalcommand(union node *cmd, int flags) *arglist.lastp = NULL; argc = 0; - if (cmd->ncmd.args) - { + if (cmd->ncmd.args) { bcmd = find_builtin(cmd->ncmd.args->narg.text); pseudovarflag = bcmd && IS_BUILTIN_ASSIGN(bcmd); } @@ -3337,7 +3315,7 @@ evalcommand(union node *cmd, int flags) find_command(argv[0], &cmdentry, cmd_flag, path); if (cmdentry.cmdtype == CMDUNKNOWN) { status = 127; - flusherr(); + flush_stderr(); goto bail; } @@ -3367,7 +3345,7 @@ evalcommand(union node *cmd, int flags) if (status) { /* We have a redirection error. */ if (spclbltin > 0) - exraise(EXERROR); + raise_exception(EXERROR); bail: exitstatus = status; goto out; @@ -3378,14 +3356,14 @@ evalcommand(union node *cmd, int flags) default: /* Fork off a child process if necessary. */ if (!(flags & EV_EXIT) || trap[0]) { - INTOFF; + INT_OFF; jp = makejob(cmd, 1); if (forkshell(jp, cmd, FORK_FG) != 0) { exitstatus = waitforjob(jp); - INTON; + INT_ON; break; } - FORCEINTON; + FORCE_INT_ON; } listsetvar(varlist.list, VEXPORT|VSTACK); shellexec(argv, path, cmdentry.u.index); @@ -3425,7 +3403,7 @@ evalcommand(union node *cmd, int flags) raise: longjmp(handler->loc, 1); } - FORCEINTON; + FORCE_INT_ON; } break; @@ -3465,7 +3443,7 @@ evalbltin(const struct builtincmd *cmd, int argc, char **argv) argptr = argv + 1; optptr = NULL; /* initialize nextopt */ exitstatus = (*cmd->builtin)(argc, argv); - flushall(); + flush_stdout_stderr(); cmddone: exitstatus |= ferror(stdout); clearerr(stdout); @@ -3491,14 +3469,14 @@ evalfun(struct funcnode *func, int argc, char **argv, int flags) if (e) { goto funcdone; } - INTOFF; + INT_OFF; savehandler = handler; handler = &jmploc; localvars = NULL; shellparam.malloc = 0; func->count++; funcnest++; - INTON; + INT_ON; shellparam.nparam = argc - 1; shellparam.p = argv + 1; #if ENABLE_ASH_GETOPTS @@ -3507,7 +3485,7 @@ evalfun(struct funcnode *func, int argc, char **argv, int flags) #endif evaltree(&func->n, flags & EV_TESTED); funcdone: - INTOFF; + INT_OFF; funcnest--; freefunc(func); poplocalvars(); @@ -3515,7 +3493,7 @@ funcdone: freeparam(&shellparam); shellparam = saveparam; handler = savehandler; - INTON; + INT_ON; evalskip &= ~SKIPFUNC; return e; } @@ -3580,7 +3558,7 @@ breakcmd(int argc, char **argv) int n = argc > 1 ? number(argv[1]) : 1; if (n <= 0) - sh_error(illnum, argv[1]); + ash_msg_and_raise_error(illnum, argv[1]); if (n > loopnest) n = loopnest; if (n > 0) { @@ -3716,7 +3694,7 @@ shellexec(char **argv, const char *path, int idx) exitstatus = exerrno; TRACE(("shellexec failed for %s, errno %d, suppressint %d\n", argv[0], e, suppressint )); - exerror(EXEXEC, "%s: %s", argv[0], errmsg(e, E_EXEC)); + ash_msg_and_raise(EXEXEC, "%s: %s", argv[0], errmsg(e, "not found")); /* NOTREACHED */ } @@ -3758,7 +3736,7 @@ tryexec(char *cmd, char **argv, char **envp) execve(cmd, argv, envp); #endif if (repeated++) { - ckfree(argv); + free(argv); } else if (errno == ENOEXEC) { char **ap; char **new; @@ -4020,7 +3998,7 @@ find_command(char *name, struct cmdentry *entry, int act, const char *path) readcmdfile(fullname); cmdp = cmdlookup(name, 0); if (cmdp == NULL || cmdp->cmdtype != CMDFUNCTION) - sh_error("%s not defined in %s", name, fullname); + ash_msg_and_raise_error("%s not defined in %s", name, fullname); stunalloc(fullname); goto success; } @@ -4030,11 +4008,11 @@ find_command(char *name, struct cmdentry *entry, int act, const char *path) entry->u.index = idx; return; } - INTOFF; + INT_OFF; cmdp = cmdlookup(name, 1); cmdp->cmdtype = CMDNORMAL; cmdp->param.index = idx; - INTON; + INT_ON; goto success; } @@ -4042,7 +4020,7 @@ find_command(char *name, struct cmdentry *entry, int act, const char *path) if (cmdp && updatetbl) delete_cmd_entry(); if (act & DO_ERR) - sh_warnx("%s: %s", name, errmsg(e, E_EXEC)); + ash_msg("%s: %s", name, errmsg(e, "not found")); entry->cmdtype = CMDUNKNOWN; return; @@ -4052,11 +4030,11 @@ find_command(char *name, struct cmdentry *entry, int act, const char *path) entry->u.cmd = bcmd; return; } - INTOFF; + INT_OFF; cmdp = cmdlookup(name, 1); cmdp->cmdtype = CMDBUILTIN; cmdp->param.cmd = bcmd; - INTON; + INT_ON; success: cmdp->rehash = 0; entry->cmdtype = cmdp->cmdtype; @@ -4168,7 +4146,7 @@ clearcmdentry(int firstchange) struct tblentry **pp; struct tblentry *cmdp; - INTOFF; + INT_OFF; for (tblp = cmdtable ; tblp < &cmdtable[CMDTABLESIZE] ; tblp++) { pp = tblp; while ((cmdp = *pp) != NULL) { @@ -4178,13 +4156,13 @@ clearcmdentry(int firstchange) builtinloc >= firstchange) ) { *pp = cmdp->next; - ckfree(cmdp); + free(cmdp); } else { pp = &cmdp->next; } } } - INTON; + INT_ON; } @@ -4238,13 +4216,13 @@ delete_cmd_entry(void) { struct tblentry *cmdp; - INTOFF; + INT_OFF; cmdp = *lastcmdentry; *lastcmdentry = cmdp->next; if (cmdp->cmdtype == CMDFUNCTION) freefunc(cmdp->param.func); - ckfree(cmdp); - INTON; + free(cmdp); + INT_ON; } @@ -4295,11 +4273,11 @@ defun(char *name, union node *func) { struct cmdentry entry; - INTOFF; + INT_OFF; entry.cmdtype = CMDFUNCTION; entry.u.func = copyfunc(func); addcmdentry(name, &entry); - INTON; + INT_ON; } @@ -4819,11 +4797,11 @@ removerecordregions(int endoff) if (ifsfirst.endoff > endoff) { while (ifsfirst.next != NULL) { struct ifsregion *ifsp; - INTOFF; + INT_OFF; ifsp = ifsfirst.next->next; - ckfree(ifsfirst.next); + free(ifsfirst.next); ifsfirst.next = ifsp; - INTON; + INT_ON; } if (ifsfirst.begoff > endoff) ifslastp = NULL; @@ -4839,11 +4817,11 @@ removerecordregions(int endoff) ifslastp=ifslastp->next; while (ifslastp->next != NULL) { struct ifsregion *ifsp; - INTOFF; + INT_OFF; ifsp = ifslastp->next->next; - ckfree(ifslastp->next); + free(ifslastp->next); ifslastp->next = ifsp; - INTON; + INT_ON; } if (ifslastp->endoff > endoff) ifslastp->endoff = endoff; @@ -4881,7 +4859,7 @@ expari(int quotes) p--; #if DEBUG if (p < start) { - sh_error("missing CTLARI (shouldn't happen)"); + ash_msg_and_raise_error("missing CTLARI (shouldn't happen)"); } #endif } @@ -4928,7 +4906,7 @@ expbackq(union node *cmd, int quoted, int quotes) int syntax = quoted? DQSYNTAX : BASESYNTAX; struct stackmark smark; - INTOFF; + INT_OFF; setstackmark(&smark); dest = expdest; startloc = dest - (char *)stackblock(); @@ -4953,12 +4931,12 @@ expbackq(union node *cmd, int quoted, int quotes) } if (in.buf) - ckfree(in.buf); + free(in.buf); if (in.fd >= 0) { close(in.fd); back_exitstatus = waitforjob(in.jp); } - INTON; + INT_ON; /* Eat all trailing newlines */ dest = expdest; @@ -5408,11 +5386,11 @@ recordregion(int start, int end, int nulonly) if (ifslastp == NULL) { ifsp = &ifsfirst; } else { - INTOFF; + INT_OFF; ifsp = (struct ifsregion *)ckmalloc(sizeof(struct ifsregion)); ifsp->next = NULL; ifslastp->next = ifsp; - INTON; + INT_ON; } ifslastp = ifsp; ifslastp->begoff = start; @@ -5515,17 +5493,17 @@ ifsfree(void) { struct ifsregion *p; - INTOFF; + INT_OFF; p = ifsfirst.next; do { struct ifsregion *ifsp; ifsp = p->next; - ckfree(p); + free(p); p = ifsp; } while (p); ifslastp = NULL; ifsfirst.next = NULL; - INTON; + INT_ON; } static void expmeta(char *, char *); @@ -5554,7 +5532,7 @@ expandmeta(struct strlist *str, int flag) goto nometa; savelastp = exparg.lastp; - INTOFF; + INT_OFF; p = preglob(str->text, 0, RMESCAPE_ALLOC | RMESCAPE_HEAP); { int i = strlen(str->text); @@ -5562,10 +5540,10 @@ expandmeta(struct strlist *str, int flag) } expmeta(expdir, p); - ckfree(expdir); + free(expdir); if (p != str->text) - ckfree(p); - INTON; + free(p); + INT_ON; if (exparg.lastp == savelastp) { /* * no matches @@ -5911,7 +5889,7 @@ varunset(const char *end, const char *var, const char *umsg, int varflags) } else msg = umsg; } - sh_error("%.*s: %s%s", end - var - 1, var, msg, tail); + ash_msg_and_raise_error("%.*s: %s%s", end - var - 1, var, msg, tail); } @@ -6104,7 +6082,7 @@ preadbuffer(void) } if (parsenleft == EOF_NLEFT || parsefile->buf == NULL) return PEOF; - flushall(); + flush_stdout_stderr(); more = parselleft; if (more <= 0) { @@ -6178,7 +6156,7 @@ pushstring(char *s, void *ap) size_t len; len = strlen(s); - INTOFF; + INT_OFF; /*dprintf("*** calling pushstring: %s, %d\n", s, len);*/ if (parsefile->strpush) { sp = ckmalloc(sizeof(struct strpush)); @@ -6197,7 +6175,7 @@ pushstring(char *s, void *ap) #endif parsenextc = s; parsenleft = len; - INTON; + INT_ON; } static void @@ -6205,14 +6183,14 @@ popstring(void) { struct strpush *sp = parsefile->strpush; - INTOFF; + INT_OFF; #if ENABLE_ASH_ALIAS if (sp->ap) { if (parsenextc[-1] == ' ' || parsenextc[-1] == '\t') { checkkwd |= CHKALIAS; } if (sp->string != sp->ap->val) { - ckfree(sp->string); + free(sp->string); } sp->ap->flag &= ~ALIASINUSE; if (sp->ap->flag & ALIASDEAD) { @@ -6225,8 +6203,8 @@ popstring(void) /*dprintf("*** calling popstring: restoring to '%s'\n", parsenextc);*/ parsefile->strpush = sp->prev; if (sp != &(parsefile->basestrpush)) - ckfree(sp); - INTON; + free(sp); + INT_ON; } @@ -6240,23 +6218,23 @@ setinputfile(const char *fname, int flags) int fd; int fd2; - INTOFF; + INT_OFF; fd = open(fname, O_RDONLY); if (fd < 0) { if (flags & INPUT_NOFILE_OK) goto out; - sh_error("Can't open %s", fname); + ash_msg_and_raise_error("Can't open %s", fname); } if (fd < 10) { fd2 = copyfd(fd, 10); close(fd); if (fd2 < 0) - sh_error("Out of file descriptors"); + ash_msg_and_raise_error("Out of file descriptors"); fd = fd2; } setinputfd(fd, flags & INPUT_PUSH_FILE); out: - INTON; + INT_ON; return fd; } @@ -6287,13 +6265,13 @@ setinputfd(int fd, int push) static void setinputstring(char *string) { - INTOFF; + INT_OFF; pushfile(); parsenextc = string; parsenleft = strlen(string); parsefile->buf = NULL; plinno = 1; - INTON; + INT_ON; } @@ -6324,20 +6302,20 @@ popfile(void) { struct parsefile *pf = parsefile; - INTOFF; + INT_OFF; if (pf->fd >= 0) close(pf->fd); if (pf->buf) - ckfree(pf->buf); + free(pf->buf); while (pf->strpush) popstring(); parsefile = pf->prev; - ckfree(pf); + free(pf); parsenleft = parsefile->nleft; parselleft = parsefile->lleft; parsenextc = parsefile->nextc; plinno = parsefile->linno; - INTON; + INT_ON; } @@ -6497,7 +6475,7 @@ setjobctl(int on) pgrp = tcgetpgrp(fd); if (pgrp < 0) { out: - sh_warnx("can't access tty; job control turned off"); + ash_msg("can't access tty; job control turned off"); mflag = on = 0; goto close; } @@ -6541,7 +6519,7 @@ killcmd(int argc, char **argv) if (argc <= 1) { usage: - sh_error( + ash_msg_and_raise_error( "Usage: kill [-s sigspec | -signum | -sigspec] [pid | job]... or\n" "kill -l [exitstatus]" ); @@ -6564,7 +6542,7 @@ killcmd(int argc, char **argv) case 's': signo = get_signum(optionarg); if (signo < 0) { - sh_error( + ash_msg_and_raise_error( "invalid signal number or name: %s", optionarg ); @@ -6598,7 +6576,7 @@ killcmd(int argc, char **argv) if (isdigit(*name)) out1fmt(snlfmt, name); else - sh_error("invalid signal number or exit status: %s", *argptr); + ash_msg_and_raise_error("invalid signal number or exit status: %s", *argptr); return 0; } @@ -6612,7 +6590,7 @@ killcmd(int argc, char **argv) -number(*argv + 1) : number(*argv); } if (kill(pid, signo) != 0) { - sh_warnx("(%d) - %m", pid); + ash_msg("(%d) - %m", pid); i = 1; } } while (*++argv); @@ -6666,7 +6644,7 @@ restartjob(struct job *jp, int mode) int status; pid_t pgid; - INTOFF; + INT_OFF; if (jp->state == JOBDONE) goto out; jp->state = JOBRUNNING; @@ -6683,7 +6661,7 @@ restartjob(struct job *jp, int mode) } while (ps++, --i); out: status = (mode == FORK_FG) ? waitforjob(jp) : 0; - INTON; + INT_ON; return status; } #endif @@ -6855,16 +6833,16 @@ freejob(struct job *jp) struct procstat *ps; int i; - INTOFF; + INT_OFF; for (i = jp->nprocs, ps = jp->ps ; --i >= 0 ; ps++) { if (ps->cmd != nullstr) - ckfree(ps->cmd); + free(ps->cmd); } if (jp->ps != &jp->ps0) - ckfree(jp->ps); + free(jp->ps); jp->used = 0; set_curjob(jp, CUR_DELETE); - INTON; + INT_ON; } @@ -6875,7 +6853,7 @@ waitcmd(int argc, char **argv) int retval; struct job *jp; - EXSIGON(); + EXSIGON; nextopt(nullstr); retval = 0; @@ -7008,7 +6986,7 @@ getjob(const char *name, int getctl) #endif return jp; err: - sh_error(err_msg, name); + ash_msg_and_raise_error(err_msg, name); } @@ -7150,7 +7128,7 @@ static void forkchild(struct job *jp, union node *n, int mode) if (jp->nprocs == 0) { close(0); if (open(bb_dev_null, O_RDONLY) != 0) - sh_error("Can't open %s", bb_dev_null); + ash_msg_and_raise_error("Can't open %s", bb_dev_null); } } if (!oldlvl && iflag) { @@ -7210,7 +7188,7 @@ forkshell(struct job *jp, union node *n, int mode) TRACE(("Fork failed, errno=%d", errno)); if (jp) freejob(jp); - sh_error("Cannot fork"); + ash_msg_and_raise_error("Cannot fork"); } if (pid == 0) forkchild(jp, n, mode); @@ -7330,7 +7308,7 @@ dowait(int block, struct job *job) TRACE(("wait returns pid %d, status=%d\n", pid, status)); if (pid <= 0) return pid; - INTOFF; + INT_OFF; thisjob = NULL; for (jp = curjob; jp; jp = jp->prev_job) { struct procstat *sp; @@ -7386,7 +7364,7 @@ dowait(int block, struct job *job) } out: - INTON; + INT_ON; if (thisjob && thisjob == job) { char s[48 + 1]; @@ -7716,14 +7694,14 @@ showpipe(struct job *jp, FILE *out) for (sp = jp->ps + 1; sp < spend; sp++) fprintf(out, " | %s", sp->cmd); outcslow('\n', out); - flushall(); + flush_stdout_stderr(); } static void xtcsetpgrp(int fd, pid_t pgrp) { if (tcsetpgrp(fd, pgrp)) - sh_error("Cannot set tty process group (%m)"); + ash_msg_and_raise_error("Cannot set tty process group (%m)"); } #endif /* JOBS */ @@ -7881,7 +7859,7 @@ int ash_main(int argc, char **argv) outcslow('\n', stderr); } popstackmark(&smark); - FORCEINTON; /* enable interrupts */ + FORCE_INT_ON; /* enable interrupts */ if (s == 1) goto state1; else if (s == 2) @@ -8085,7 +8063,7 @@ static char * find_dot_file(char *name) } /* not found in the PATH */ - sh_error(not_found_msg, name); + ash_msg_and_raise_error("%s: not found", name); /* NOTREACHED */ } @@ -8132,7 +8110,7 @@ exitcmd(int argc, char **argv) return 0; if (argc > 1) exitstatus = number(argv[1]); - exraise(EXEXIT); + raise_exception(EXEXIT); /* NOTREACHED */ } @@ -8162,7 +8140,7 @@ ckrealloc(pointer p, size_t nbytes) { p = realloc(p, nbytes); if (p == NULL) - sh_error(bb_msg_memory_exhausted); + ash_msg_and_raise_error(bb_msg_memory_exhausted); return p; } @@ -8180,7 +8158,7 @@ savestr(const char *s) { char *p = strdup(s); if (!p) - sh_error(bb_msg_memory_exhausted); + ash_msg_and_raise_error(bb_msg_memory_exhausted); return p; } @@ -8210,15 +8188,15 @@ stalloc(size_t nbytes) blocksize = MINSIZE; len = sizeof(struct stack_block) - MINSIZE + blocksize; if (len < blocksize) - sh_error(bb_msg_memory_exhausted); - INTOFF; + ash_msg_and_raise_error(bb_msg_memory_exhausted); + INT_OFF; sp = ckmalloc(len); sp->prev = stackp; stacknxt = sp->space; stacknleft = blocksize; sstrend = stacknxt + blocksize; stackp = sp; - INTON; + INT_ON; } p = stacknxt; stacknxt += aligned; @@ -8257,17 +8235,17 @@ popstackmark(struct stackmark *mark) { struct stack_block *sp; - INTOFF; + INT_OFF; markp = mark->marknext; while (stackp != mark->stackp) { sp = stackp; stackp = sp->prev; - ckfree(sp); + free(sp); } stacknxt = mark->stacknxt; stacknleft = mark->stacknleft; sstrend = mark->stacknxt + mark->stacknleft; - INTON; + INT_ON; } @@ -8287,7 +8265,7 @@ growstackblock(void) newlen = stacknleft * 2; if (newlen < stacknleft) - sh_error(bb_msg_memory_exhausted); + ash_msg_and_raise_error(bb_msg_memory_exhausted); if (newlen < 128) newlen += 128; @@ -8298,7 +8276,7 @@ growstackblock(void) struct stack_block *prevstackp; size_t grosslen; - INTOFF; + INT_OFF; oldstackp = stackp; sp = stackp; prevstackp = sp->prev; @@ -8321,7 +8299,7 @@ growstackblock(void) xmark->stacknleft = stacknleft; xmark = xmark->marknext; } - INTON; + INT_ON; } else { char *oldspace = stacknxt; int oldlen = stacknleft; @@ -8436,7 +8414,7 @@ static int number(const char *s) { if (! is_number(s)) - sh_error(illnum, s); + ash_msg_and_raise_error(illnum, s); return atoi(s); } @@ -8729,7 +8707,7 @@ static void freefunc(struct funcnode *f) { if (f && --f->count < 0) - ckfree(f); + free(f); } @@ -8759,7 +8737,7 @@ procargs(int argc, char **argv) xminusc = minusc; if (*xargv == NULL) { if (xminusc) - sh_error(bb_msg_requires_arg, "-c"); + ash_msg_and_raise_error(bb_msg_requires_arg, "-c"); sflag = 1; } if (iflag == 2 && sflag == 1 && isatty(0) && isatty(1)) @@ -8824,7 +8802,7 @@ static void minus_o(char *name, int val) optlist[i] = val; return; } - sh_error("Illegal option -o %s", name); + ash_msg_and_raise_error("Illegal option -o %s", name); } } @@ -8893,7 +8871,7 @@ setoption(int flag, int val) optlist[i] = val; return; } - sh_error("Illegal option -%c", flag); + ash_msg_and_raise_error("Illegal option -%c", flag); /* NOTREACHED */ } @@ -8935,8 +8913,8 @@ freeparam(volatile struct shparam *param) if (param->malloc) { for (ap = param->p ; *ap ; ap++) - ckfree(*ap); - ckfree(param->p); + free(*ap); + free(param->p); } } @@ -8954,12 +8932,12 @@ shiftcmd(int argc, char **argv) if (argc > 1) n = number(argv[1]); if (n > shellparam.nparam) - sh_error("can't shift that many"); - INTOFF; + ash_msg_and_raise_error("can't shift that many"); + INT_OFF; shellparam.nparam -= n; for (ap1 = shellparam.p ; --n >= 0 ; ap1++) { if (shellparam.malloc) - ckfree(*ap1); + free(*ap1); } ap2 = shellparam.p; while ((*ap2++ = *ap1++) != NULL); @@ -8967,7 +8945,7 @@ shiftcmd(int argc, char **argv) shellparam.optind = 1; shellparam.optoff = -1; #endif - INTON; + INT_ON; return 0; } @@ -8980,13 +8958,13 @@ setcmd(int argc, char **argv) { if (argc == 1) return showvars(nullstr, 0, VUNSET); - INTOFF; + INT_OFF; options(0); optschanged(); if (*argptr != NULL) { setparam(argptr); } - INTON; + INT_ON; return 0; } @@ -9119,8 +9097,8 @@ getopts(char *optstr, char *optvar, char **optfirst, int *param_optind, int *opt if (err) { *param_optind = 1; *optoff = -1; - flushall(); - exraise(EXERROR); + flush_stdout_stderr(); + raise_exception(EXERROR); } return done; } @@ -9138,7 +9116,7 @@ getoptscmd(int argc, char **argv) char **optbase; if (argc < 3) - sh_error("Usage: getopts optstring var [arg]"); + ash_msg_and_raise_error("Usage: getopts optstring var [arg]"); else if (argc == 3) { optbase = shellparam.p; if (shellparam.optind > shellparam.nparam + 1) { @@ -9187,13 +9165,13 @@ nextopt(const char *optstring) c = *p++; for (q = optstring ; *q != c ; ) { if (*q == '\0') - sh_error("Illegal option -%c", c); + ash_msg_and_raise_error("Illegal option -%c", c); if (*++q == ':') q++; } if (*++q == ':') { if (*p == '\0' && (p = *argptr++) == NULL) - sh_error("No arg for -%c option", c); + ash_msg_and_raise_error("No arg for -%c option", c); optionarg = p; p = NULL; } @@ -9202,73 +9180,6 @@ nextopt(const char *optstring) } -/* output.c */ - -static void -outstr(const char *p, FILE *file) -{ - INTOFF; - fputs(p, file); - INTON; -} - -static void -flushall(void) -{ - INTOFF; - fflush(stdout); - fflush(stderr); - INTON; -} - -static void -flusherr(void) -{ - INTOFF; - fflush(stderr); - INTON; -} - -static void -outcslow(int c, FILE *dest) -{ - INTOFF; - putc(c, dest); - fflush(dest); - INTON; -} - - -static int -out1fmt(const char *fmt, ...) -{ - va_list ap; - int r; - - INTOFF; - va_start(ap, fmt); - r = vprintf(fmt, ap); - va_end(ap); - INTON; - return r; -} - - -static int -fmtstr(char *outbuf, size_t length, const char *fmt, ...) -{ - va_list ap; - int ret; - - va_start(ap, fmt); - INTOFF; - ret = vsnprintf(outbuf, length, fmt, ap); - va_end(ap); - INTON; - return ret; -} - - /* parser.c */ @@ -10551,12 +10462,12 @@ parsebackq: { savepbq = parsebackquote; if (setjmp(jmploc.loc)) { if (str) - ckfree(str); + free(str); parsebackquote = 0; handler = savehandler; longjmp(handler->loc, 1); } - INTOFF; + INT_OFF; str = NULL; savelen = out - (char *)stackblock(); if (savelen > 0) { @@ -10565,7 +10476,7 @@ parsebackq: { } savehandler = handler; handler = &jmploc; - INTON; + INT_ON; if (oldstyle) { /* We must read until the closing backquote, giving special treatment to some slashes, and then push the string and @@ -10669,10 +10580,10 @@ parsebackq: { if (str) { memcpy(out, str, savelen); STADJUST(savelen, out); - INTOFF; - ckfree(str); + INT_OFF; + free(str); str = NULL; - INTON; + INT_ON; } parsebackquote = savepbq; handler = savehandler; @@ -10776,7 +10687,7 @@ static void synexpect(int token) static void synerror(const char *msg) { - sh_error("Syntax error: %s", msg); + ash_msg_and_raise_error("Syntax error: %s", msg); /* NOTREACHED */ } @@ -10925,7 +10836,7 @@ static int openhere(union node *redir) size_t len = 0; if (pipe(pip) < 0) - sh_error("Pipe call failed"); + ash_msg_and_raise_error("Pipe call failed"); if (redir->type == NHERE) { len = strlen(redir->nhere.doc->narg.text); if (len <= PIPESIZE) { @@ -11011,9 +10922,9 @@ openredirect(union node *redir) return f; ecreate: - sh_error("cannot create %s: %s", fname, errmsg(errno, E_CREAT)); + ash_msg_and_raise_error("cannot create %s: %s", fname, errmsg(errno, "Directory nonexistent")); eopen: - sh_error("cannot open %s: %s", fname, errmsg(errno, E_OPEN)); + ash_msg_and_raise_error("cannot open %s: %s", fname, errmsg(errno, "No such file")); } static void dupredirect(union node *redir, int f) @@ -11055,7 +10966,7 @@ redirect(union node *redir, int flags) return; } sv = NULL; - INTOFF; + INT_OFF; if (flags & REDIR_PUSH) { struct redirtab *q; q = ckmalloc(sizeof(struct redirtab)); @@ -11085,7 +10996,7 @@ redirect(union node *redir, int flags) if (i != EBADF) { close(newfd); errno = i; - sh_error("%d: %m", fd); + ash_msg_and_raise_error("%d: %m", fd); /* NOTREACHED */ } } else { @@ -11097,7 +11008,7 @@ redirect(union node *redir, int flags) } dupredirect(n, newfd); } while ((n = n->nfile.next)); - INTON; + INT_ON; if (flags & REDIR_SAVEFD2 && sv && sv->renamed[2] >= 0) preverrout_fd = sv->renamed[2]; } @@ -11114,7 +11025,7 @@ popredir(int drop) if (--nullredirs >= 0) return; - INTOFF; + INT_OFF; rp = redirlist; for (i = 0 ; i < 10 ; i++) { if (rp->renamed[i] != EMPTY) { @@ -11127,8 +11038,8 @@ popredir(int drop) } redirlist = rp->next; nullredirs = rp->nullredirs; - ckfree(rp); - INTON; + free(rp); + INT_ON; } /* @@ -11165,7 +11076,7 @@ copyfd(int from, int to) if (errno == EMFILE) return EMPTY; else - sh_error("%d: %m", from); + ash_msg_and_raise_error("%d: %m", from); } return newfd; } @@ -11179,7 +11090,7 @@ redirectsafe(union node *redir, int flags) struct jmploc *volatile savehandler = handler; struct jmploc jmploc; - SAVEINT(saveint); + SAVE_INT(saveint); err = setjmp(jmploc.loc) * 2; if (!err) { handler = &jmploc; @@ -11188,7 +11099,7 @@ redirectsafe(union node *redir, int flags) handler = savehandler; if (err && exception != EXERROR) longjmp(handler->loc, 1); - RESTOREINT(saveint); + RESTORE_INT(saveint); return err; } @@ -11585,8 +11496,8 @@ trapcmd(int argc, char **argv) while (*ap) { signo = get_signum(*ap); if (signo < 0) - sh_error("%s: bad trap", *ap); - INTOFF; + ash_msg_and_raise_error("%s: bad trap", *ap); + INT_OFF; if (action) { if (LONE_DASH(action)) action = NULL; @@ -11594,11 +11505,11 @@ trapcmd(int argc, char **argv) action = savestr(action); } if (trap[signo]) - ckfree(trap[signo]); + free(trap[signo]); trap[signo] = action; if (signo != 0) setsignal(signo); - INTON; + INT_ON; ap++; } return 0; @@ -11615,12 +11526,12 @@ clear_traps(void) for (tp = trap ; tp < &trap[NSIG] ; tp++) { if (*tp && **tp) { /* trap not NULL or SIG_IGN */ - INTOFF; - ckfree(*tp); + INT_OFF; + free(*tp); *tp = NULL; if (tp != &trap[0]) setsignal(tp - trap); - INTON; + INT_ON; } } } @@ -11738,7 +11649,7 @@ onsig(int signo) if (exsig || (signo == SIGINT && !trap[SIGINT])) { if (!suppressint) - onint(); + raise_interrupt(); intpending = 1; } } @@ -11868,7 +11779,7 @@ exitshell(void) trap[0] = NULL; evalstring(p, 0); } - flushall(); + flush_stdout_stderr(); out: setjobctl(0); _exit(status); @@ -11899,7 +11810,7 @@ setvarsafe(const char *name, const char *val, int flags) struct jmploc *volatile savehandler = handler; struct jmploc jmploc; - SAVEINT(saveint); + SAVE_INT(saveint); if (setjmp(jmploc.loc)) err = 1; else { @@ -11908,7 +11819,7 @@ setvarsafe(const char *name, const char *val, int flags) err = 0; } handler = savehandler; - RESTOREINT(saveint); + RESTORE_INT(saveint); return err; } #endif @@ -11930,14 +11841,14 @@ setvar(const char *name, const char *val, int flags) p = strchrnul(q, '='); namelen = p - name; if (!namelen || p != q) - sh_error("%.*s: bad variable name", namelen, name); + ash_msg_and_raise_error("%.*s: bad variable name", namelen, name); vallen = 0; if (val == NULL) { flags |= VUNSET; } else { vallen = strlen(val); } - INTOFF; + INT_OFF; nameeq = ckmalloc(namelen + vallen + 2); p = memcpy(nameeq, name, namelen) + namelen; if (val) { @@ -11946,7 +11857,7 @@ setvar(const char *name, const char *val, int flags) } *p = '\0'; setvareq(nameeq, flags | VNOSAVE); - INTON; + INT_ON; } @@ -11972,7 +11883,7 @@ setvareq(char *s, int flags) if (flags & VNOSAVE) free(s); n = vp->text; - sh_error("%.*s: is read only", strchrnul(n, '=') - n, n); + ash_msg_and_raise_error("%.*s: is read only", strchrnul(n, '=') - n, n); } if (flags & VNOSET) @@ -11982,7 +11893,7 @@ setvareq(char *s, int flags) (*vp->func)(strchrnul(s, '=') + 1); if ((vp->flags & (VTEXTFIXED|VSTACK)) == 0) - ckfree(vp->text); + free((char*)vp->text); flags |= vp->flags & ~(VTEXTFIXED|VSTACK|VNOSAVE|VUNSET); } else { @@ -12011,11 +11922,11 @@ listsetvar(struct strlist *list_set_var, int flags) if (!lp) return; - INTOFF; + INT_OFF; do { setvareq(lp->text, flags); } while ((lp = lp->next)); - INTON; + INT_ON; } @@ -12175,7 +12086,7 @@ static void mklocal(char *name) struct var **vpp; struct var *vp; - INTOFF; + INT_OFF; lvp = ckmalloc(sizeof(struct localvar)); if (LONE_DASH(name)) { char *p; @@ -12206,7 +12117,7 @@ static void mklocal(char *name) lvp->vp = vp; lvp->next = localvars; localvars = lvp; - INTON; + INT_ON; } @@ -12242,7 +12153,7 @@ poplocalvars(void) TRACE(("poplocalvar %s", vp ? vp->text : "-")); if (vp == NULL) { /* $- saved */ memcpy(optlist, lvp->text, sizeof(optlist)); - ckfree(lvp->text); + free((char*)lvp->text); optschanged(); } else if ((lvp->flags & (VUNSET|VSTRFIXED)) == VUNSET) { unsetvar(vp->text); @@ -12250,11 +12161,11 @@ poplocalvars(void) if (vp->func) (*vp->func)(strchrnul(lvp->text, '=') + 1); if ((vp->flags & (VTEXTFIXED|VSTACK)) == 0) - ckfree(vp->text); + free((char*)vp->text); vp->flags = lvp->flags; vp->text = lvp->text; } - ckfree(lvp); + free(lvp); } } @@ -12315,17 +12226,17 @@ unsetvar(const char *s) if (flags & VUNSET) goto ok; if ((flags & VSTRFIXED) == 0) { - INTOFF; + INT_OFF; if ((flags & (VTEXTFIXED|VSTACK)) == 0) - ckfree(vp->text); + free((char*)vp->text); *vpp = vp->next; - ckfree(vp); - INTON; + free(vp); + INT_ON; } else { setvar(s, 0, 0); vp->flags &= ~VEXPORT; } -ok: + ok: retval = 0; } out: @@ -12429,19 +12340,19 @@ dash_arith(const char *s) arith_t result; int errcode = 0; - INTOFF; + INT_OFF; result = arith(s, &errcode); if (errcode < 0) { if (errcode == -3) - sh_error("exponent less than 0"); + ash_msg_and_raise_error("exponent less than 0"); else if (errcode == -2) - sh_error("divide by zero"); + ash_msg_and_raise_error("divide by zero"); else if (errcode == -5) - sh_error("expression recursion loop detected"); + ash_msg_and_raise_error("expression recursion loop detected"); else synerror(s); } - INTON; + INT_ON; return result; } @@ -12461,7 +12372,7 @@ letcmd(int argc, char **argv) ap = argv + 1; if (!*ap) - sh_error("expression expected"); + ash_msg_and_raise_error("expression expected"); for (ap = argv + 1; *ap; ap++) { i = dash_arith(*ap); } @@ -12535,7 +12446,7 @@ readcmd(int argc, char **argv) case 'n': nchars = strtol(optionarg, &p, 10); if (*p) - sh_error("invalid count"); + ash_msg_and_raise_error("invalid count"); nch_flag = (nchars > 0); break; case 's': @@ -12552,19 +12463,19 @@ readcmd(int argc, char **argv) int scale; ts.tv_usec = strtol(p, &p2, 10); if (*p2) - sh_error("invalid timeout"); + ash_msg_and_raise_error("invalid timeout"); scale = p2 - p; /* normalize to usec */ if (scale > 6) - sh_error("invalid timeout"); + ash_msg_and_raise_error("invalid timeout"); while (scale++ < 6) ts.tv_usec *= 10; } } else if (*p) { - sh_error("invalid timeout"); + ash_msg_and_raise_error("invalid timeout"); } if ( ! ts.tv_sec && ! ts.tv_usec) - sh_error("invalid timeout"); + ash_msg_and_raise_error("invalid timeout"); break; #endif case 'r': @@ -12579,7 +12490,7 @@ readcmd(int argc, char **argv) } ap = argptr; if (*ap == NULL) - sh_error("arg count"); + ash_msg_and_raise_error("arg count"); ifs = bltinlookup("IFS"); if (ifs == NULL) ifs = defifs; @@ -12691,10 +12602,10 @@ static int umaskcmd(int argc, char **argv) symbolic_mode = 1; } - INTOFF; + INT_OFF; mask = umask(0); umask(mask); - INTON; + INT_ON; ap = *argptr; if (ap == NULL) { @@ -12724,14 +12635,14 @@ static int umaskcmd(int argc, char **argv) mask = 0; do { if (*ap >= '8' || *ap < '0') - sh_error(illnum, argv[1]); + ash_msg_and_raise_error(illnum, argv[1]); mask = (mask << 3) + (*ap - '0'); } while (*++ap != '\0'); umask(mask); } else { mask = ~mask & 0777; if (!bb_parse_mode(ap, &mask)) { - sh_error("Illegal mode: %s", ap); + ash_msg_and_raise_error("Illegal mode: %s", ap); } umask(~mask & 0777); } @@ -12881,7 +12792,7 @@ ulimitcmd(int argc, char **argv) char *p = *argptr; if (all || argptr[1]) - sh_error("too many arguments"); + ash_msg_and_raise_error("too many arguments"); if (strncmp(p, "unlimited\n", 9) == 0) val = RLIM_INFINITY; else { @@ -12893,7 +12804,7 @@ ulimitcmd(int argc, char **argv) break; } if (c) - sh_error("bad number"); + ash_msg_and_raise_error("bad number"); val *= l->factor; } } @@ -12913,7 +12824,7 @@ ulimitcmd(int argc, char **argv) if (how & SOFT) limit.rlim_cur = val; if (setrlimit(l->cmd, &limit) < 0) - sh_error("error setting limit (%m)"); + ash_msg_and_raise_error("error setting limit (%m)"); } else { printlim(how, &limit, l); } |