aboutsummaryrefslogtreecommitdiff
path: root/ash.c
diff options
context:
space:
mode:
authorEric Andersen <andersen@codepoet.org>2001-08-02 05:02:46 +0000
committerEric Andersen <andersen@codepoet.org>2001-08-02 05:02:46 +0000
commit34506361697643277042fc8d7294bc17a27d4e28 (patch)
treebf2c45a12020be4e0a37547abb50c40c0074e8ec /ash.c
parent2d91deba45d5a284614e06cc55e2be03599ca26d (diff)
downloadbusybox-w32-34506361697643277042fc8d7294bc17a27d4e28.tar.gz
busybox-w32-34506361697643277042fc8d7294bc17a27d4e28.tar.bz2
busybox-w32-34506361697643277042fc8d7294bc17a27d4e28.zip
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.
Diffstat (limited to 'ash.c')
-rw-r--r--ash.c171
1 files changed, 45 insertions, 126 deletions
diff --git a/ash.c b/ash.c
index b1aec6278..bcd12f106 100644
--- a/ash.c
+++ b/ash.c
@@ -52,6 +52,7 @@
52 52
53/* If you need ash to act as a full Posix shell, with full math 53/* If you need ash to act as a full Posix shell, with full math
54 * support, enable this. This adds a bit over 2k an x86 system. */ 54 * support, enable this. This adds a bit over 2k an x86 system. */
55//#undef ASH_MATH_SUPPORT
55#define ASH_MATH_SUPPORT 56#define ASH_MATH_SUPPORT
56 57
57/* Getopts is used by shell procedures to parse positional parameters. 58/* Getopts is used by shell procedures to parse positional parameters.
@@ -78,8 +79,6 @@
78/* These are here to work with glibc -- Don't change these... */ 79/* These are here to work with glibc -- Don't change these... */
79#undef FNMATCH_BROKEN 80#undef FNMATCH_BROKEN
80#undef GLOB_BROKEN 81#undef GLOB_BROKEN
81#undef _GNU_SOURCE
82#undef __USE_GNU
83 82
84#include <assert.h> 83#include <assert.h>
85#include <ctype.h> 84#include <ctype.h>
@@ -4839,6 +4838,7 @@ static void
4839expari(int flag) 4838expari(int flag)
4840{ 4839{
4841 char *p, *start; 4840 char *p, *start;
4841 int errcode;
4842 int result; 4842 int result;
4843 int begoff; 4843 int begoff;
4844 int quotes = flag & (EXP_FULL | EXP_CASE); 4844 int quotes = flag & (EXP_FULL | EXP_CASE);
@@ -4877,9 +4877,13 @@ expari(int flag)
4877 removerecordregions(begoff); 4877 removerecordregions(begoff);
4878 if (quotes) 4878 if (quotes)
4879 rmescapes(p+2); 4879 rmescapes(p+2);
4880 result = arith(p+2); 4880 result = arith(p+2, &errcode);
4881 if (result < 0) 4881 if (errcode < 0) {
4882 error("arith: syntax error: \"%s\"\n", p+2); 4882 if(errcode == -2)
4883 error("divide by zero");
4884 else
4885 error("syntax error: \"%s\"\n", p+2);
4886 }
4883 snprintf(p, 12, "%d", result); 4887 snprintf(p, 12, "%d", result);
4884 4888
4885 while (*p++) 4889 while (*p++)
@@ -5429,9 +5433,9 @@ expandmeta(str, flag)
5429 goto nometa; 5433 goto nometa;
5430 p = preglob(str->text); 5434 p = preglob(str->text);
5431 INTOFF; 5435 INTOFF;
5432 switch (glob(p, GLOB_NOMAGIC, 0, &pglob)) { 5436 switch (glob(p, 0, 0, &pglob)) {
5433 case 0: 5437 case 0:
5434 if (!(pglob.gl_flags & GLOB_MAGCHAR)) 5438 if(pglob.gl_pathv[1]==0 && !strcmp(p, pglob.gl_pathv[0]))
5435 goto nometa2; 5439 goto nometa2;
5436 addglob(&pglob); 5440 addglob(&pglob);
5437 globfree(&pglob); 5441 globfree(&pglob);
@@ -6006,7 +6010,7 @@ static int histcmd(argc, argv)
6006struct redirtab { 6010struct redirtab {
6007 struct redirtab *next; 6011 struct redirtab *next;
6008 short renamed[10]; /* Current ash support only 0-9 descriptors */ 6012 short renamed[10]; /* Current ash support only 0-9 descriptors */
6009 /* char renamed[10]; */ /* char on arm (and others) can't be negative */ 6013 /* char on arm (and others) can't be negative */
6010}; 6014};
6011 6015
6012static struct redirtab *redirlist; 6016static struct redirtab *redirlist;
@@ -6166,7 +6170,7 @@ preadfd(void)
6166retry: 6170retry:
6167#ifdef BB_FEATURE_COMMAND_EDITING 6171#ifdef BB_FEATURE_COMMAND_EDITING
6168 { 6172 {
6169 if (parsefile->fd) 6173 if (!iflag || parsefile->fd)
6170 nr = safe_read(parsefile->fd, buf, BUFSIZ - 1); 6174 nr = safe_read(parsefile->fd, buf, BUFSIZ - 1);
6171 else { 6175 else {
6172 nr = cmdedit_read_input((char*)cmdedit_prompt, buf); 6176 nr = cmdedit_read_input((char*)cmdedit_prompt, buf);
@@ -6468,80 +6472,6 @@ static void setjobctl(int enable)
6468#endif 6472#endif
6469 6473
6470 6474
6471/* A translation list so we can be polite to our users. */
6472static char *signal_names[NSIG + 2] = {
6473 "EXIT",
6474 "SIGHUP",
6475 "SIGINT",
6476 "SIGQUIT",
6477 "SIGILL",
6478 "SIGTRAP",
6479 "SIGABRT",
6480 "SIGBUS",
6481 "SIGFPE",
6482 "SIGKILL",
6483 "SIGUSR1",
6484 "SIGSEGV",
6485 "SIGUSR2",
6486 "SIGPIPE",
6487 "SIGALRM",
6488 "SIGTERM",
6489 "SIGJUNK(16)",
6490 "SIGCHLD",
6491 "SIGCONT",
6492 "SIGSTOP",
6493 "SIGTSTP",
6494 "SIGTTIN",
6495 "SIGTTOU",
6496 "SIGURG",
6497 "SIGXCPU",
6498 "SIGXFSZ",
6499 "SIGVTALRM",
6500 "SIGPROF",
6501 "SIGWINCH",
6502 "SIGIO",
6503 "SIGPWR",
6504 "SIGSYS",
6505#ifdef SIGRTMIN
6506 "SIGRTMIN",
6507 "SIGRTMIN+1",
6508 "SIGRTMIN+2",
6509 "SIGRTMIN+3",
6510 "SIGRTMIN+4",
6511 "SIGRTMIN+5",
6512 "SIGRTMIN+6",
6513 "SIGRTMIN+7",
6514 "SIGRTMIN+8",
6515 "SIGRTMIN+9",
6516 "SIGRTMIN+10",
6517 "SIGRTMIN+11",
6518 "SIGRTMIN+12",
6519 "SIGRTMIN+13",
6520 "SIGRTMIN+14",
6521 "SIGRTMIN+15",
6522 "SIGRTMAX-15",
6523 "SIGRTMAX-14",
6524 "SIGRTMAX-13",
6525 "SIGRTMAX-12",
6526 "SIGRTMAX-11",
6527 "SIGRTMAX-10",
6528 "SIGRTMAX-9",
6529 "SIGRTMAX-8",
6530 "SIGRTMAX-7",
6531 "SIGRTMAX-6",
6532 "SIGRTMAX-5",
6533 "SIGRTMAX-4",
6534 "SIGRTMAX-3",
6535 "SIGRTMAX-2",
6536 "SIGRTMAX-1",
6537 "SIGRTMAX",
6538#endif
6539 "DEBUG",
6540 (char *)0x0,
6541};
6542
6543
6544
6545#ifdef JOBS 6475#ifdef JOBS
6546static int 6476static int
6547killcmd(argc, argv) 6477killcmd(argc, argv)
@@ -6599,18 +6529,20 @@ usage:
6599 } 6529 }
6600 6530
6601 if (list) { 6531 if (list) {
6532 const char *name;
6533
6602 if (!*argptr) { 6534 if (!*argptr) {
6603 out1str("0\n"); 6535 out1str("0\n");
6604 for (i = 1; i < NSIG; i++) { 6536 for (i = 1; i < NSIG; i++) {
6605 printf(snlfmt, signal_names[i] + 3); 6537 name = u_signal_names(0, &i, 1);
6538 if(name)
6539 printf(snlfmt, name);
6606 } 6540 }
6607 return 0; 6541 return 0;
6608 } 6542 }
6609 signo = atoi(*argptr); 6543 name = u_signal_names(*argptr, &signo, -1);
6610 if (signo > 128) 6544 if (name)
6611 signo -= 128; 6545 printf(snlfmt, name);
6612 if (0 < signo && signo < NSIG)
6613 printf(snlfmt, signal_names[signo] + 3);
6614 else 6546 else
6615 error("invalid signal number or exit status: %s", 6547 error("invalid signal number or exit status: %s",
6616 *argptr); 6548 *argptr);
@@ -8834,12 +8766,6 @@ copynodelist(const struct nodelist *lp)
8834static char * 8766static char *
8835nodesavestr(const char *s) 8767nodesavestr(const char *s)
8836{ 8768{
8837#ifdef _GNU_SOURCE
8838 char *rtn = funcstring;
8839
8840 funcstring = stpcpy(funcstring, s) + 1;
8841 return rtn;
8842#else
8843 const char *p = s; 8769 const char *p = s;
8844 char *q = funcstring; 8770 char *q = funcstring;
8845 char *rtn = funcstring; 8771 char *rtn = funcstring;
@@ -8848,7 +8774,6 @@ nodesavestr(const char *s)
8848 continue; 8774 continue;
8849 funcstring = q; 8775 funcstring = q;
8850 return rtn; 8776 return rtn;
8851#endif
8852} 8777}
8853 8778
8854#ifdef ASH_GETOPTS 8779#ifdef ASH_GETOPTS
@@ -12052,11 +11977,15 @@ trapcmd(argc, argv)
12052 for (signo = 0 ; signo < NSIG ; signo++) { 11977 for (signo = 0 ; signo < NSIG ; signo++) {
12053 if (trap[signo] != NULL) { 11978 if (trap[signo] != NULL) {
12054 char *p; 11979 char *p;
11980 const char *sn;
12055 11981
12056 p = single_quote(trap[signo]); 11982 p = single_quote(trap[signo]);
12057 printf("trap -- %s %s\n", p, 11983 sn = sys_siglist[signo];
12058 signal_names[signo] + (signo ? 3 : 0) 11984 if(sn==NULL)
12059 ); 11985 sn = u_signal_names(0, &signo, 0);
11986 if(sn==NULL)
11987 sn = "???";
11988 printf("trap -- %s %s\n", p, sn);
12060 stunalloc(p); 11989 stunalloc(p);
12061 } 11990 }
12062 } 11991 }
@@ -12273,30 +12202,11 @@ l2: _exit(status);
12273static int decode_signal(const char *string, int minsig) 12202static int decode_signal(const char *string, int minsig)
12274{ 12203{
12275 int signo; 12204 int signo;
12205 const char *name = u_signal_names(string, &signo, minsig);
12276 12206
12277 if (is_number(string, &signo)) { 12207 return name ? signo : -1;
12278 if (signo >= NSIG) {
12279 return -1;
12280 }
12281 return signo;
12282 }
12283
12284 signo = minsig;
12285 if (!signo) {
12286 goto zero;
12287 }
12288 for (; signo < NSIG; signo++) {
12289 if (!strcasecmp(string, &(signal_names[signo])[3])) {
12290 return signo;
12291 }
12292zero:
12293 if (!strcasecmp(string, signal_names[signo])) {
12294 return signo;
12295 }
12296 }
12297
12298 return -1;
12299} 12208}
12209
12300static struct var **hashvar (const char *); 12210static struct var **hashvar (const char *);
12301static void showvars (const char *, int, int); 12211static void showvars (const char *, int, int);
12302static struct var **findvar (struct var **, const char *); 12212static struct var **findvar (struct var **, const char *);
@@ -12616,6 +12526,7 @@ found:;
12616 return 0; 12526 return 0;
12617} 12527}
12618 12528
12529
12619/* 12530/*
12620 * The "local" command. 12531 * The "local" command.
12621 */ 12532 */
@@ -12874,7 +12785,7 @@ findvar(struct var **vpp, const char *name)
12874/* 12785/*
12875 * Copyright (c) 1999 Herbert Xu <herbert@debian.org> 12786 * Copyright (c) 1999 Herbert Xu <herbert@debian.org>
12876 * This file contains code for the times builtin. 12787 * This file contains code for the times builtin.
12877 * $Id: ash.c,v 1.16 2001/08/01 17:21:33 kraai Exp $ 12788 * $Id: ash.c,v 1.17 2001/08/02 05:02:45 andersen Exp $
12878 */ 12789 */
12879static int timescmd (int argc, char **argv) 12790static int timescmd (int argc, char **argv)
12880{ 12791{
@@ -12894,24 +12805,32 @@ static int timescmd (int argc, char **argv)
12894 return 0; 12805 return 0;
12895} 12806}
12896 12807
12897
12898#ifdef ASH_MATH_SUPPORT 12808#ifdef ASH_MATH_SUPPORT
12899/* The let builtin. */ 12809/* The let builtin. */
12900int letcmd(int argc, char **argv) 12810int letcmd(int argc, char **argv)
12901{ 12811{
12812 int errcode;
12902 long result=0; 12813 long result=0;
12903 if (argc == 2) { 12814 if (argc == 2) {
12904 char *tmp, *expression, p[13]; 12815 char *tmp, *expression, p[13];
12905 expression = strchr(argv[1], '='); 12816 expression = strchr(argv[1], '=');
12906 if (!expression) { 12817 if (!expression) {
12818 /* Cannot use 'error()' here, or the return code
12819 * will be incorrect */
12907 out2fmt("sh: let: syntax error: \"%s\"\n", argv[1]); 12820 out2fmt("sh: let: syntax error: \"%s\"\n", argv[1]);
12908 return 0; 12821 return 0;
12909 } 12822 }
12910 *expression = '\0'; 12823 *expression = '\0';
12911 tmp = ++expression; 12824 tmp = ++expression;
12912 result = arith(tmp); 12825 result = arith(tmp, &errcode);
12913 if (result < 0) { 12826 if (errcode < 0) {
12914 out2fmt("sh: let: syntax error: \"%s=%s\"\n", argv[1], expression); 12827 /* Cannot use 'error()' here, or the return code
12828 * will be incorrect */
12829 out2fmt("sh: let: ");
12830 if(errcode == -2)
12831 out2fmt("divide by zero");
12832 else
12833 out2fmt("syntax error: \"%s=%s\"\n", argv[1], expression);
12915 return 0; 12834 return 0;
12916 } 12835 }
12917 snprintf(p, 12, "%ld", result); 12836 snprintf(p, 12, "%ld", result);