aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorGlenn L McGrath <bug1@ihug.co.nz>2004-01-13 10:19:37 +0000
committerGlenn L McGrath <bug1@ihug.co.nz>2004-01-13 10:19:37 +0000
commit76620620ecbf2e8d456e00592bd7d5f8e31a33d2 (patch)
tree8d8eb03ef1a5b00a3c0e334163bf3fa5dfc06e9f
parentdfb6211df36207a62ae39b9d3c670bb0dc1ebbd5 (diff)
downloadbusybox-w32-76620620ecbf2e8d456e00592bd7d5f8e31a33d2.tar.gz
busybox-w32-76620620ecbf2e8d456e00592bd7d5f8e31a33d2.tar.bz2
busybox-w32-76620620ecbf2e8d456e00592bd7d5f8e31a33d2.zip
Vodz last_patch_121, syncing with dash_0.4.19, reduce code size.
-rw-r--r--shell/ash.c289
1 files changed, 127 insertions, 162 deletions
diff --git a/shell/ash.c b/shell/ash.c
index fe99b02cb..b34f0583f 100644
--- a/shell/ash.c
+++ b/shell/ash.c
@@ -1214,7 +1214,7 @@ static char *nodesavestr(char *);
1214 1214
1215 1215
1216 1216
1217static void evalstring(char *, int); 1217static void evalstring(char *);
1218union node; /* BLETCH for ansi C */ 1218union node; /* BLETCH for ansi C */
1219static void evaltree(union node *, int); 1219static void evaltree(union node *, int);
1220static void evalbackcmd(union node *, struct backcmd *); 1220static void evalbackcmd(union node *, struct backcmd *);
@@ -2704,7 +2704,7 @@ evalcmd(int argc, char **argv)
2704 STPUTC('\0', concat); 2704 STPUTC('\0', concat);
2705 p = grabstackstr(concat); 2705 p = grabstackstr(concat);
2706 } 2706 }
2707 evalstring(p, EV_TESTED); 2707 evalstring(p);
2708 } 2708 }
2709 return exitstatus; 2709 return exitstatus;
2710} 2710}
@@ -2715,7 +2715,7 @@ evalcmd(int argc, char **argv)
2715 */ 2715 */
2716 2716
2717static void 2717static void
2718evalstring(char *s, int flag) 2718evalstring(char *s)
2719{ 2719{
2720 union node *n; 2720 union node *n;
2721 struct stackmark smark; 2721 struct stackmark smark;
@@ -2724,7 +2724,7 @@ evalstring(char *s, int flag)
2724 setinputstring(s); 2724 setinputstring(s);
2725 2725
2726 while ((n = parsecmd(0)) != NEOF) { 2726 while ((n = parsecmd(0)) != NEOF) {
2727 evaltree(n, flag); 2727 evaltree(n, 0);
2728 popstackmark(&smark); 2728 popstackmark(&smark);
2729 if (evalskip) 2729 if (evalskip)
2730 break; 2730 break;
@@ -4496,10 +4496,9 @@ static char *exptilde(char *, char *, int);
4496static void expbackq(union node *, int, int); 4496static void expbackq(union node *, int, int);
4497static const char *subevalvar(char *, char *, int, int, int, int, int); 4497static const char *subevalvar(char *, char *, int, int, int, int, int);
4498static char *evalvar(char *, int); 4498static char *evalvar(char *, int);
4499static int varisset(char *, int);
4500static void strtodest(const char *, int, int); 4499static void strtodest(const char *, int, int);
4501static void memtodest(const char *p, size_t len, int syntax, int quotes); 4500static void memtodest(const char *p, size_t len, int syntax, int quotes);
4502static void varvalue(char *, int, int); 4501static ssize_t varvalue(char *, int, int);
4503static void recordregion(int, int, int); 4502static void recordregion(int, int, int);
4504static void removerecordregions(int); 4503static void removerecordregions(int);
4505static void ifsbreakup(char *, struct arglist *); 4504static void ifsbreakup(char *, struct arglist *);
@@ -5112,9 +5111,8 @@ evalvar(char *p, int flag)
5112 char *var; 5111 char *var;
5113 int patloc; 5112 int patloc;
5114 int c; 5113 int c;
5115 int set;
5116 int startloc; 5114 int startloc;
5117 size_t varlen; 5115 ssize_t varlen;
5118 int easy; 5116 int easy;
5119 int quotes; 5117 int quotes;
5120 int quoted; 5118 int quoted;
@@ -5125,48 +5123,22 @@ evalvar(char *p, int flag)
5125 quoted = varflags & VSQUOTE; 5123 quoted = varflags & VSQUOTE;
5126 var = p; 5124 var = p;
5127 easy = (!quoted || (*var == '@' && shellparam.nparam)); 5125 easy = (!quoted || (*var == '@' && shellparam.nparam));
5128 varlen = 0;
5129 startloc = expdest - (char *)stackblock(); 5126 startloc = expdest - (char *)stackblock();
5130 p = strchr(p, '=') + 1; 5127 p = strchr(p, '=') + 1;
5131 5128
5132 if (!is_name(*var)) {
5133 set = varisset(var, varflags & VSNUL);
5134 set--;
5135 if (subtype == VSPLUS)
5136 goto vsplus;
5137 if (++set) {
5138 varvalue(var, quoted, flag);
5139 if (subtype == VSLENGTH) {
5140 varlen =
5141 expdest - (char *)stackblock() -
5142 startloc;
5143 STADJUST(-varlen, expdest);
5144 goto vslen;
5145 }
5146 }
5147 } else {
5148 const char *val;
5149again: 5129again:
5150 /* jump here after setting a variable with ${var=text} */ 5130 varlen = varvalue(var, varflags, flag);
5151 val = lookupvar(var); 5131 if (varflags & VSNUL)
5152 set = !val || ((varflags & VSNUL) && !*val); 5132 varlen--;
5153 if (subtype == VSPLUS)
5154 goto vsplus;
5155 if (--set) {
5156 varlen = strlen(val);
5157 if (subtype == VSLENGTH)
5158 goto vslen;
5159 memtodest(
5160 val, varlen, quoted ? DQSYNTAX : BASESYNTAX,
5161 quotes
5162 );
5163 }
5164 }
5165 5133
5134 if (subtype == VSPLUS) {
5135 varlen = -1 - varlen;
5136 goto vsplus;
5137 }
5166 5138
5167 if (subtype == VSMINUS) { 5139 if (subtype == VSMINUS) {
5168vsplus: 5140vsplus:
5169 if (!set) { 5141 if (varlen < 0) {
5170 argstr( 5142 argstr(
5171 p, flag | EXP_TILDE | 5143 p, flag | EXP_TILDE |
5172 (quoted ? EXP_QWORD : EXP_WORD) 5144 (quoted ? EXP_QWORD : EXP_WORD)
@@ -5179,7 +5151,7 @@ vsplus:
5179 } 5151 }
5180 5152
5181 if (subtype == VSASSIGN || subtype == VSQUESTION) { 5153 if (subtype == VSASSIGN || subtype == VSQUESTION) {
5182 if (!set) { 5154 if (varlen < 0) {
5183 if (subevalvar(p, var, 0, subtype, startloc, 5155 if (subevalvar(p, var, 0, subtype, startloc,
5184 varflags, 0)) { 5156 varflags, 0)) {
5185 varflags &= ~VSNUL; 5157 varflags &= ~VSNUL;
@@ -5197,12 +5169,11 @@ vsplus:
5197 goto end; 5169 goto end;
5198 } 5170 }
5199 5171
5200 if (!set && uflag) 5172 if (varlen < 0 && uflag)
5201 varunset(p, var, 0, 0); 5173 varunset(p, var, 0, 0);
5202 5174
5203 if (subtype == VSLENGTH) { 5175 if (subtype == VSLENGTH) {
5204vslen: 5176 cvtnum(varlen > 0 ? varlen : 0);
5205 cvtnum(varlen);
5206 goto record; 5177 goto record;
5207 } 5178 }
5208 5179
@@ -5226,7 +5197,7 @@ record:
5226 } 5197 }
5227#endif 5198#endif
5228 5199
5229 if (set) { 5200 if (varlen >= 0) {
5230 /* 5201 /*
5231 * Terminate the string and start recording the pattern 5202 * Terminate the string and start recording the pattern
5232 * right after it 5203 * right after it
@@ -5252,7 +5223,7 @@ end:
5252 if ((c = *p++) == CTLESC) 5223 if ((c = *p++) == CTLESC)
5253 p++; 5224 p++;
5254 else if (c == CTLBACKQ || c == (CTLBACKQ|CTLQUOTE)) { 5225 else if (c == CTLBACKQ || c == (CTLBACKQ|CTLQUOTE)) {
5255 if (set) 5226 if (varlen >= 0)
5256 argbackq = argbackq->next; 5227 argbackq = argbackq->next;
5257 } else if (c == CTLVAR) { 5228 } else if (c == CTLVAR) {
5258 if ((*p++ & VSTYPE) != VSNORMAL) 5229 if ((*p++ & VSTYPE) != VSNORMAL)
@@ -5267,47 +5238,6 @@ end:
5267} 5238}
5268 5239
5269 5240
5270
5271/*
5272 * Test whether a specialized variable is set.
5273 */
5274
5275static int
5276varisset(char *name, int nulok)
5277{
5278 if (*name == '!')
5279 return backgndpid != 0;
5280 else if (*name == '@' || *name == '*') {
5281 if (*shellparam.p == NULL)
5282 return 0;
5283
5284 if (nulok) {
5285 char **av;
5286
5287 for (av = shellparam.p; *av; av++)
5288 if (**av != '\0')
5289 return 1;
5290 return 0;
5291 }
5292 } else if (is_digit(*name)) {
5293 char *ap;
5294 int num = atoi(name);
5295
5296 if (num > shellparam.nparam)
5297 return 0;
5298
5299 if (num == 0)
5300 ap = arg0;
5301 else
5302 ap = shellparam.p[num - 1];
5303
5304 if (nulok && (ap == NULL || *ap == '\0'))
5305 return 0;
5306 }
5307 return 1;
5308}
5309
5310
5311/* 5241/*
5312 * Put a string on the stack. 5242 * Put a string on the stack.
5313 */ 5243 */
@@ -5342,19 +5272,24 @@ strtodest(const char *p, int syntax, int quotes)
5342 * Add the value of a specialized variable to the stack string. 5272 * Add the value of a specialized variable to the stack string.
5343 */ 5273 */
5344 5274
5345static void 5275static ssize_t
5346varvalue(char *name, int quoted, int flags) 5276varvalue(char *name, int varflags, int flags)
5347{ 5277{
5348 int num; 5278 int num;
5349 char *p; 5279 char *p;
5350 int i; 5280 int i;
5351 int sep; 5281 int sep = 0;
5352 int sepq = 0; 5282 int sepq = 0;
5283 ssize_t len = 0;
5353 char **ap; 5284 char **ap;
5354 int syntax; 5285 int syntax;
5355 int allow_split = flags & EXP_FULL; 5286 int quoted = varflags & VSQUOTE;
5287 int subtype = varflags & VSTYPE;
5356 int quotes = flags & (EXP_FULL | EXP_CASE); 5288 int quotes = flags & (EXP_FULL | EXP_CASE);
5357 5289
5290 if (quoted && (flags & EXP_FULL))
5291 sep = 1 << CHAR_BIT;
5292
5358 syntax = quoted ? DQSYNTAX : BASESYNTAX; 5293 syntax = quoted ? DQSYNTAX : BASESYNTAX;
5359 switch (*name) { 5294 switch (*name) {
5360 case '$': 5295 case '$':
@@ -5368,48 +5303,86 @@ varvalue(char *name, int quoted, int flags)
5368 goto numvar; 5303 goto numvar;
5369 case '!': 5304 case '!':
5370 num = backgndpid; 5305 num = backgndpid;
5306 if (num == 0)
5307 return -1;
5371numvar: 5308numvar:
5372 cvtnum(num); 5309 len = cvtnum(num);
5373 break; 5310 break;
5374 case '-': 5311 case '-':
5375 for (i = 0 ; i < NOPTS ; i++) { 5312 p = makestrspace(NOPTS, expdest);
5376 if (optlist[i]) 5313 for (i = NOPTS - 1; i >= 0; i--) {
5377 STPUTC(optletters(i), expdest); 5314 if (optlist[i]) {
5315 USTPUTC(optletters(i), p);
5316 len++;
5317 }
5378 } 5318 }
5319 expdest = p;
5379 break; 5320 break;
5380 case '@': 5321 case '@':
5381 if (allow_split && quoted) { 5322 if (sep)
5382 sep = 1 << CHAR_BIT;
5383 goto param; 5323 goto param;
5384 }
5385 /* fall through */ 5324 /* fall through */
5386 case '*': 5325 case '*':
5387 sep = ifsset() ? ifsval()[0] : ' '; 5326 sep = ifsset() ? ifsval()[0] : ' ';
5388 if (quotes) { 5327 if (quotes && (SIT(sep, syntax) == CCTL || SIT(sep, syntax) == CBACK))
5389 sepq = (SIT(sep, syntax) == CCTL) || (SIT(sep, syntax) == CBACK); 5328 sepq = 1;
5390 }
5391param: 5329param:
5392 for (ap = shellparam.p ; (p = *ap++) != NULL ; ) { 5330 if (!(ap = shellparam.p))
5393 strtodest(p, syntax, quotes); 5331 return -1;
5394 if (*ap && sep) { 5332 while ((p = *ap++)) {
5395 p = expdest; 5333 size_t partlen;
5334
5335 partlen = strlen(p);
5336
5337 len += partlen;
5338 if (len > partlen && sep) {
5339 char *q;
5340
5341 len++;
5342 if (subtype == VSPLUS || subtype == VSLENGTH) {
5343 continue;
5344 }
5345 q = expdest;
5396 if (sepq) 5346 if (sepq)
5397 STPUTC(CTLESC, p); 5347 STPUTC(CTLESC, q);
5398 STPUTC(sep, p); 5348 STPUTC(sep, q);
5399 expdest = p; 5349 expdest = q;
5400 } 5350 }
5351
5352 if (!(subtype == VSPLUS || subtype == VSLENGTH))
5353 memtodest(p, partlen, syntax, quotes);
5401 } 5354 }
5402 break; 5355 return len;
5403 case '0': 5356 case '0':
5404 strtodest(arg0, syntax, quotes); 5357 case '1':
5405 break; 5358 case '2':
5406 default: 5359 case '3':
5360 case '4':
5361 case '5':
5362 case '6':
5363 case '7':
5364 case '8':
5365 case '9':
5407 num = atoi(name); 5366 num = atoi(name);
5408 if (num > 0 && num <= shellparam.nparam) { 5367 if (num < 0 || num > shellparam.nparam)
5409 strtodest(shellparam.p[num - 1], syntax, quotes); 5368 return -1;
5410 } 5369 p = num ? shellparam.p[num - 1] : arg0;
5411 break; 5370 goto value;
5371 default:
5372 p = lookupvar(name);
5373value:
5374 if (!p)
5375 return -1;
5376
5377 len = strlen(p);
5378 if (!(subtype == VSPLUS || subtype == VSLENGTH))
5379 memtodest(p, len, syntax, quotes);
5380 return len;
5412 } 5381 }
5382
5383 if (subtype == VSPLUS || subtype == VSLENGTH)
5384 STADJUST(-len, expdest);
5385 return len;
5413} 5386}
5414 5387
5415 5388
@@ -7946,7 +7919,7 @@ state2:
7946state3: 7919state3:
7947 state = 4; 7920 state = 4;
7948 if (minusc) 7921 if (minusc)
7949 evalstring(minusc, 0); 7922 evalstring(minusc);
7950 7923
7951 if (sflag || minusc == NULL) { 7924 if (sflag || minusc == NULL) {
7952#ifdef CONFIG_FEATURE_COMMAND_SAVEHISTORY 7925#ifdef CONFIG_FEATURE_COMMAND_SAVEHISTORY
@@ -7988,8 +7961,8 @@ cmdloop(int top)
7988 int numeof = 0; 7961 int numeof = 0;
7989 7962
7990 TRACE(("cmdloop(%d) called\n", top)); 7963 TRACE(("cmdloop(%d) called\n", top));
7991 setstackmark(&smark);
7992 for (;;) { 7964 for (;;) {
7965 setstackmark(&smark);
7993 if (pendingsigs) 7966 if (pendingsigs)
7994 dotrap(); 7967 dotrap();
7995#if JOBS 7968#if JOBS
@@ -8020,13 +7993,11 @@ cmdloop(int top)
8020 evaltree(n, 0); 7993 evaltree(n, 0);
8021 } 7994 }
8022 popstackmark(&smark); 7995 popstackmark(&smark);
8023 setstackmark(&smark); 7996 if (evalskip) {
8024 if (evalskip == SKIPFILE) {
8025 evalskip = 0; 7997 evalskip = 0;
8026 break; 7998 break;
8027 } 7999 }
8028 } 8000 }
8029 popstackmark(&smark);
8030} 8001}
8031 8002
8032 8003
@@ -11778,7 +11749,7 @@ dotrap(void)
11778 p = trap[p - q + 1]; 11749 p = trap[p - q + 1];
11779 if (!p) 11750 if (!p)
11780 continue; 11751 continue;
11781 evalstring(p, 0); 11752 evalstring(p);
11782 exitstatus = savestatus; 11753 exitstatus = savestatus;
11783 } 11754 }
11784} 11755}
@@ -11870,7 +11841,7 @@ exitshell(void)
11870 handler = &loc; 11841 handler = &loc;
11871 if ((p = trap[0]) != NULL && *p != '\0') { 11842 if ((p = trap[0]) != NULL && *p != '\0') {
11872 trap[0] = NULL; 11843 trap[0] = NULL;
11873 evalstring(p, 0); 11844 evalstring(p);
11874 } 11845 }
11875 flushall(); 11846 flushall();
11876#ifdef CONFIG_FEATURE_COMMAND_SAVEHISTORY 11847#ifdef CONFIG_FEATURE_COMMAND_SAVEHISTORY
@@ -12497,7 +12468,7 @@ letcmd(int argc, char **argv)
12497#undef rflag 12468#undef rflag
12498 12469
12499#ifdef __GLIBC__ 12470#ifdef __GLIBC__
12500#if !defined(__GLIBC__) || __GLIBC__ == 2 && __GLIBC_MINOR__ < 1 12471#if __GLIBC__ == 2 && __GLIBC_MINOR__ < 1
12501typedef enum __rlimit_resource rlim_t; 12472typedef enum __rlimit_resource rlim_t;
12502#endif 12473#endif
12503#endif 12474#endif
@@ -12694,34 +12665,52 @@ static const struct limits limits[] = {
12694 { "locked memory(kbytes)", RLIMIT_MEMLOCK, 1024, 'l' }, 12665 { "locked memory(kbytes)", RLIMIT_MEMLOCK, 1024, 'l' },
12695#endif 12666#endif
12696#ifdef RLIMIT_NPROC 12667#ifdef RLIMIT_NPROC
12697 { "process(processes)", RLIMIT_NPROC, 1, 'p' }, 12668 { "process", RLIMIT_NPROC, 1, 'p' },
12698#endif 12669#endif
12699#ifdef RLIMIT_NOFILE 12670#ifdef RLIMIT_NOFILE
12700 { "nofiles(descriptors)", RLIMIT_NOFILE, 1, 'n' }, 12671 { "nofiles", RLIMIT_NOFILE, 1, 'n' },
12701#endif 12672#endif
12702#ifdef RLIMIT_VMEM 12673#ifdef RLIMIT_AS
12703 { "vmemory(kbytes)", RLIMIT_VMEM, 1024, 'v' }, 12674 { "vmemory(kbytes)", RLIMIT_AS, 1024, 'v' },
12704#endif 12675#endif
12705#ifdef RLIMIT_SWAP 12676#ifdef RLIMIT_LOCKS
12706 { "swap(kbytes)", RLIMIT_SWAP, 1024, 'w' }, 12677 { "locks", RLIMIT_LOCKS, 1, 'w' },
12707#endif 12678#endif
12708 { (char *) 0, 0, 0, '\0' } 12679 { (char *) 0, 0, 0, '\0' }
12709}; 12680};
12710 12681
12682enum limtype { SOFT = 0x1, HARD = 0x2 };
12683
12684static void printlim(enum limtype how, const struct rlimit *limit,
12685 const struct limits *l)
12686{
12687 rlim_t val;
12688
12689 val = limit->rlim_max;
12690 if (how & SOFT)
12691 val = limit->rlim_cur;
12692
12693 if (val == RLIM_INFINITY)
12694 out1fmt("unlimited\n");
12695 else {
12696 val /= l->factor;
12697 out1fmt("%lld\n", (long long) val);
12698 }
12699}
12700
12711int 12701int
12712ulimitcmd(int argc, char **argv) 12702ulimitcmd(int argc, char **argv)
12713{ 12703{
12714 int c; 12704 int c;
12715 rlim_t val = 0; 12705 rlim_t val = 0;
12716 enum { SOFT = 0x1, HARD = 0x2 } 12706 enum limtype how = SOFT | HARD;
12717 how = SOFT | HARD;
12718 const struct limits *l; 12707 const struct limits *l;
12719 int set, all = 0; 12708 int set, all = 0;
12720 int optc, what; 12709 int optc, what;
12721 struct rlimit limit; 12710 struct rlimit limit;
12722 12711
12723 what = 'f'; 12712 what = 'f';
12724 while ((optc = nextopt("HSatfdsmcnpl")) != '\0') 12713 while ((optc = nextopt("HSatfdsmcnplvw")) != '\0')
12725 switch (optc) { 12714 switch (optc) {
12726 case 'H': 12715 case 'H':
12727 how = HARD; 12716 how = HARD;
@@ -12736,10 +12725,8 @@ ulimitcmd(int argc, char **argv)
12736 what = optc; 12725 what = optc;
12737 } 12726 }
12738 12727
12739 for (l = limits; l->name && l->option != what; l++) 12728 for (l = limits; l->option != what; l++)
12740 ; 12729 ;
12741 if (!l->name)
12742 error("internal error (%c)", what);
12743 12730
12744 set = *argptr ? 1 : 0; 12731 set = *argptr ? 1 : 0;
12745 if (set) { 12732 if (set) {
@@ -12766,19 +12753,8 @@ ulimitcmd(int argc, char **argv)
12766 if (all) { 12753 if (all) {
12767 for (l = limits; l->name; l++) { 12754 for (l = limits; l->name; l++) {
12768 getrlimit(l->cmd, &limit); 12755 getrlimit(l->cmd, &limit);
12769 if (how & SOFT)
12770 val = limit.rlim_cur;
12771 else if (how & HARD)
12772 val = limit.rlim_max;
12773
12774 out1fmt("%-20s ", l->name); 12756 out1fmt("%-20s ", l->name);
12775 if (val == RLIM_INFINITY) 12757 printlim(how, &limit, l);
12776 out1fmt("unlimited\n");
12777 else
12778 {
12779 val /= l->factor;
12780 out1fmt("%lld\n", (long long) val);
12781 }
12782 } 12758 }
12783 return 0; 12759 return 0;
12784 } 12760 }
@@ -12792,18 +12768,7 @@ ulimitcmd(int argc, char **argv)
12792 if (setrlimit(l->cmd, &limit) < 0) 12768 if (setrlimit(l->cmd, &limit) < 0)
12793 error("error setting limit (%m)"); 12769 error("error setting limit (%m)");
12794 } else { 12770 } else {
12795 if (how & SOFT) 12771 printlim(how, &limit, l);
12796 val = limit.rlim_cur;
12797 else if (how & HARD)
12798 val = limit.rlim_max;
12799
12800 if (val == RLIM_INFINITY)
12801 out1fmt("unlimited\n");
12802 else
12803 {
12804 val /= l->factor;
12805 out1fmt("%lld\n", (long long) val);
12806 }
12807 } 12772 }
12808 return 0; 12773 return 0;
12809} 12774}