Changeset 3449 for trunk/src/kash/eval.c
- Timestamp:
- Sep 13, 2020, 1:17:09 PM (5 years ago)
- File:
-
- 1 edited
Legend:
- Unmodified
- Added
- Removed
-
trunk/src/kash/eval.c
r3440 r3449 41 41 #endif 42 42 43 #include <assert.h> 44 #include <stddef.h> 43 45 #include <stdlib.h> 44 46 #include <stdio.h> … … 103 105 STATIC void evalcase(shinstance *, union node *, int); 104 106 STATIC void evalsubshell(shinstance *, union node *, int); 105 STATIC void expredir(shinstance *, union node *); 106 STATIC void expredircleanup(shinstance *, union node *); 107 STATIC unsigned expredir(shinstance *, union node *); 107 108 STATIC void evalpipe(shinstance *, union node *); 108 109 STATIC void evalcommand(shinstance *, union node *, int, struct backcmd *); … … 247 248 evaltree(psh, n->nbinary.ch2, flags); 248 249 break; 249 case NREDIR: 250 expredir(psh, n->nredir.redirect);250 case NREDIR: { 251 unsigned const oldfnames = expredir(psh, n->nredir.redirect); 251 252 redirect(psh, n->nredir.redirect, REDIR_PUSH); 252 253 evaltree(psh, n->nredir.n, flags); 253 254 popredir(psh); 254 expredircleanup(psh, n->nredir.redirect);255 expredircleanup(psh, oldfnames); 255 256 break; 257 } 256 258 case NSUBSHELL: 257 259 evalsubshell(psh, n, flags); … … 450 452 struct job *jp; 451 453 int backgnd = (n->type == NBACKGND); 452 453 expredir(psh, n->nredir.redirect); 454 unsigned expfnamedepth; 455 456 expfnamedepth = expredir(psh, n->nredir.redirect); 454 457 INTOFF; 455 458 jp = makejob(psh, n, 1); … … 474 477 if (! backgnd) 475 478 psh->exitstatus = waitforjob(psh, jp); 479 expredircleanup(psh, expfnamedepth); 476 480 INTON; 477 expredircleanup(psh, n->nredir.redirect);478 481 } 479 482 … … 484 487 */ 485 488 486 STATIC void489 STATIC unsigned 487 490 expredir(shinstance *psh, union node *n) 488 491 { 489 492 union node *redir; 490 491 for (redir = n ; redir ; redir = redir->nfile.next) { 493 redirexpfnames *expfnames; 494 unsigned i; 495 496 /* We typically end up here w/o redirections. */ 497 if (!n) 498 return !(expfnames = psh->expfnames) ? 0 : expfnames->depth + 1; 499 500 /* Prepare a table for the expanded names. */ 501 i = 0; 502 for (redir = n; redir ; redir = redir->nfile.next) 503 i++; 504 expfnames = stalloc(psh, offsetof(redirexpfnames, names) + sizeof(expfnames->names[0]) * i); 505 expfnames->count = i; 506 TRACE2((psh, "expredir: %p: count=%u\n", expfnames, i)); 507 508 /* Do the expansion. */ 509 for (redir = n, i = 0 ; redir ; redir = redir->nfile.next, i++) { 492 510 struct arglist fn; 493 511 fn.lastp = &fn.list; … … 499 517 case NAPPEND: 500 518 expandarg(psh, redir->nfile.fname, &fn, EXP_TILDE | EXP_REDIR); 501 redir->nfile.expfname= fn.list->text;519 expfnames->names[i] = fn.list->text; 502 520 break; 503 521 case NFROMFD: … … 507 525 fixredir(psh, redir, fn.list->text, 1); 508 526 } 527 expfnames->names[i] = NULL; 509 528 break; 510 } 511 } 529 default: 530 assert(0); 531 expfnames->names[i] = NULL; 532 break; 533 } 534 } 535 assert(i == expfnames->count); 536 537 /* Do the linking at the end, as nesting happens when we expand backtick arguments. */ 538 expfnames->prev = psh->expfnames; 539 psh->expfnames = expfnames; 540 return expfnames->depth = psh->expfnames ? psh->expfnames->depth + 1 : 1; 512 541 } 513 542 514 543 STATIC void 515 expredircleanup(shinstance *psh, union node *n) 516 { 517 for (; n ; n = n->nfile.next) { 518 struct arglist fn; 519 fn.lastp = &fn.list; 520 switch (n->type) { 521 case NFROMTO: 522 case NFROM: 523 case NTO: 524 case NCLOBBER: 525 case NAPPEND: 526 n->nfile.expfname = NULL; 527 break; 528 } 529 } 544 expredircleanup(shinstance *psh, unsigned depth) 545 { 546 redirexpfnames *expfnames = psh->expfnames; 547 assert(expfnames == NULL ? depth == 0 : expfnames->depth == depth || expfnames->depth + 1 == depth); 548 while (expfnames && expfnames->depth >= depth) 549 expfnames = psh->expfnames = expfnames->prev; 530 550 } 531 551 … … 1111 1131 struct strlist *sp; 1112 1132 const char *path = pathval(psh); 1133 unsigned expfnamedepth; 1113 1134 1114 1135 /* First expand the arguments. */ … … 1134 1155 *arglist.lastp = NULL; 1135 1156 1136 exp redir(psh, cmd->ncmd.redirect);1157 expfnamedepth = expredir(psh, cmd->ncmd.redirect); 1137 1158 1138 1159 /* Now do the initial 'name=value' ones we skipped above */ … … 1254 1275 &args, sizeof(args), evalcommand_setup_child); 1255 1276 evalcommand_parent(psh, flags, args.lastarg, &args.smark, mode, jp, 1256 1277 args.pip, backcmd); 1257 1278 #else 1258 1279 if (forkshell(psh, jp, cmd, mode) != 0) { 1259 1280 evalcommand_parent(psh, flags, args.lastarg, &args.smark, mode, jp, 1260 1281 args.pip, backcmd); 1261 expredircleanup(psh, cmd->ncmd.redirect);1282 expredircleanup(psh, expfnamedepth); 1262 1283 return; /* at end of routine */ 1263 1284 } … … 1270 1291 evalcommand_doit(psh, cmd, &args); 1271 1292 } 1272 expredircleanup(psh, cmd->ncmd.redirect);1293 expredircleanup(psh, expfnamedepth); 1273 1294 } 1274 1295
Note:
See TracChangeset
for help on using the changeset viewer.