diff options
author | Eric Andersen <andersen@codepoet.org> | 2001-08-02 09:02:46 +0400 |
---|---|---|
committer | Eric Andersen <andersen@codepoet.org> | 2001-08-02 09:02:46 +0400 |
commit | 34506361697643277042fc8d7294bc17a27d4e28 (patch) | |
tree | bf2c45a12020be4e0a37547abb50c40c0074e8ec | |
parent | 2d91deba45d5a284614e06cc55e2be03599ca26d (diff) |
Latest patch from vodz. Adds a check for divide by zero in the posix
math suport, cleaner math syntax error checking, moves redundant signal
string tables (from kill and ash) into libbb and provides a few
cleanups elsewhere.
-rw-r--r-- | Makefile | 2 | ||||
-rw-r--r-- | ash.c | 171 | ||||
-rw-r--r-- | cmdedit.c | 24 | ||||
-rw-r--r-- | coreutils/cut.c | 6 | ||||
-rw-r--r-- | coreutils/uudecode.c | 10 | ||||
-rw-r--r-- | cut.c | 6 | ||||
-rw-r--r-- | include/libbb.h | 4 | ||||
-rw-r--r-- | kill.c | 142 | ||||
-rw-r--r-- | libbb/arith.c | 33 | ||||
-rw-r--r-- | libbb/concat_path_file.c | 2 | ||||
-rw-r--r-- | libbb/libbb.h | 4 | ||||
-rw-r--r-- | miscutils/update.c | 3 | ||||
-rw-r--r-- | procps/kill.c | 142 | ||||
-rw-r--r-- | shell/ash.c | 171 | ||||
-rw-r--r-- | shell/cmdedit.c | 24 | ||||
-rw-r--r-- | update.c | 3 | ||||
-rw-r--r-- | uudecode.c | 10 |
17 files changed, 187 insertions, 570 deletions
@@ -247,7 +247,7 @@ safe_read.c safe_strncpy.c syscalls.c syslog_msg_with_name.c time_string.c \ trim.c unzip.c vdprintf.c verror_msg.c vperror_msg.c wfopen.c xfuncs.c \ xgetcwd.c xreadlink.c xregcomp.c interface.c remove_file.c last_char_is.c \ copyfd.c vherror_msg.c herror_msg.c herror_msg_and_die.c xgethostbyname.c \ -dirname.c make_directory.c create_icmp_socket.c arith.c +dirname.c make_directory.c create_icmp_socket.c u_signal_names.c arith.c LIBBB_OBJS=$(patsubst %.c,$(LIBBB)/%.o, $(LIBBB_CSRC)) LIBBB_CFLAGS = -I$(LIBBB) ifneq ($(strip $(BB_SRC_DIR)),) @@ -52,6 +52,7 @@ /* If you need ash to act as a full Posix shell, with full math * support, enable this. This adds a bit over 2k an x86 system. */ +//#undef ASH_MATH_SUPPORT #define ASH_MATH_SUPPORT /* Getopts is used by shell procedures to parse positional parameters. @@ -78,8 +79,6 @@ /* These are here to work with glibc -- Don't change these... */ #undef FNMATCH_BROKEN #undef GLOB_BROKEN -#undef _GNU_SOURCE -#undef __USE_GNU #include <assert.h> #include <ctype.h> @@ -4839,6 +4838,7 @@ static void expari(int flag) { char *p, *start; + int errcode; int result; int begoff; int quotes = flag & (EXP_FULL | EXP_CASE); @@ -4877,9 +4877,13 @@ expari(int flag) removerecordregions(begoff); if (quotes) rmescapes(p+2); - result = arith(p+2); - if (result < 0) - error("arith: syntax error: \"%s\"\n", p+2); + result = arith(p+2, &errcode); + if (errcode < 0) { + if(errcode == -2) + error("divide by zero"); + else + error("syntax error: \"%s\"\n", p+2); + } snprintf(p, 12, "%d", result); while (*p++) @@ -5429,9 +5433,9 @@ expandmeta(str, flag) goto nometa; p = preglob(str->text); INTOFF; - switch (glob(p, GLOB_NOMAGIC, 0, &pglob)) { + switch (glob(p, 0, 0, &pglob)) { case 0: - if (!(pglob.gl_flags & GLOB_MAGCHAR)) + if(pglob.gl_pathv[1]==0 && !strcmp(p, pglob.gl_pathv[0])) goto nometa2; addglob(&pglob); globfree(&pglob); @@ -6006,7 +6010,7 @@ static int histcmd(argc, argv) struct redirtab { struct redirtab *next; short renamed[10]; /* Current ash support only 0-9 descriptors */ - /* char renamed[10]; */ /* char on arm (and others) can't be negative */ + /* char on arm (and others) can't be negative */ }; static struct redirtab *redirlist; @@ -6166,7 +6170,7 @@ preadfd(void) retry: #ifdef BB_FEATURE_COMMAND_EDITING { - if (parsefile->fd) + if (!iflag || parsefile->fd) nr = safe_read(parsefile->fd, buf, BUFSIZ - 1); else { nr = cmdedit_read_input((char*)cmdedit_prompt, buf); @@ -6468,80 +6472,6 @@ static void setjobctl(int enable) #endif -/* A translation list so we can be polite to our users. */ -static char *signal_names[NSIG + 2] = { - "EXIT", - "SIGHUP", - "SIGINT", - "SIGQUIT", - "SIGILL", - "SIGTRAP", - "SIGABRT", - "SIGBUS", - "SIGFPE", - "SIGKILL", - "SIGUSR1", - "SIGSEGV", - "SIGUSR2", - "SIGPIPE", - "SIGALRM", - "SIGTERM", - "SIGJUNK(16)", - "SIGCHLD", - "SIGCONT", - "SIGSTOP", - "SIGTSTP", - "SIGTTIN", - "SIGTTOU", - "SIGURG", - "SIGXCPU", - "SIGXFSZ", - "SIGVTALRM", - "SIGPROF", - "SIGWINCH", - "SIGIO", - "SIGPWR", - "SIGSYS", -#ifdef SIGRTMIN - "SIGRTMIN", - "SIGRTMIN+1", - "SIGRTMIN+2", - "SIGRTMIN+3", - "SIGRTMIN+4", - "SIGRTMIN+5", - "SIGRTMIN+6", - "SIGRTMIN+7", - "SIGRTMIN+8", - "SIGRTMIN+9", - "SIGRTMIN+10", - "SIGRTMIN+11", - "SIGRTMIN+12", - "SIGRTMIN+13", - "SIGRTMIN+14", - "SIGRTMIN+15", - "SIGRTMAX-15", - "SIGRTMAX-14", - "SIGRTMAX-13", - "SIGRTMAX-12", - "SIGRTMAX-11", - "SIGRTMAX-10", - "SIGRTMAX-9", - "SIGRTMAX-8", - "SIGRTMAX-7", - "SIGRTMAX-6", - "SIGRTMAX-5", - "SIGRTMAX-4", - "SIGRTMAX-3", - "SIGRTMAX-2", - "SIGRTMAX-1", - "SIGRTMAX", -#endif - "DEBUG", - (char *)0x0, -}; - - - #ifdef JOBS static int killcmd(argc, argv) @@ -6599,18 +6529,20 @@ usage: } if (list) { + const char *name; + if (!*argptr) { out1str("0\n"); for (i = 1; i < NSIG; i++) { - printf(snlfmt, signal_names[i] + 3); + name = u_signal_names(0, &i, 1); + if(name) + printf(snlfmt, name); } return 0; } - signo = atoi(*argptr); - if (signo > 128) - signo -= 128; - if (0 < signo && signo < NSIG) - printf(snlfmt, signal_names[signo] + 3); + name = u_signal_names(*argptr, &signo, -1); + if (name) + printf(snlfmt, name); else error("invalid signal number or exit status: %s", *argptr); @@ -8834,12 +8766,6 @@ copynodelist(const struct nodelist *lp) static char * nodesavestr(const char *s) { -#ifdef _GNU_SOURCE - char *rtn = funcstring; - - funcstring = stpcpy(funcstring, s) + 1; - return rtn; -#else const char *p = s; char *q = funcstring; char *rtn = funcstring; @@ -8848,7 +8774,6 @@ nodesavestr(const char *s) continue; funcstring = q; return rtn; -#endif } #ifdef ASH_GETOPTS @@ -12052,11 +11977,15 @@ trapcmd(argc, argv) for (signo = 0 ; signo < NSIG ; signo++) { if (trap[signo] != NULL) { char *p; + const char *sn; p = single_quote(trap[signo]); - printf("trap -- %s %s\n", p, - signal_names[signo] + (signo ? 3 : 0) - ); + sn = sys_siglist[signo]; + if(sn==NULL) + sn = u_signal_names(0, &signo, 0); + if(sn==NULL) + sn = "???"; + printf("trap -- %s %s\n", p, sn); stunalloc(p); } } @@ -12273,30 +12202,11 @@ l2: _exit(status); static int decode_signal(const char *string, int minsig) { int signo; + const char *name = u_signal_names(string, &signo, minsig); - if (is_number(string, &signo)) { - if (signo >= NSIG) { - return -1; - } - return signo; - } - - signo = minsig; - if (!signo) { - goto zero; - } - for (; signo < NSIG; signo++) { - if (!strcasecmp(string, &(signal_names[signo])[3])) { - return signo; - } -zero: - if (!strcasecmp(string, signal_names[signo])) { - return signo; - } - } - - return -1; + return name ? signo : -1; } + static struct var **hashvar (const char *); static void showvars (const char *, int, int); static struct var **findvar (struct var **, const char *); @@ -12616,6 +12526,7 @@ found:; return 0; } + /* * The "local" command. */ @@ -12874,7 +12785,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.16 2001/08/01 17:21:33 kraai Exp $ + * $Id: ash.c,v 1.17 2001/08/02 05:02:45 andersen Exp $ */ static int timescmd (int argc, char **argv) { @@ -12894,24 +12805,32 @@ static int timescmd (int argc, char **argv) return 0; } - #ifdef ASH_MATH_SUPPORT /* The let builtin. */ int letcmd(int argc, char **argv) { + int errcode; long result=0; if (argc == 2) { char *tmp, *expression, p[13]; expression = strchr(argv[1], '='); if (!expression) { + /* Cannot use 'error()' here, or the return code + * will be incorrect */ out2fmt("sh: let: syntax error: \"%s\"\n", argv[1]); return 0; } *expression = '\0'; tmp = ++expression; - result = arith(tmp); - if (result < 0) { - out2fmt("sh: let: syntax error: \"%s=%s\"\n", argv[1], expression); + result = arith(tmp, &errcode); + if (errcode < 0) { + /* Cannot use 'error()' here, or the return code + * will be incorrect */ + out2fmt("sh: let: "); + if(errcode == -2) + out2fmt("divide by zero"); + else + out2fmt("syntax error: \"%s=%s\"\n", argv[1], expression); return 0; } snprintf(p, 12, "%ld", result); @@ -1167,25 +1167,21 @@ int cmdedit_read_input(char *prompt, char command[BUFSIZ]) len = 0; command_ps = command; - if (new_settings.c_cc[VERASE] == 0) { /* first call */ - - getTermSettings(0, (void *) &initial_settings); - memcpy(&new_settings, &initial_settings, sizeof(struct termios)); - new_settings.c_lflag &= ~ICANON; /* unbuffered input */ - /* Turn off echoing and CTRL-C, so we can trap it */ - new_settings.c_lflag &= ~(ECHO | ECHONL | ISIG); + getTermSettings(0, (void *) &initial_settings); + memcpy(&new_settings, &initial_settings, sizeof(struct termios)); + new_settings.c_lflag &= ~ICANON; /* unbuffered input */ + /* Turn off echoing and CTRL-C, so we can trap it */ + new_settings.c_lflag &= ~(ECHO | ECHONL | ISIG); #ifndef linux - /* Hmm, in linux c_cc[] not parsed if set ~ICANON */ - new_settings.c_cc[VMIN] = 1; - new_settings.c_cc[VTIME] = 0; - /* Turn off CTRL-C, so we can trap it */ + /* Hmm, in linux c_cc[] not parsed if set ~ICANON */ + new_settings.c_cc[VMIN] = 1; + new_settings.c_cc[VTIME] = 0; + /* Turn off CTRL-C, so we can trap it */ # ifndef _POSIX_VDISABLE # define _POSIX_VDISABLE '\0' # endif - new_settings.c_cc[VINTR] = _POSIX_VDISABLE; + new_settings.c_cc[VINTR] = _POSIX_VDISABLE; #endif - } - command[0] = 0; setTermSettings(0, (void *) &new_settings); diff --git a/coreutils/cut.c b/coreutils/cut.c index abe05726b..3ed264870 100644 --- a/coreutils/cut.c +++ b/coreutils/cut.c @@ -344,10 +344,8 @@ extern int cut_main(int argc, char **argv) int i; FILE *file; for (i = optind; i < argc; i++) { - file = fopen(argv[i], "r"); - if (file == NULL) { - perror_msg("%s", argv[i]); - } else { + file = wfopen(argv[i], "r"); + if(file) { cut_file(file); fclose(file); } diff --git a/coreutils/uudecode.c b/coreutils/uudecode.c index 6ac9f1bf3..a4059ddfe 100644 --- a/coreutils/uudecode.c +++ b/coreutils/uudecode.c @@ -201,9 +201,8 @@ static int decode (const char *inname, const char *forced_outname) { struct passwd *pw; - register int n; register char *p; - int mode, n1; + int mode; char buf[2 * BUFSIZ]; char *outname; int do_base64 = 0; @@ -249,12 +248,7 @@ static int decode (const char *inname, error_msg("%s: No user `%s'", inname, buf + 1); return FALSE; } - n = strlen (pw->pw_dir); - n1 = strlen (p); - outname = (char *) xmalloc ((size_t) (n + n1 + 2)); - memcpy (outname + n + 1, p, (size_t) (n1 + 1)); - memcpy (outname, pw->pw_dir, (size_t) n); - outname[n] = '/'; + outname = concat_path_file(pw->pw_dir, p); dofre = TRUE; } } @@ -344,10 +344,8 @@ extern int cut_main(int argc, char **argv) int i; FILE *file; for (i = optind; i < argc; i++) { - file = fopen(argv[i], "r"); - if (file == NULL) { - perror_msg("%s", argv[i]); - } else { + file = wfopen(argv[i], "r"); + if(file) { cut_file(file); fclose(file); } diff --git a/include/libbb.h b/include/libbb.h index 66acc2278..df52027ce 100644 --- a/include/libbb.h +++ b/include/libbb.h @@ -212,7 +212,7 @@ char *xreadlink(const char *path); char *concat_path_file(const char *path, const char *filename); char *last_char_is(const char *s, int c); -extern long arith (const char *startbuf); +extern long arith (const char *startbuf, int *errcode); typedef struct file_headers_s { char *name; @@ -261,6 +261,8 @@ char *dirname (const char *path); int make_directory (char *path, mode_t mode, int flags); +const char *u_signal_names(const char *str_sig, int *signo, int startnum); + #define CT_AUTO 0 #define CT_UNIX2DOS 1 #define CT_DOS2UNIX 2 @@ -34,96 +34,11 @@ static const int KILL = 0; static const int KILLALL = 1; -struct signal_name { - const char *name; - int number; -}; - -static const struct signal_name signames[] = { - /* POSIX signals */ - { "HUP", SIGHUP }, /* 1 */ - { "INT", SIGINT }, /* 2 */ - { "QUIT", SIGQUIT }, /* 3 */ - { "ILL", SIGILL }, /* 4 */ - { "ABRT", SIGABRT }, /* 6 */ - { "FPE", SIGFPE }, /* 8 */ - { "KILL", SIGKILL }, /* 9 */ - { "SEGV", SIGSEGV }, /* 11 */ - { "PIPE", SIGPIPE }, /* 13 */ - { "ALRM", SIGALRM }, /* 14 */ - { "TERM", SIGTERM }, /* 15 */ - { "USR1", SIGUSR1 }, /* 10 (arm,i386,m68k,ppc), 30 (alpha,sparc*), 16 (mips) */ - { "USR2", SIGUSR2 }, /* 12 (arm,i386,m68k,ppc), 31 (alpha,sparc*), 17 (mips) */ - { "CHLD", SIGCHLD }, /* 17 (arm,i386,m68k,ppc), 20 (alpha,sparc*), 18 (mips) */ - { "CONT", SIGCONT }, /* 18 (arm,i386,m68k,ppc), 19 (alpha,sparc*), 25 (mips) */ - { "STOP", SIGSTOP }, /* 19 (arm,i386,m68k,ppc), 17 (alpha,sparc*), 23 (mips) */ - { "TSTP", SIGTSTP }, /* 20 (arm,i386,m68k,ppc), 18 (alpha,sparc*), 24 (mips) */ - { "TTIN", SIGTTIN }, /* 21 (arm,i386,m68k,ppc,alpha,sparc*), 26 (mips) */ - { "TTOU", SIGTTOU }, /* 22 (arm,i386,m68k,ppc,alpha,sparc*), 27 (mips) */ - /* Miscellaneous other signals */ -#ifdef SIGTRAP - { "TRAP", SIGTRAP }, /* 5 */ -#endif -#ifdef SIGIOT - { "IOT", SIGIOT }, /* 6, same as SIGABRT */ -#endif -#ifdef SIGEMT - { "EMT", SIGEMT }, /* 7 (mips,alpha,sparc*) */ -#endif -#ifdef SIGBUS - { "BUS", SIGBUS }, /* 7 (arm,i386,m68k,ppc), 10 (mips,alpha,sparc*) */ -#endif -#ifdef SIGSYS - { "SYS", SIGSYS }, /* 12 (mips,alpha,sparc*) */ -#endif -#ifdef SIGSTKFLT - { "STKFLT", SIGSTKFLT }, /* 16 (arm,i386,m68k,ppc) */ -#endif -#ifdef SIGURG - { "URG", SIGURG }, /* 23 (arm,i386,m68k,ppc), 16 (alpha,sparc*), 21 (mips) */ -#endif -#ifdef SIGIO - { "IO", SIGIO }, /* 29 (arm,i386,m68k,ppc), 23 (alpha,sparc*), 22 (mips) */ -#endif -#ifdef SIGPOLL - { "POLL", SIGPOLL }, /* same as SIGIO */ -#endif -#ifdef SIGCLD - { "CLD", SIGCLD }, /* same as SIGCHLD (mips) */ -#endif -#ifdef SIGXCPU - { "XCPU", SIGXCPU }, /* 24 (arm,i386,m68k,ppc,alpha,sparc*), 30 (mips) */ -#endif -#ifdef SIGXFSZ - { "XFSZ", SIGXFSZ }, /* 25 (arm,i386,m68k,ppc,alpha,sparc*), 31 (mips) */ -#endif -#ifdef SIGVTALRM - { "VTALRM", SIGVTALRM }, /* 26 (arm,i386,m68k,ppc,alpha,sparc*), 28 (mips) */ -#endif -#ifdef SIGPROF - { "PROF", SIGPROF }, /* 27 (arm,i386,m68k,ppc,alpha,sparc*), 29 (mips) */ -#endif -#ifdef SIGPWR - { "PWR", SIGPWR }, /* 30 (arm,i386,m68k,ppc), 29 (alpha,sparc*), 19 (mips) */ -#endif -#ifdef SIGINFO - { "INFO", SIGINFO }, /* 29 (alpha) */ -#endif -#ifdef SIGLOST - { "LOST", SIGLOST }, /* 29 (arm,i386,m68k,ppc,sparc*) */ -#endif -#ifdef SIGWINCH - { "WINCH", SIGWINCH }, /* 28 (arm,i386,m68k,ppc,alpha,sparc*), 20 (mips) */ -#endif -#ifdef SIGUNUSED - { "UNUSED", SIGUNUSED }, /* 31 (arm,i386,m68k,ppc) */ -#endif - {0, 0} -}; extern int kill_main(int argc, char **argv) { int whichApp, sig = SIGTERM; + const char *name; #ifdef BB_KILLALL /* Figure out what we are trying to do here */ @@ -142,52 +57,37 @@ extern int kill_main(int argc, char **argv) while (*++(*argv)) { switch (**argv) { case 'l': - { + if(argc>1) { + for(argv++; *argv; argv++) { + name = u_signal_names(*argv, &sig, -1); + if(name!=NULL) + printf("%s\n", name); + } + } else { int col = 0; - const struct signal_name *s = signames; - - while (s->name != 0) { - col += fprintf(stderr, "%2d) %-8s", s->number, s->name); - s++; + for(sig=1; sig < NSIG; sig++) { + name = u_signal_names(0, &sig, 1); + if(name==NULL) /* unnamed */ + continue; + col += printf("%2d) %-16s", sig, name); if (col > 60) { - fprintf(stderr, "\n"); + printf("\n"); col = 0; } } - fprintf(stderr, "\n\n"); - return EXIT_SUCCESS; + printf("\n"); } - break; + return EXIT_SUCCESS; case '-': show_usage(); default: - { - if (isdigit(**argv)) { - sig = atoi(*argv); - if (sig < 0 || sig >= NSIG) - goto end; - else { - argc--; - argv++; - goto do_it_now; - } - } else { - const struct signal_name *s = signames; - - while (s->name != 0) { - if (strcasecmp(s->name, *argv) == 0) { - sig = s->number; + name = u_signal_names(*argv, &sig, 0); + if(name==NULL) + error_msg_and_die( "bad signal name: %s", *argv); argc--; argv++; goto do_it_now; } - s++; - } - if (s->name == 0) - goto end; - } - } - } argc--; argv++; } @@ -239,8 +139,4 @@ extern int kill_main(int argc, char **argv) #endif return EXIT_SUCCESS; - - - end: - error_msg_and_die( "bad signal name: %s", *argv); } diff --git a/libbb/arith.c b/libbb/arith.c index c7a3cf98b..04c45ec3d 100644 --- a/libbb/arith.c +++ b/libbb/arith.c @@ -119,20 +119,26 @@ static short arith_apply(operator op, long *numstack, long **numstackptr) NUMPTR[-1] = (NUMPTR[-1] <= *NUMPTR); else if (op == TOK_MUL) NUMPTR[-1] *= *NUMPTR; - else if (op == TOK_DIV) + else if (op == TOK_DIV) { + if(*NUMPTR==0) + return -2; NUMPTR[-1] /= *NUMPTR; - else if (op == TOK_REM) + } + else if (op == TOK_REM) { + if(*NUMPTR==0) + return -2; NUMPTR[-1] %= *NUMPTR; + } else if (op == TOK_ADD) NUMPTR[-1] += *NUMPTR; else if (op == TOK_SUB) NUMPTR[-1] -= *NUMPTR; } return 0; -err: return(1); +err: return(-1); } -extern long arith (const char *startbuf) +extern long arith (const char *startbuf, int *errcode) { register char arithval; const char *expr = startbuf; @@ -142,8 +148,9 @@ extern long arith (const char *startbuf) unsigned char prec; long *numstack, *numstackptr; - operator *stack = alloca(datasizes * sizeof(operator)), *stackptr = stack; + + *errcode = 0; numstack = alloca((datasizes/2+1)*sizeof(long)), numstackptr = numstack; while ((arithval = *expr)) { @@ -163,7 +170,8 @@ extern long arith (const char *startbuf) op = *--stackptr; if (op == TOK_LPAREN) goto prologue; - if(ARITH_APPLY(op)) goto err; + *errcode = ARITH_APPLY(op); + if(*errcode) return *errcode; } goto err; /* Mismatched parens */ } if (arithval == '|') { @@ -231,17 +239,22 @@ extern long arith (const char *startbuf) prec = PREC(op); if (prec != UNARYPREC) - while (stackptr != stack && PREC(stackptr[-1]) >= prec) - if(ARITH_APPLY(*--stackptr)) goto err; + while (stackptr != stack && PREC(stackptr[-1]) >= prec) { + *errcode = ARITH_APPLY(*--stackptr); + if(*errcode) return *errcode; + } *stackptr++ = op; lasttok = op; prologue: ++expr; } /* yay */ - while (stackptr != stack) - if(ARITH_APPLY(*--stackptr)) goto err; + while (stackptr != stack) { + *errcode = ARITH_APPLY(*--stackptr); + if(*errcode) return *errcode; + } if (numstackptr != numstack+1) { err: + *errcode = -1; return -1; /* NOTREACHED */ } diff --git a/libbb/concat_path_file.c b/libbb/concat_path_file.c index c699a84f7..86dd2fbbf 100644 --- a/libbb/concat_path_file.c +++ b/libbb/concat_path_file.c @@ -17,7 +17,7 @@ extern char *concat_path_file(const char *path, const char *filename) if (!path) path=""; lc = last_char_is(path, '/'); - if (filename[0] == '/') + while (*filename == '/') filename++; outbuf = xmalloc(strlen(path)+strlen(filename)+1+(lc==NULL)); sprintf(outbuf, "%s%s%s", path, (lc==NULL)? "/" : "", filename); diff --git a/libbb/libbb.h b/libbb/libbb.h index 66acc2278..df52027ce 100644 --- a/libbb/libbb.h +++ b/libbb/libbb.h @@ -212,7 +212,7 @@ char *xreadlink(const char *path); char *concat_path_file(const char *path, const char *filename); char *last_char_is(const char *s, int c); -extern long arith (const char *startbuf); +extern long arith (const char *startbuf, int *errcode); typedef struct file_headers_s { char *name; @@ -261,6 +261,8 @@ char *dirname (const char *path); int make_directory (char *path, mode_t mode, int flags); +const char *u_signal_names(const char *str_sig, int *signo, int startnum); + #define CT_AUTO 0 #define CT_UNIX2DOS 1 #define CT_DOS2UNIX 2 diff --git a/miscutils/update.c b/miscutils/update.c index 603740e38..27a04ddee 100644 --- a/miscutils/update.c +++ b/miscutils/update.c @@ -69,9 +69,6 @@ extern int update_main(int argc, char **argv) if (daemon(0, 1) < 0) perror_msg_and_die("daemon"); - /* Become a proper daemon */ - setsid(); - chdir("/"); #ifdef OPEN_MAX for (pid = 0; pid < OPEN_MAX; pid++) close(pid); #else diff --git a/procps/kill.c b/procps/kill.c index 34cbc4d6a..3884ebdf4 100644 --- a/procps/kill.c +++ b/procps/kill.c @@ -34,96 +34,11 @@ static const int KILL = 0; static const int KILLALL = 1; -struct signal_name { - const char *name; - int number; -}; - -static const struct signal_name signames[] = { - /* POSIX signals */ - { "HUP", SIGHUP }, /* 1 */ - { "INT", SIGINT }, /* 2 */ - { "QUIT", SIGQUIT }, /* 3 */ - { "ILL", SIGILL }, /* 4 */ - { "ABRT", SIGABRT }, /* 6 */ - { "FPE", SIGFPE }, /* 8 */ - { "KILL", SIGKILL }, /* 9 */ - { "SEGV", SIGSEGV }, /* 11 */ - { "PIPE", SIGPIPE }, /* 13 */ - { "ALRM", SIGALRM }, /* 14 */ - { "TERM", SIGTERM }, /* 15 */ - { "USR1", SIGUSR1 }, /* 10 (arm,i386,m68k,ppc), 30 (alpha,sparc*), 16 (mips) */ - { "USR2", SIGUSR2 }, /* 12 (arm,i386,m68k,ppc), 31 (alpha,sparc*), 17 (mips) */ - { "CHLD", SIGCHLD }, /* 17 (arm,i386,m68k,ppc), 20 (alpha,sparc*), 18 (mips) */ - { "CONT", SIGCONT }, /* 18 (arm,i386,m68k,ppc), 19 (alpha,sparc*), 25 (mips) */ - { "STOP", SIGSTOP }, /* 19 (arm,i386,m68k,ppc), 17 (alpha,sparc*), 23 (mips) */ - { "TSTP", SIGTSTP }, /* 20 (arm,i386,m68k,ppc), 18 (alpha,sparc*), 24 (mips) */ - { "TTIN", SIGTTIN }, /* 21 (arm,i386,m68k,ppc,alpha,sparc*), 26 (mips) */ - { "TTOU", SIGTTOU }, /* 22 (arm,i386,m68k,ppc,alpha,sparc*), 27 (mips) */ - /* Miscellaneous other signals */ -#ifdef SIGTRAP - { "TRAP", SIGTRAP }, /* 5 */ -#endif -#ifdef SIGIOT - { "IOT", SIGIOT }, /* 6, same as SIGABRT */ -#endif -#ifdef SIGEMT - { "EMT", SIGEMT }, /* 7 (mips,alpha,sparc*) */ -#endif -#ifdef SIGBUS - { "BUS", SIGBUS }, /* 7 (arm,i386,m68k,ppc), 10 (mips,alpha,sparc*) */ -#endif -#ifdef SIGSYS - { "SYS", SIGSYS }, /* 12 (mips,alpha,sparc*) */ -#endif -#ifdef SIGSTKFLT - { "STKFLT", SIGSTKFLT }, /* 16 (arm,i386,m68k,ppc) */ -#endif -#ifdef SIGURG - { "URG", SIGURG }, /* 23 (arm,i386,m68k,ppc), 16 (alpha,sparc*), 21 (mips) */ -#endif -#ifdef SIGIO - { "IO", SIGIO }, /* 29 (arm,i386,m68k,ppc), 23 (alpha,sparc*), 22 (mips) */ -#endif -#ifdef SIGPOLL - { "POLL", SIGPOLL }, /* same as SIGIO */ -#endif -#ifdef SIGCLD - { "CLD", SIGCLD }, /* same as SIGCHLD (mips) */ -#endif -#ifdef SIGXCPU - { "XCPU", SIGXCPU }, /* 24 (arm,i386,m68k,ppc,alpha,sparc*), 30 (mips) */ -#endif -#ifdef SIGXFSZ - { "XFSZ", SIGXFSZ }, /* 25 (arm,i386,m68k,ppc,alpha,sparc*), 31 (mips) */ -#endif -#ifdef SIGVTALRM - { "VTALRM", SIGVTALRM }, /* 26 (arm,i386,m68k,ppc,alpha,sparc*), 28 (mips) */ -#endif -#ifdef SIGPROF - { "PROF", SIGPROF }, /* 27 (arm,i386,m68k,ppc,alpha,sparc*), 29 (mips) */ -#endif -#ifdef SIGPWR - { "PWR", SIGPWR }, /* 30 (arm,i386,m68k,ppc), 29 (alpha,sparc*), 19 (mips) */ -#endif -#ifdef SIGINFO - { "INFO", SIGINFO }, /* 29 (alpha) */ -#endif -#ifdef SIGLOST - { "LOST", SIGLOST }, /* 29 (arm,i386,m68k,ppc,sparc*) */ -#endif -#ifdef SIGWINCH - { "WINCH", SIGWINCH }, /* 28 (arm,i386,m68k,ppc,alpha,sparc*), 20 (mips) */ -#endif -#ifdef SIGUNUSED - { "UNUSED", SIGUNUSED }, /* 31 (arm,i386,m68k,ppc) */ -#endif - {0, 0} -}; extern int kill_main(int argc, char **argv) { int whichApp, sig = SIGTERM; + const char *name; #ifdef BB_KILLALL /* Figure out what we are trying to do here */ @@ -142,52 +57,37 @@ extern int kill_main(int argc, char **argv) while (*++(*argv)) { switch (**argv) { case 'l': - { + if(argc>1) { + for(argv++; *argv; argv++) { + name = u_signal_names(*argv, &sig, -1); + if(name!=NULL) + printf("%s\n", name); + } + } else { int col = 0; - const struct signal_name *s = signames; - - while (s->name != 0) { - col += fprintf(stderr, "%2d) %-8s", s->number, s->name); - s++; + for(sig=1; sig < NSIG; sig++) { + name = u_signal_names(0, &sig, 1); + if(name==NULL) /* unnamed */ + continue; + col += printf("%2d) %-16s", sig, name); if (col > 60) { - fprintf(stderr, "\n"); + printf("\n"); col = 0; } } - fprintf(stderr, "\n\n"); - return EXIT_SUCCESS; + printf("\n"); } - break; + return EXIT_SUCCESS; case '-': show_usage(); default: - { - if (isdigit(**argv)) { - sig = atoi(*argv); - if (sig < 0 || sig >= NSIG) - goto end; - else { - argc--; - argv++; - goto do_it_now; - } - } else { - const struct signal_name *s = signames; - - while (s->name != 0) { - if (strcasecmp(s->name, *argv) == 0) { - sig = s->number; + name = u_signal_names(*argv, &sig, 0); + if(name==NULL) + error_msg_and_die( "bad signal name: %s", *argv); argc--; argv++; goto do_it_now; } - s++; - } - if (s->name == 0) - goto end; - } - } - } argc--; argv++; } @@ -239,8 +139,4 @@ extern int kill_main(int argc, char **argv) #endif return EXIT_SUCCESS; - - - end: - error_msg_and_die( "bad signal name: %s", *argv); } diff --git a/shell/ash.c b/shell/ash.c index b1aec6278..bcd12f106 100644 --- a/shell/ash.c +++ b/shell/ash.c @@ -52,6 +52,7 @@ /* If you need ash to act as a full Posix shell, with full math * support, enable this. This adds a bit over 2k an x86 system. */ +//#undef ASH_MATH_SUPPORT #define ASH_MATH_SUPPORT /* Getopts is used by shell procedures to parse positional parameters. @@ -78,8 +79,6 @@ /* These are here to work with glibc -- Don't change these... */ #undef FNMATCH_BROKEN #undef GLOB_BROKEN -#undef _GNU_SOURCE -#undef __USE_GNU #include <assert.h> #include <ctype.h> @@ -4839,6 +4838,7 @@ static void expari(int flag) { char *p, *start; + int errcode; int result; int begoff; int quotes = flag & (EXP_FULL | EXP_CASE); @@ -4877,9 +4877,13 @@ expari(int flag) removerecordregions(begoff); if (quotes) rmescapes(p+2); - result = arith(p+2); - if (result < 0) - error("arith: syntax error: \"%s\"\n", p+2); + result = arith(p+2, &errcode); + if (errcode < 0) { + if(errcode == -2) + error("divide by zero"); + else + error("syntax error: \"%s\"\n", p+2); + } snprintf(p, 12, "%d", result); while (*p++) @@ -5429,9 +5433,9 @@ expandmeta(str, flag) goto nometa; p = preglob(str->text); INTOFF; - switch (glob(p, GLOB_NOMAGIC, 0, &pglob)) { + switch (glob(p, 0, 0, &pglob)) { case 0: - if (!(pglob.gl_flags & GLOB_MAGCHAR)) + if(pglob.gl_pathv[1]==0 && !strcmp(p, pglob.gl_pathv[0])) goto nometa2; addglob(&pglob); globfree(&pglob); @@ -6006,7 +6010,7 @@ static int histcmd(argc, argv) struct redirtab { struct redirtab *next; short renamed[10]; /* Current ash support only 0-9 descriptors */ - /* char renamed[10]; */ /* char on arm (and others) can't be negative */ + /* char on arm (and others) can't be negative */ }; static struct redirtab *redirlist; @@ -6166,7 +6170,7 @@ preadfd(void) retry: #ifdef BB_FEATURE_COMMAND_EDITING { - if (parsefile->fd) + if (!iflag || parsefile->fd) nr = safe_read(parsefile->fd, buf, BUFSIZ - 1); else { nr = cmdedit_read_input((char*)cmdedit_prompt, buf); @@ -6468,80 +6472,6 @@ static void setjobctl(int enable) #endif -/* A translation list so we can be polite to our users. */ -static char *signal_names[NSIG + 2] = { - "EXIT", - "SIGHUP", - "SIGINT", - "SIGQUIT", - "SIGILL", - "SIGTRAP", - "SIGABRT", - "SIGBUS", - "SIGFPE", - "SIGKILL", - "SIGUSR1", - "SIGSEGV", - "SIGUSR2", - "SIGPIPE", - "SIGALRM", - "SIGTERM", - "SIGJUNK(16)", - "SIGCHLD", - "SIGCONT", - "SIGSTOP", - "SIGTSTP", - "SIGTTIN", - "SIGTTOU", - "SIGURG", - "SIGXCPU", - "SIGXFSZ", - "SIGVTALRM", - "SIGPROF", - "SIGWINCH", - "SIGIO", - "SIGPWR", - "SIGSYS", -#ifdef SIGRTMIN - "SIGRTMIN", - "SIGRTMIN+1", - "SIGRTMIN+2", - "SIGRTMIN+3", - "SIGRTMIN+4", - "SIGRTMIN+5", - "SIGRTMIN+6", - "SIGRTMIN+7", - "SIGRTMIN+8", - "SIGRTMIN+9", - "SIGRTMIN+10", - "SIGRTMIN+11", - "SIGRTMIN+12", - "SIGRTMIN+13", - "SIGRTMIN+14", - "SIGRTMIN+15", - "SIGRTMAX-15", - "SIGRTMAX-14", - "SIGRTMAX-13", - "SIGRTMAX-12", - "SIGRTMAX-11", - "SIGRTMAX-10", - "SIGRTMAX-9", - "SIGRTMAX-8", - "SIGRTMAX-7", - "SIGRTMAX-6", - "SIGRTMAX-5", - "SIGRTMAX-4", - "SIGRTMAX-3", - "SIGRTMAX-2", - "SIGRTMAX-1", - "SIGRTMAX", -#endif - "DEBUG", - (char *)0x0, -}; - - - #ifdef JOBS static int killcmd(argc, argv) @@ -6599,18 +6529,20 @@ usage: } if (list) { + const char *name; + if (!*argptr) { out1str("0\n"); for (i = 1; i < NSIG; i++) { - printf(snlfmt, signal_names[i] + 3); + name = u_signal_names(0, &i, 1); + if(name) + printf(snlfmt, name); } return 0; } - signo = atoi(*argptr); - if (signo > 128) - signo -= 128; - if (0 < signo && signo < NSIG) - printf(snlfmt, signal_names[signo] + 3); + name = u_signal_names(*argptr, &signo, -1); + if (name) + printf(snlfmt, name); else error("invalid signal number or exit status: %s", *argptr); @@ -8834,12 +8766,6 @@ copynodelist(const struct nodelist *lp) static char * nodesavestr(const char *s) { -#ifdef _GNU_SOURCE - char *rtn = funcstring; - - funcstring = stpcpy(funcstring, s) + 1; - return rtn; -#else const char *p = s; char *q = funcstring; char *rtn = funcstring; @@ -8848,7 +8774,6 @@ nodesavestr(const char *s) continue; funcstring = q; return rtn; -#endif } #ifdef ASH_GETOPTS @@ -12052,11 +11977,15 @@ trapcmd(argc, argv) for (signo = 0 ; signo < NSIG ; signo++) { if (trap[signo] != NULL) { char *p; + const char *sn; p = single_quote(trap[signo]); - printf("trap -- %s %s\n", p, - signal_names[signo] + (signo ? 3 : 0) - ); + sn = sys_siglist[signo]; + if(sn==NULL) + sn = u_signal_names(0, &signo, 0); + if(sn==NULL) + sn = "???"; + printf("trap -- %s %s\n", p, sn); stunalloc(p); } } @@ -12273,30 +12202,11 @@ l2: _exit(status); static int decode_signal(const char *string, int minsig) { int signo; + const char *name = u_signal_names(string, &signo, minsig); - if (is_number(string, &signo)) { - if (signo >= NSIG) { - return -1; - } - return signo; - } - - signo = minsig; - if (!signo) { - goto zero; - } - for (; signo < NSIG; signo++) { - if (!strcasecmp(string, &(signal_names[signo])[3])) { - return signo; - } -zero: - if (!strcasecmp(string, signal_names[signo])) { - return signo; - } - } - - return -1; + return name ? signo : -1; } + static struct var **hashvar (const char *); static void showvars (const char *, int, int); static struct var **findvar (struct var **, const char *); @@ -12616,6 +12526,7 @@ found:; return 0; } + /* * The "local" command. */ @@ -12874,7 +12785,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.16 2001/08/01 17:21:33 kraai Exp $ + * $Id: ash.c,v 1.17 2001/08/02 05:02:45 andersen Exp $ */ static int timescmd (int argc, char **argv) { @@ -12894,24 +12805,32 @@ static int timescmd (int argc, char **argv) return 0; } - #ifdef ASH_MATH_SUPPORT /* The let builtin. */ int letcmd(int argc, char **argv) { + int errcode; long result=0; if (argc == 2) { char *tmp, *expression, p[13]; expression = strchr(argv[1], '='); if (!expression) { + /* Cannot use 'error()' here, or the return code + * will be incorrect */ out2fmt("sh: let: syntax error: \"%s\"\n", argv[1]); return 0; } *expression = '\0'; tmp = ++expression; - result = arith(tmp); - if (result < 0) { - out2fmt("sh: let: syntax error: \"%s=%s\"\n", argv[1], expression); + result = arith(tmp, &errcode); + if (errcode < 0) { + /* Cannot use 'error()' here, or the return code + * will be incorrect */ + out2fmt("sh: let: "); + if(errcode == -2) + out2fmt("divide by zero"); + else + out2fmt("syntax error: \"%s=%s\"\n", argv[1], expression); return 0; } snprintf(p, 12, "%ld", result); diff --git a/shell/cmdedit.c b/shell/cmdedit.c index 3b4750455..2ec81548d 100644 --- a/shell/cmdedit.c +++ b/shell/cmdedit.c @@ -1167,25 +1167,21 @@ int cmdedit_read_input(char *prompt, char command[BUFSIZ]) len = 0; command_ps = command; - if (new_settings.c_cc[VERASE] == 0) { /* first call */ - - getTermSettings(0, (void *) &initial_settings); - memcpy(&new_settings, &initial_settings, sizeof(struct termios)); - new_settings.c_lflag &= ~ICANON; /* unbuffered input */ - /* Turn off echoing and CTRL-C, so we can trap it */ - new_settings.c_lflag &= ~(ECHO | ECHONL | ISIG); + getTermSettings(0, (void *) &initial_settings); + memcpy(&new_settings, &initial_settings, sizeof(struct termios)); + new_settings.c_lflag &= ~ICANON; /* unbuffered input */ + /* Turn off echoing and CTRL-C, so we can trap it */ + new_settings.c_lflag &= ~(ECHO | ECHONL | ISIG); #ifndef linux - /* Hmm, in linux c_cc[] not parsed if set ~ICANON */ - new_settings.c_cc[VMIN] = 1; - new_settings.c_cc[VTIME] = 0; - /* Turn off CTRL-C, so we can trap it */ + /* Hmm, in linux c_cc[] not parsed if set ~ICANON */ + new_settings.c_cc[VMIN] = 1; + new_settings.c_cc[VTIME] = 0; + /* Turn off CTRL-C, so we can trap it */ # ifndef _POSIX_VDISABLE # define _POSIX_VDISABLE '\0' # endif - new_settings.c_cc[VINTR] = _POSIX_VDISABLE; + new_settings.c_cc[VINTR] = _POSIX_VDISABLE; #endif - } - command[0] = 0; setTermSettings(0, (void *) &new_settings); @@ -69,9 +69,6 @@ extern int update_main(int argc, char **argv) if (daemon(0, 1) < 0) perror_msg_and_die("daemon"); - /* Become a proper daemon */ - setsid(); - chdir("/"); #ifdef OPEN_MAX for (pid = 0; pid < OPEN_MAX; pid++) close(pid); #else diff --git a/uudecode.c b/uudecode.c index 6ac9f1bf3..a4059ddfe 100644 --- a/uudecode.c +++ b/uudecode.c @@ -201,9 +201,8 @@ static int decode (const char *inname, const char *forced_outname) { struct passwd *pw; - register int n; register char *p; - int mode, n1; + int mode; char buf[2 * BUFSIZ]; char *outname; int do_base64 = 0; @@ -249,12 +248,7 @@ static int decode (const char *inname, error_msg("%s: No user `%s'", inname, buf + 1); return FALSE; } - n = strlen (pw->pw_dir); - n1 = strlen (p); - outname = (char *) xmalloc ((size_t) (n + n1 + 2)); - memcpy (outname + n + 1, p, (size_t) (n1 + 1)); - memcpy (outname, pw->pw_dir, (size_t) n); - outname[n] = '/'; + outname = concat_path_file(pw->pw_dir, p); dofre = TRUE; } } |