summaryrefslogtreecommitdiff
path: root/shell
diff options
context:
space:
mode:
authorDenis Vlasenko <vda.linux@googlemail.com>2007-02-23 01:05:15 +0000
committerDenis Vlasenko <vda.linux@googlemail.com>2007-02-23 01:05:15 +0000
commita6704933dde751bfccf85b632361034367ad6ec5 (patch)
treed9ee0c6d801217d342a21052fa001d0720a5e466 /shell
parent5c67e3ed90f559b61b02aa013ad4dd7d57fce772 (diff)
downloadbusybox-w32-a6704933dde751bfccf85b632361034367ad6ec5.tar.gz
busybox-w32-a6704933dde751bfccf85b632361034367ad6ec5.tar.bz2
busybox-w32-a6704933dde751bfccf85b632361034367ad6ec5.zip
ash: cleanup part 6
Diffstat (limited to 'shell')
-rw-r--r--shell/ash.c577
1 files changed, 283 insertions, 294 deletions
diff --git a/shell/ash.c b/shell/ash.c
index 54fc8ea48..69b8ab0b9 100644
--- a/shell/ash.c
+++ b/shell/ash.c
@@ -3664,7 +3664,6 @@ printalias(const struct alias *ap)
3664#define EV_TESTED 02 /* exit status is checked; ignore -e flag */ 3664#define EV_TESTED 02 /* exit status is checked; ignore -e flag */
3665#define EV_BACKCMD 04 /* command executing within back quotes */ 3665#define EV_BACKCMD 04 /* command executing within back quotes */
3666 3666
3667
3668static void evalloop(union node *, int); 3667static void evalloop(union node *, int);
3669static void evalfor(union node *, int); 3668static void evalfor(union node *, int);
3670static void evalcase(union node *, int); 3669static void evalcase(union node *, int);
@@ -3677,13 +3676,11 @@ static int evalfun(struct funcnode *, int, char **, int);
3677static void prehash(union node *); 3676static void prehash(union node *);
3678static int bltincmd(int, char **); 3677static int bltincmd(int, char **);
3679 3678
3680
3681static const struct builtincmd bltin = { 3679static const struct builtincmd bltin = {
3682 "\0\0", bltincmd 3680 "\0\0", bltincmd
3683}; 3681};
3684 3682
3685 3683
3686
3687/* 3684/*
3688 * Evaluate a parse tree. The value is left in the global variable 3685 * Evaluate a parse tree. The value is left in the global variable
3689 * exitstatus. 3686 * exitstatus.
@@ -7277,13 +7274,6 @@ static struct job *curjob;
7277/* number of presumed living untracked jobs */ 7274/* number of presumed living untracked jobs */
7278static int jobless; 7275static int jobless;
7279 7276
7280#if JOBS
7281static char *commandtext(union node *);
7282static void cmdlist(union node *, int);
7283static void cmdtxt(union node *);
7284static void cmdputs(const char *);
7285#endif
7286
7287static void 7277static void
7288set_curjob(struct job *jp, unsigned mode) 7278set_curjob(struct job *jp, unsigned mode)
7289{ 7279{
@@ -7887,10 +7877,8 @@ showjob(FILE *out, struct job *jp, int mode)
7887 col += sizeof("Running") - 1; 7877 col += sizeof("Running") - 1;
7888 } else { 7878 } else {
7889 int status = psend[-1].status; 7879 int status = psend[-1].status;
7890#if JOBS
7891 if (jp->state == JOBSTOPPED) 7880 if (jp->state == JOBSTOPPED)
7892 status = jp->stopstatus; 7881 status = jp->stopstatus;
7893#endif
7894 col += sprint_status(s + col, status, 0); 7882 col += sprint_status(s + col, status, 0);
7895 } 7883 }
7896 7884
@@ -8143,6 +8131,288 @@ makejob(union node *node, int nprocs)
8143 return jp; 8131 return jp;
8144} 8132}
8145 8133
8134#if JOBS
8135/*
8136 * Return a string identifying a command (to be printed by the
8137 * jobs command).
8138 */
8139static char *cmdnextc;
8140
8141static void
8142cmdputs(const char *s)
8143{
8144 const char *p, *str;
8145 char c, cc[2] = " ";
8146 char *nextc;
8147 int subtype = 0;
8148 int quoted = 0;
8149 static const char vstype[VSTYPE + 1][4] = {
8150 "", "}", "-", "+", "?", "=",
8151 "%", "%%", "#", "##"
8152 };
8153
8154 nextc = makestrspace((strlen(s) + 1) * 8, cmdnextc);
8155 p = s;
8156 while ((c = *p++) != 0) {
8157 str = 0;
8158 switch (c) {
8159 case CTLESC:
8160 c = *p++;
8161 break;
8162 case CTLVAR:
8163 subtype = *p++;
8164 if ((subtype & VSTYPE) == VSLENGTH)
8165 str = "${#";
8166 else
8167 str = "${";
8168 if (!(subtype & VSQUOTE) == !(quoted & 1))
8169 goto dostr;
8170 quoted ^= 1;
8171 c = '"';
8172 break;
8173 case CTLENDVAR:
8174 str = "\"}" + !(quoted & 1);
8175 quoted >>= 1;
8176 subtype = 0;
8177 goto dostr;
8178 case CTLBACKQ:
8179 str = "$(...)";
8180 goto dostr;
8181 case CTLBACKQ+CTLQUOTE:
8182 str = "\"$(...)\"";
8183 goto dostr;
8184#if ENABLE_ASH_MATH_SUPPORT
8185 case CTLARI:
8186 str = "$((";
8187 goto dostr;
8188 case CTLENDARI:
8189 str = "))";
8190 goto dostr;
8191#endif
8192 case CTLQUOTEMARK:
8193 quoted ^= 1;
8194 c = '"';
8195 break;
8196 case '=':
8197 if (subtype == 0)
8198 break;
8199 if ((subtype & VSTYPE) != VSNORMAL)
8200 quoted <<= 1;
8201 str = vstype[subtype & VSTYPE];
8202 if (subtype & VSNUL)
8203 c = ':';
8204 else
8205 goto checkstr;
8206 break;
8207 case '\'':
8208 case '\\':
8209 case '"':
8210 case '$':
8211 /* These can only happen inside quotes */
8212 cc[0] = c;
8213 str = cc;
8214 c = '\\';
8215 break;
8216 default:
8217 break;
8218 }
8219 USTPUTC(c, nextc);
8220 checkstr:
8221 if (!str)
8222 continue;
8223 dostr:
8224 while ((c = *str++)) {
8225 USTPUTC(c, nextc);
8226 }
8227 }
8228 if (quoted & 1) {
8229 USTPUTC('"', nextc);
8230 }
8231 *nextc = 0;
8232 cmdnextc = nextc;
8233}
8234
8235/* cmdtxt() and cmdlist() call each other */
8236static void cmdtxt(union node *n);
8237
8238static void
8239cmdlist(union node *np, int sep)
8240{
8241 for (; np; np = np->narg.next) {
8242 if (!sep)
8243 cmdputs(spcstr);
8244 cmdtxt(np);
8245 if (sep && np->narg.next)
8246 cmdputs(spcstr);
8247 }
8248}
8249
8250static void
8251cmdtxt(union node *n)
8252{
8253 union node *np;
8254 struct nodelist *lp;
8255 const char *p;
8256 char s[2];
8257
8258 if (!n)
8259 return;
8260 switch (n->type) {
8261 default:
8262#if DEBUG
8263 abort();
8264#endif
8265 case NPIPE:
8266 lp = n->npipe.cmdlist;
8267 for (;;) {
8268 cmdtxt(lp->n);
8269 lp = lp->next;
8270 if (!lp)
8271 break;
8272 cmdputs(" | ");
8273 }
8274 break;
8275 case NSEMI:
8276 p = "; ";
8277 goto binop;
8278 case NAND:
8279 p = " && ";
8280 goto binop;
8281 case NOR:
8282 p = " || ";
8283 binop:
8284 cmdtxt(n->nbinary.ch1);
8285 cmdputs(p);
8286 n = n->nbinary.ch2;
8287 goto donode;
8288 case NREDIR:
8289 case NBACKGND:
8290 n = n->nredir.n;
8291 goto donode;
8292 case NNOT:
8293 cmdputs("!");
8294 n = n->nnot.com;
8295 donode:
8296 cmdtxt(n);
8297 break;
8298 case NIF:
8299 cmdputs("if ");
8300 cmdtxt(n->nif.test);
8301 cmdputs("; then ");
8302 n = n->nif.ifpart;
8303 if (n->nif.elsepart) {
8304 cmdtxt(n);
8305 cmdputs("; else ");
8306 n = n->nif.elsepart;
8307 }
8308 p = "; fi";
8309 goto dotail;
8310 case NSUBSHELL:
8311 cmdputs("(");
8312 n = n->nredir.n;
8313 p = ")";
8314 goto dotail;
8315 case NWHILE:
8316 p = "while ";
8317 goto until;
8318 case NUNTIL:
8319 p = "until ";
8320 until:
8321 cmdputs(p);
8322 cmdtxt(n->nbinary.ch1);
8323 n = n->nbinary.ch2;
8324 p = "; done";
8325 dodo:
8326 cmdputs("; do ");
8327 dotail:
8328 cmdtxt(n);
8329 goto dotail2;
8330 case NFOR:
8331 cmdputs("for ");
8332 cmdputs(n->nfor.var);
8333 cmdputs(" in ");
8334 cmdlist(n->nfor.args, 1);
8335 n = n->nfor.body;
8336 p = "; done";
8337 goto dodo;
8338 case NDEFUN:
8339 cmdputs(n->narg.text);
8340 p = "() { ... }";
8341 goto dotail2;
8342 case NCMD:
8343 cmdlist(n->ncmd.args, 1);
8344 cmdlist(n->ncmd.redirect, 0);
8345 break;
8346 case NARG:
8347 p = n->narg.text;
8348 dotail2:
8349 cmdputs(p);
8350 break;
8351 case NHERE:
8352 case NXHERE:
8353 p = "<<...";
8354 goto dotail2;
8355 case NCASE:
8356 cmdputs("case ");
8357 cmdputs(n->ncase.expr->narg.text);
8358 cmdputs(" in ");
8359 for (np = n->ncase.cases; np; np = np->nclist.next) {
8360 cmdtxt(np->nclist.pattern);
8361 cmdputs(") ");
8362 cmdtxt(np->nclist.body);
8363 cmdputs(";; ");
8364 }
8365 p = "esac";
8366 goto dotail2;
8367 case NTO:
8368 p = ">";
8369 goto redir;
8370 case NCLOBBER:
8371 p = ">|";
8372 goto redir;
8373 case NAPPEND:
8374 p = ">>";
8375 goto redir;
8376 case NTOFD:
8377 p = ">&";
8378 goto redir;
8379 case NFROM:
8380 p = "<";
8381 goto redir;
8382 case NFROMFD:
8383 p = "<&";
8384 goto redir;
8385 case NFROMTO:
8386 p = "<>";
8387 redir:
8388 s[0] = n->nfile.fd + '0';
8389 s[1] = '\0';
8390 cmdputs(s);
8391 cmdputs(p);
8392 if (n->type == NTOFD || n->type == NFROMFD) {
8393 s[0] = n->ndup.dupfd + '0';
8394 p = s;
8395 goto dotail2;
8396 }
8397 n = n->nfile.fname;
8398 goto donode;
8399 }
8400}
8401
8402static char *
8403commandtext(union node *n)
8404{
8405 char *name;
8406
8407 STARTSTACKSTR(cmdnextc);
8408 cmdtxt(n);
8409 name = stackblock();
8410 TRACE(("commandtext: name %p, end %p\n\t\"%s\"\n",
8411 name, cmdnextc, cmdnextc));
8412 return ckstrdup(name);
8413}
8414#endif /* JOBS */
8415
8146/* 8416/*
8147 * Fork off a subshell. If we are doing job control, give the subshell its 8417 * Fork off a subshell. If we are doing job control, give the subshell its
8148 * own process group. Jp is a job structure that the job is to be added to. 8418 * own process group. Jp is a job structure that the job is to be added to.
@@ -8332,289 +8602,10 @@ stoppedjobs(void)
8332 job_warning = 2; 8602 job_warning = 2;
8333 retval++; 8603 retval++;
8334 } 8604 }
8335 8605 out:
8336out:
8337 return retval; 8606 return retval;
8338} 8607}
8339 8608
8340/*
8341 * Return a string identifying a command (to be printed by the
8342 * jobs command).
8343 */
8344#if JOBS
8345static char *cmdnextc;
8346
8347static char *
8348commandtext(union node *n)
8349{
8350 char *name;
8351
8352 STARTSTACKSTR(cmdnextc);
8353 cmdtxt(n);
8354 name = stackblock();
8355 TRACE(("commandtext: name %p, end %p\n\t\"%s\"\n",
8356 name, cmdnextc, cmdnextc));
8357 return ckstrdup(name);
8358}
8359
8360static void
8361cmdtxt(union node *n)
8362{
8363 union node *np;
8364 struct nodelist *lp;
8365 const char *p;
8366 char s[2];
8367
8368 if (!n)
8369 return;
8370 switch (n->type) {
8371 default:
8372#if DEBUG
8373 abort();
8374#endif
8375 case NPIPE:
8376 lp = n->npipe.cmdlist;
8377 for (;;) {
8378 cmdtxt(lp->n);
8379 lp = lp->next;
8380 if (!lp)
8381 break;
8382 cmdputs(" | ");
8383 }
8384 break;
8385 case NSEMI:
8386 p = "; ";
8387 goto binop;
8388 case NAND:
8389 p = " && ";
8390 goto binop;
8391 case NOR:
8392 p = " || ";
8393 binop:
8394 cmdtxt(n->nbinary.ch1);
8395 cmdputs(p);
8396 n = n->nbinary.ch2;
8397 goto donode;
8398 case NREDIR:
8399 case NBACKGND:
8400 n = n->nredir.n;
8401 goto donode;
8402 case NNOT:
8403 cmdputs("!");
8404 n = n->nnot.com;
8405 donode:
8406 cmdtxt(n);
8407 break;
8408 case NIF:
8409 cmdputs("if ");
8410 cmdtxt(n->nif.test);
8411 cmdputs("; then ");
8412 n = n->nif.ifpart;
8413 if (n->nif.elsepart) {
8414 cmdtxt(n);
8415 cmdputs("; else ");
8416 n = n->nif.elsepart;
8417 }
8418 p = "; fi";
8419 goto dotail;
8420 case NSUBSHELL:
8421 cmdputs("(");
8422 n = n->nredir.n;
8423 p = ")";
8424 goto dotail;
8425 case NWHILE:
8426 p = "while ";
8427 goto until;
8428 case NUNTIL:
8429 p = "until ";
8430 until:
8431 cmdputs(p);
8432 cmdtxt(n->nbinary.ch1);
8433 n = n->nbinary.ch2;
8434 p = "; done";
8435 dodo:
8436 cmdputs("; do ");
8437 dotail:
8438 cmdtxt(n);
8439 goto dotail2;
8440 case NFOR:
8441 cmdputs("for ");
8442 cmdputs(n->nfor.var);
8443 cmdputs(" in ");
8444 cmdlist(n->nfor.args, 1);
8445 n = n->nfor.body;
8446 p = "; done";
8447 goto dodo;
8448 case NDEFUN:
8449 cmdputs(n->narg.text);
8450 p = "() { ... }";
8451 goto dotail2;
8452 case NCMD:
8453 cmdlist(n->ncmd.args, 1);
8454 cmdlist(n->ncmd.redirect, 0);
8455 break;
8456 case NARG:
8457 p = n->narg.text;
8458 dotail2:
8459 cmdputs(p);
8460 break;
8461 case NHERE:
8462 case NXHERE:
8463 p = "<<...";
8464 goto dotail2;
8465 case NCASE:
8466 cmdputs("case ");
8467 cmdputs(n->ncase.expr->narg.text);
8468 cmdputs(" in ");
8469 for (np = n->ncase.cases; np; np = np->nclist.next) {
8470 cmdtxt(np->nclist.pattern);
8471 cmdputs(") ");
8472 cmdtxt(np->nclist.body);
8473 cmdputs(";; ");
8474 }
8475 p = "esac";
8476 goto dotail2;
8477 case NTO:
8478 p = ">";
8479 goto redir;
8480 case NCLOBBER:
8481 p = ">|";
8482 goto redir;
8483 case NAPPEND:
8484 p = ">>";
8485 goto redir;
8486 case NTOFD:
8487 p = ">&";
8488 goto redir;
8489 case NFROM:
8490 p = "<";
8491 goto redir;
8492 case NFROMFD:
8493 p = "<&";
8494 goto redir;
8495 case NFROMTO:
8496 p = "<>";
8497 redir:
8498 s[0] = n->nfile.fd + '0';
8499 s[1] = '\0';
8500 cmdputs(s);
8501 cmdputs(p);
8502 if (n->type == NTOFD || n->type == NFROMFD) {
8503 s[0] = n->ndup.dupfd + '0';
8504 p = s;
8505 goto dotail2;
8506 }
8507 n = n->nfile.fname;
8508 goto donode;
8509 }
8510}
8511
8512static void
8513cmdlist(union node *np, int sep)
8514{
8515 for (; np; np = np->narg.next) {
8516 if (!sep)
8517 cmdputs(spcstr);
8518 cmdtxt(np);
8519 if (sep && np->narg.next)
8520 cmdputs(spcstr);
8521 }
8522}
8523
8524static void
8525cmdputs(const char *s)
8526{
8527 const char *p, *str;
8528 char c, cc[2] = " ";
8529 char *nextc;
8530 int subtype = 0;
8531 int quoted = 0;
8532 static const char vstype[VSTYPE + 1][4] = {
8533 "", "}", "-", "+", "?", "=",
8534 "%", "%%", "#", "##"
8535 };
8536
8537 nextc = makestrspace((strlen(s) + 1) * 8, cmdnextc);
8538 p = s;
8539 while ((c = *p++) != 0) {
8540 str = 0;
8541 switch (c) {
8542 case CTLESC:
8543 c = *p++;
8544 break;
8545 case CTLVAR:
8546 subtype = *p++;
8547 if ((subtype & VSTYPE) == VSLENGTH)
8548 str = "${#";
8549 else
8550 str = "${";
8551 if (!(subtype & VSQUOTE) == !(quoted & 1))
8552 goto dostr;
8553 quoted ^= 1;
8554 c = '"';
8555 break;
8556 case CTLENDVAR:
8557 str = "\"}" + !(quoted & 1);
8558 quoted >>= 1;
8559 subtype = 0;
8560 goto dostr;
8561 case CTLBACKQ:
8562 str = "$(...)";
8563 goto dostr;
8564 case CTLBACKQ+CTLQUOTE:
8565 str = "\"$(...)\"";
8566 goto dostr;
8567#if ENABLE_ASH_MATH_SUPPORT
8568 case CTLARI:
8569 str = "$((";
8570 goto dostr;
8571 case CTLENDARI:
8572 str = "))";
8573 goto dostr;
8574#endif
8575 case CTLQUOTEMARK:
8576 quoted ^= 1;
8577 c = '"';
8578 break;
8579 case '=':
8580 if (subtype == 0)
8581 break;
8582 if ((subtype & VSTYPE) != VSNORMAL)
8583 quoted <<= 1;
8584 str = vstype[subtype & VSTYPE];
8585 if (subtype & VSNUL)
8586 c = ':';
8587 else
8588 goto checkstr;
8589 break;
8590 case '\'':
8591 case '\\':
8592 case '"':
8593 case '$':
8594 /* These can only happen inside quotes */
8595 cc[0] = c;
8596 str = cc;
8597 c = '\\';
8598 break;
8599 default:
8600 break;
8601 }
8602 USTPUTC(c, nextc);
8603 checkstr:
8604 if (!str)
8605 continue;
8606 dostr:
8607 while ((c = *str++)) {
8608 USTPUTC(c, nextc);
8609 }
8610 }
8611 if (quoted & 1) {
8612 USTPUTC('"', nextc);
8613 }
8614 *nextc = 0;
8615 cmdnextc = nextc;
8616}
8617#endif /* JOBS */
8618 8609
8619#if ENABLE_ASH_MAIL 8610#if ENABLE_ASH_MAIL
8620/* mail.c */ 8611/* mail.c */
@@ -11348,8 +11339,6 @@ redirectsafe(union node *redir, int flags)
11348 11339
11349/* trap.c */ 11340/* trap.c */
11350 11341
11351
11352
11353/* 11342/*
11354 * The trap builtin. 11343 * The trap builtin.
11355 */ 11344 */