1 /* $NetBSD: eval.c,v 1.155 2018/06/22 11:04:55 kre Exp $ */ 2 3 /*- 4 * Copyright (c) 1993 5 * The Regents of the University of California. All rights reserved. 6 * 7 * This code is derived from software contributed to Berkeley by 8 * Kenneth Almquist. 9 * 10 * Redistribution and use in source and binary forms, with or without 11 * modification, are permitted provided that the following conditions 12 * are met: 13 * 1. Redistributions of source code must retain the above copyright 14 * notice, this list of conditions and the following disclaimer. 15 * 2. Redistributions in binary form must reproduce the above copyright 16 * notice, this list of conditions and the following disclaimer in the 17 * documentation and/or other materials provided with the distribution. 18 * 3. Neither the name of the University nor the names of its contributors 19 * may be used to endorse or promote products derived from this software 20 * without specific prior written permission. 21 * 22 * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND 23 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 24 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 25 * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE 26 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 27 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS 28 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 29 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT 30 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY 31 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 32 * SUCH DAMAGE. 33 */ 34 35 #include <sys/cdefs.h> 36 #ifndef lint 37 #if 0 38 static char sccsid[] = "@(#)eval.c 8.9 (Berkeley) 6/8/95"; 39 #else 40 __RCSID("$NetBSD: eval.c,v 1.155 2018/06/22 11:04:55 kre Exp $"); 41 #endif 42 #endif /* not lint */ 43 44 #include <stdbool.h> 45 #include <stdlib.h> 46 #include <signal.h> 47 #include <stdio.h> 48 #include <string.h> 49 #include <errno.h> 50 #include <limits.h> 51 #include <unistd.h> 52 #include <sys/fcntl.h> 53 #include <sys/stat.h> 54 #include <sys/times.h> 55 #include <sys/param.h> 56 #include <sys/types.h> 57 #include <sys/wait.h> 58 #include <sys/sysctl.h> 59 60 /* 61 * Evaluate a command. 62 */ 63 64 #include "shell.h" 65 #include "nodes.h" 66 #include "syntax.h" 67 #include "expand.h" 68 #include "parser.h" 69 #include "jobs.h" 70 #include "eval.h" 71 #include "builtins.h" 72 #include "options.h" 73 #include "exec.h" 74 #include "redir.h" 75 #include "input.h" 76 #include "output.h" 77 #include "trap.h" 78 #include "var.h" 79 #include "memalloc.h" 80 #include "error.h" 81 #include "show.h" 82 #include "mystring.h" 83 #include "main.h" 84 #ifndef SMALL 85 #include "nodenames.h" 86 #include "myhistedit.h" 87 #endif 88 89 90 STATIC enum skipstate evalskip; /* != SKIPNONE if we are skipping commands */ 91 STATIC int skipcount; /* number of levels to skip */ 92 STATIC int loopnest; /* current loop nesting level */ 93 STATIC int funcnest; /* depth of function calls */ 94 STATIC int builtin_flags; /* evalcommand flags for builtins */ 95 /* 96 * Base function nesting level inside a dot command. Set to 0 initially 97 * and to (funcnest + 1) before every dot command to enable 98 * 1) detection of being in a file sourced by a dot command and 99 * 2) counting of function nesting in that file for the implementation 100 * of the return command. 101 * The value is reset to its previous value after the dot command. 102 */ 103 STATIC int dot_funcnest; 104 105 106 const char *commandname; 107 struct strlist *cmdenviron; 108 int exitstatus; /* exit status of last command */ 109 int back_exitstatus; /* exit status of backquoted command */ 110 111 112 STATIC void evalloop(union node *, int); 113 STATIC void evalfor(union node *, int); 114 STATIC void evalcase(union node *, int); 115 STATIC void evalsubshell(union node *, int); 116 STATIC void expredir(union node *); 117 STATIC void evalpipe(union node *); 118 STATIC void evalcommand(union node *, int, struct backcmd *); 119 STATIC void prehash(union node *); 120 121 STATIC char *find_dot_file(char *); 122 123 /* 124 * Called to reset things after an exception. 125 */ 126 127 #ifdef mkinit 128 INCLUDE "eval.h" 129 130 RESET { 131 reset_eval(); 132 } 133 134 SHELLPROC { 135 exitstatus = 0; 136 } 137 #endif 138 139 void 140 reset_eval(void) 141 { 142 evalskip = SKIPNONE; 143 dot_funcnest = 0; 144 loopnest = 0; 145 funcnest = 0; 146 } 147 148 static int 149 sh_pipe(int fds[2]) 150 { 151 int nfd; 152 153 if (pipe(fds)) 154 return -1; 155 156 if (fds[0] < 3) { 157 nfd = fcntl(fds[0], F_DUPFD, 3); 158 if (nfd != -1) { 159 close(fds[0]); 160 fds[0] = nfd; 161 } 162 } 163 164 if (fds[1] < 3) { 165 nfd = fcntl(fds[1], F_DUPFD, 3); 166 if (nfd != -1) { 167 close(fds[1]); 168 fds[1] = nfd; 169 } 170 } 171 return 0; 172 } 173 174 175 /* 176 * The eval commmand. 177 */ 178 179 int 180 evalcmd(int argc, char **argv) 181 { 182 char *p; 183 char *concat; 184 char **ap; 185 186 if (argc > 1) { 187 p = argv[1]; 188 if (argc > 2) { 189 STARTSTACKSTR(concat); 190 ap = argv + 2; 191 for (;;) { 192 while (*p) 193 STPUTC(*p++, concat); 194 if ((p = *ap++) == NULL) 195 break; 196 STPUTC(' ', concat); 197 } 198 STPUTC('\0', concat); 199 p = grabstackstr(concat); 200 } 201 evalstring(p, builtin_flags & EV_TESTED); 202 } else 203 exitstatus = 0; 204 return exitstatus; 205 } 206 207 208 /* 209 * Execute a command or commands contained in a string. 210 */ 211 212 void 213 evalstring(char *s, int flag) 214 { 215 union node *n; 216 struct stackmark smark; 217 218 setstackmark(&smark); 219 setinputstring(s, 1, line_number); 220 221 while ((n = parsecmd(0)) != NEOF) { 222 XTRACE(DBG_EVAL, ("evalstring: "), showtree(n)); 223 if (n && nflag == 0) 224 evaltree(n, flag | EV_MORE); 225 popstackmark(&smark); 226 } 227 popfile(); 228 popstackmark(&smark); 229 } 230 231 232 233 /* 234 * Evaluate a parse tree. The value is left in the global variable 235 * exitstatus. 236 */ 237 238 void 239 evaltree(union node *n, int flags) 240 { 241 bool do_etest; 242 int sflags = flags & ~EV_EXIT; 243 244 do_etest = false; 245 if (n == NULL || nflag) { 246 VTRACE(DBG_EVAL, ("evaltree(%s) called\n", 247 n == NULL ? "NULL" : "-n")); 248 if (nflag == 0) 249 exitstatus = 0; 250 goto out; 251 } 252 #ifndef SMALL 253 displayhist = 1; /* show history substitutions done with fc */ 254 #endif 255 CTRACE(DBG_EVAL, ("pid %d, evaltree(%p: %s(%d), %#x) called\n", 256 getpid(), n, NODETYPENAME(n->type), n->type, flags)); 257 switch (n->type) { 258 case NSEMI: 259 evaltree(n->nbinary.ch1, (sflags & EV_TESTED) | 260 (n->nbinary.ch2 ? EV_MORE : 0)); 261 if (nflag || evalskip) 262 goto out; 263 evaltree(n->nbinary.ch2, flags); 264 break; 265 case NAND: 266 evaltree(n->nbinary.ch1, EV_TESTED | EV_MORE); 267 if (nflag || evalskip || exitstatus != 0) 268 goto out; 269 evaltree(n->nbinary.ch2, flags); 270 break; 271 case NOR: 272 evaltree(n->nbinary.ch1, EV_TESTED | EV_MORE); 273 if (nflag || evalskip || exitstatus == 0) 274 goto out; 275 evaltree(n->nbinary.ch2, flags); 276 break; 277 case NREDIR: 278 expredir(n->nredir.redirect); 279 if (xflag && n->nredir.redirect) { 280 union node *rn; 281 282 outxstr(expandstr(ps4val(), line_number)); 283 outxstr("using redirections:"); 284 for (rn = n->nredir.redirect; rn; rn = rn->nfile.next) 285 (void) outredir(outx, rn, ' '); 286 outxstr(" do\n"); 287 flushout(outx); 288 } 289 redirect(n->nredir.redirect, REDIR_PUSH | REDIR_KEEP); 290 evaltree(n->nredir.n, flags); 291 popredir(); 292 if (xflag && n->nredir.redirect) { 293 outxstr(expandstr(ps4val(), line_number)); 294 outxstr("done\n"); 295 flushout(outx); 296 } 297 break; 298 case NSUBSHELL: 299 evalsubshell(n, flags & ~EV_MORE); 300 do_etest = !(flags & EV_TESTED); 301 break; 302 case NBACKGND: 303 evalsubshell(n, flags & ~EV_MORE); 304 break; 305 case NIF: { 306 evaltree(n->nif.test, EV_TESTED | EV_MORE); 307 if (nflag || evalskip) 308 goto out; 309 if (exitstatus == 0) 310 evaltree(n->nif.ifpart, flags); 311 else if (n->nif.elsepart) 312 evaltree(n->nif.elsepart, flags); 313 else 314 exitstatus = 0; 315 break; 316 } 317 case NWHILE: 318 case NUNTIL: 319 evalloop(n, sflags); 320 break; 321 case NFOR: 322 evalfor(n, sflags); 323 break; 324 case NCASE: 325 evalcase(n, sflags); 326 break; 327 case NDEFUN: 328 CTRACE(DBG_EVAL, ("Defining fn %s @%d%s\n", n->narg.text, 329 n->narg.lineno, fnline1 ? " LINENO=1" : "")); 330 defun(n->narg.text, n->narg.next, n->narg.lineno); 331 exitstatus = 0; 332 break; 333 case NNOT: 334 evaltree(n->nnot.com, (sflags & EV_MORE) | EV_TESTED); 335 exitstatus = !exitstatus; 336 break; 337 case NDNOT: 338 evaltree(n->nnot.com, (sflags & EV_MORE) | EV_TESTED); 339 if (exitstatus != 0) 340 exitstatus = 1; 341 break; 342 case NPIPE: 343 evalpipe(n); 344 do_etest = !(flags & EV_TESTED); 345 break; 346 case NCMD: 347 evalcommand(n, flags, NULL); 348 do_etest = !(flags & EV_TESTED); 349 break; 350 default: 351 #ifdef NODETYPENAME 352 out1fmt("Node type = %d(%s)\n", n->type, NODETYPENAME(n->type)); 353 #else 354 out1fmt("Node type = %d\n", n->type); 355 #endif 356 flushout(&output); 357 break; 358 } 359 out: 360 if (pendingsigs) 361 dotrap(); 362 if ((flags & EV_EXIT) != 0 || (eflag && exitstatus != 0 && do_etest)) 363 exitshell(exitstatus); 364 } 365 366 367 STATIC void 368 evalloop(union node *n, int flags) 369 { 370 int status; 371 372 loopnest++; 373 status = 0; 374 375 CTRACE(DBG_EVAL, ("evalloop %s:", NODETYPENAME(n->type))); 376 VXTRACE(DBG_EVAL, (" "), showtree(n->nbinary.ch1)); 377 VXTRACE(DBG_EVAL, ("evalloop do: "), showtree(n->nbinary.ch2)); 378 VTRACE(DBG_EVAL, ("evalloop done\n")); 379 CTRACE(DBG_EVAL, ("\n")); 380 381 for (;;) { 382 evaltree(n->nbinary.ch1, EV_TESTED | EV_MORE); 383 if (nflag) 384 break; 385 if (evalskip) { 386 skipping: if (evalskip == SKIPCONT && --skipcount <= 0) { 387 evalskip = SKIPNONE; 388 continue; 389 } 390 if (evalskip == SKIPBREAK && --skipcount <= 0) 391 evalskip = SKIPNONE; 392 break; 393 } 394 if (n->type == NWHILE) { 395 if (exitstatus != 0) 396 break; 397 } else { 398 if (exitstatus == 0) 399 break; 400 } 401 evaltree(n->nbinary.ch2, (flags & EV_TESTED) | EV_MORE); 402 status = exitstatus; 403 if (evalskip) 404 goto skipping; 405 } 406 loopnest--; 407 exitstatus = status; 408 } 409 410 411 412 STATIC void 413 evalfor(union node *n, int flags) 414 { 415 struct arglist arglist; 416 union node *argp; 417 struct strlist *sp; 418 struct stackmark smark; 419 int status; 420 421 status = nflag ? exitstatus : 0; 422 423 setstackmark(&smark); 424 arglist.lastp = &arglist.list; 425 for (argp = n->nfor.args ; argp ; argp = argp->narg.next) { 426 expandarg(argp, &arglist, EXP_FULL | EXP_TILDE); 427 if (evalskip) 428 goto out; 429 } 430 *arglist.lastp = NULL; 431 432 loopnest++; 433 for (sp = arglist.list ; sp ; sp = sp->next) { 434 int f = flags & (EV_TESTED | EV_MORE); 435 436 if (sp->next) 437 f |= EV_MORE; 438 439 if (xflag) { 440 outxstr(expandstr(ps4val(), line_number)); 441 outxstr("for "); 442 outxstr(n->nfor.var); 443 outxc('='); 444 outxshstr(sp->text); 445 outxc('\n'); 446 flushout(outx); 447 } 448 449 setvar(n->nfor.var, sp->text, 0); 450 evaltree(n->nfor.body, f); 451 status = exitstatus; 452 if (nflag) 453 break; 454 if (evalskip) { 455 if (evalskip == SKIPCONT && --skipcount <= 0) { 456 evalskip = SKIPNONE; 457 continue; 458 } 459 if (evalskip == SKIPBREAK && --skipcount <= 0) 460 evalskip = SKIPNONE; 461 break; 462 } 463 } 464 loopnest--; 465 exitstatus = status; 466 out: 467 popstackmark(&smark); 468 } 469 470 471 472 STATIC void 473 evalcase(union node *n, int flags) 474 { 475 union node *cp, *ncp; 476 union node *patp; 477 struct arglist arglist; 478 struct stackmark smark; 479 int status = 0; 480 481 setstackmark(&smark); 482 arglist.lastp = &arglist.list; 483 line_number = n->ncase.lineno; 484 expandarg(n->ncase.expr, &arglist, EXP_TILDE); 485 for (cp = n->ncase.cases; cp && evalskip == 0; cp = cp->nclist.next) { 486 for (patp = cp->nclist.pattern; patp; patp = patp->narg.next) { 487 line_number = patp->narg.lineno; 488 if (casematch(patp, arglist.list->text)) { 489 while (cp != NULL && evalskip == 0 && 490 nflag == 0) { 491 if (cp->type == NCLISTCONT) 492 ncp = cp->nclist.next; 493 else 494 ncp = NULL; 495 line_number = cp->nclist.lineno; 496 evaltree(cp->nclist.body, 497 ncp ? (flags | EV_MORE) : flags); 498 status = exitstatus; 499 cp = ncp; 500 } 501 goto out; 502 } 503 } 504 } 505 out: 506 exitstatus = status; 507 popstackmark(&smark); 508 } 509 510 511 512 /* 513 * Kick off a subshell to evaluate a tree. 514 */ 515 516 STATIC void 517 evalsubshell(union node *n, int flags) 518 { 519 struct job *jp; 520 int backgnd = (n->type == NBACKGND); 521 522 expredir(n->nredir.redirect); 523 if (xflag && n->nredir.redirect) { 524 union node *rn; 525 526 outxstr(expandstr(ps4val(), line_number)); 527 outxstr("using redirections:"); 528 for (rn = n->nredir.redirect; rn; rn = rn->nfile.next) 529 (void) outredir(outx, rn, ' '); 530 outxstr(" do subshell\n"); 531 flushout(outx); 532 } 533 INTOFF; 534 jp = makejob(n, 1); 535 if (forkshell(jp, n, backgnd ? FORK_BG : FORK_FG) == 0) { 536 INTON; 537 if (backgnd) 538 flags &=~ EV_TESTED; 539 redirect(n->nredir.redirect, REDIR_KEEP); 540 /* never returns */ 541 evaltree(n->nredir.n, flags | EV_EXIT); 542 } 543 exitstatus = backgnd ? 0 : waitforjob(jp); 544 INTON; 545 if (!backgnd && xflag && n->nredir.redirect) { 546 outxstr(expandstr(ps4val(), line_number)); 547 outxstr("done subshell\n"); 548 flushout(outx); 549 } 550 } 551 552 553 554 /* 555 * Compute the names of the files in a redirection list. 556 */ 557 558 STATIC void 559 expredir(union node *n) 560 { 561 union node *redir; 562 563 for (redir = n ; redir ; redir = redir->nfile.next) { 564 struct arglist fn; 565 566 fn.lastp = &fn.list; 567 switch (redir->type) { 568 case NFROMTO: 569 case NFROM: 570 case NTO: 571 case NCLOBBER: 572 case NAPPEND: 573 expandarg(redir->nfile.fname, &fn, EXP_TILDE | EXP_REDIR); 574 redir->nfile.expfname = fn.list->text; 575 break; 576 case NFROMFD: 577 case NTOFD: 578 if (redir->ndup.vname) { 579 expandarg(redir->ndup.vname, &fn, EXP_TILDE | EXP_REDIR); 580 fixredir(redir, fn.list->text, 1); 581 } 582 break; 583 } 584 } 585 } 586 587 588 589 /* 590 * Evaluate a pipeline. All the processes in the pipeline are children 591 * of the process creating the pipeline. (This differs from some versions 592 * of the shell, which make the last process in a pipeline the parent 593 * of all the rest.) 594 */ 595 596 STATIC void 597 evalpipe(union node *n) 598 { 599 struct job *jp; 600 struct nodelist *lp; 601 int pipelen; 602 int prevfd; 603 int pip[2]; 604 605 CTRACE(DBG_EVAL, ("evalpipe(%p) called\n", n)); 606 pipelen = 0; 607 for (lp = n->npipe.cmdlist ; lp ; lp = lp->next) 608 pipelen++; 609 INTOFF; 610 jp = makejob(n, pipelen); 611 prevfd = -1; 612 for (lp = n->npipe.cmdlist ; lp ; lp = lp->next) { 613 prehash(lp->n); 614 pip[1] = -1; 615 if (lp->next) { 616 if (sh_pipe(pip) < 0) { 617 if (prevfd >= 0) 618 close(prevfd); 619 error("Pipe call failed"); 620 } 621 } 622 if (forkshell(jp, lp->n, n->npipe.backgnd ? FORK_BG : FORK_FG) == 0) { 623 INTON; 624 if (prevfd > 0) 625 movefd(prevfd, 0); 626 if (pip[1] >= 0) { 627 close(pip[0]); 628 movefd(pip[1], 1); 629 } 630 evaltree(lp->n, EV_EXIT); 631 } 632 if (prevfd >= 0) 633 close(prevfd); 634 prevfd = pip[0]; 635 close(pip[1]); 636 } 637 if (n->npipe.backgnd == 0) { 638 exitstatus = waitforjob(jp); 639 CTRACE(DBG_EVAL, ("evalpipe: job done exit status %d\n", 640 exitstatus)); 641 } else 642 exitstatus = 0; 643 INTON; 644 } 645 646 647 648 /* 649 * Execute a command inside back quotes. If it's a builtin command, we 650 * want to save its output in a block obtained from malloc. Otherwise 651 * we fork off a subprocess and get the output of the command via a pipe. 652 * Should be called with interrupts off. 653 */ 654 655 void 656 evalbackcmd(union node *n, struct backcmd *result) 657 { 658 int pip[2]; 659 struct job *jp; 660 struct stackmark smark; /* unnecessary */ 661 662 setstackmark(&smark); 663 result->fd = -1; 664 result->buf = NULL; 665 result->nleft = 0; 666 result->jp = NULL; 667 if (nflag || n == NULL) { 668 goto out; 669 } 670 #ifdef notyet 671 /* 672 * For now we disable executing builtins in the same 673 * context as the shell, because we are not keeping 674 * enough state to recover from changes that are 675 * supposed only to affect subshells. eg. echo "`cd /`" 676 */ 677 if (n->type == NCMD) { 678 exitstatus = oexitstatus; 679 evalcommand(n, EV_BACKCMD, result); 680 } else 681 #endif 682 { 683 INTOFF; 684 if (sh_pipe(pip) < 0) 685 error("Pipe call failed"); 686 jp = makejob(n, 1); 687 if (forkshell(jp, n, FORK_NOJOB) == 0) { 688 FORCEINTON; 689 close(pip[0]); 690 movefd(pip[1], 1); 691 eflag = 0; 692 evaltree(n, EV_EXIT); 693 /* NOTREACHED */ 694 } 695 close(pip[1]); 696 result->fd = pip[0]; 697 result->jp = jp; 698 INTON; 699 } 700 out: 701 popstackmark(&smark); 702 CTRACE(DBG_EVAL, ("evalbackcmd done: fd=%d buf=0x%x nleft=%d jp=0x%x\n", 703 result->fd, result->buf, result->nleft, result->jp)); 704 } 705 706 static const char * 707 syspath(void) 708 { 709 static char *sys_path = NULL; 710 static int mib[] = {CTL_USER, USER_CS_PATH}; 711 static char def_path[] = "PATH=/usr/bin:/bin:/usr/sbin:/sbin"; 712 size_t len; 713 714 if (sys_path == NULL) { 715 if (sysctl(mib, 2, 0, &len, 0, 0) != -1 && 716 (sys_path = ckmalloc(len + 5)) != NULL && 717 sysctl(mib, 2, sys_path + 5, &len, 0, 0) != -1) { 718 memcpy(sys_path, "PATH=", 5); 719 } else { 720 ckfree(sys_path); 721 /* something to keep things happy */ 722 sys_path = def_path; 723 } 724 } 725 return sys_path; 726 } 727 728 static int 729 parse_command_args(int argc, char **argv, int *use_syspath) 730 { 731 int sv_argc = argc; 732 char *cp, c; 733 734 *use_syspath = 0; 735 736 for (;;) { 737 argv++; 738 if (--argc == 0) 739 break; 740 cp = *argv; 741 if (*cp++ != '-') 742 break; 743 if (*cp == '-' && cp[1] == 0) { 744 argv++; 745 argc--; 746 break; 747 } 748 while ((c = *cp++)) { 749 switch (c) { 750 case 'p': 751 *use_syspath = 1; 752 break; 753 default: 754 /* run 'typecmd' for other options */ 755 return 0; 756 } 757 } 758 } 759 return sv_argc - argc; 760 } 761 762 int vforked = 0; 763 extern char *trap[]; 764 765 /* 766 * Execute a simple command. 767 */ 768 769 STATIC void 770 evalcommand(union node *cmd, int flgs, struct backcmd *backcmd) 771 { 772 struct stackmark smark; 773 union node *argp; 774 struct arglist arglist; 775 struct arglist varlist; 776 volatile int flags = flgs; 777 char ** volatile argv; 778 volatile int argc; 779 char **envp; 780 int varflag; 781 struct strlist *sp; 782 volatile int mode; 783 int pip[2]; 784 struct cmdentry cmdentry; 785 struct job * volatile jp; 786 struct jmploc jmploc; 787 struct jmploc *volatile savehandler = NULL; 788 const char *volatile savecmdname; 789 volatile struct shparam saveparam; 790 struct localvar *volatile savelocalvars; 791 volatile int e; 792 char * volatile lastarg; 793 const char * volatile path = pathval(); 794 volatile int temp_path; 795 const int savefuncline = funclinebase; 796 const int savefuncabs = funclineabs; 797 798 vforked = 0; 799 /* First expand the arguments. */ 800 CTRACE(DBG_EVAL, ("evalcommand(%p, %d) called [%s]\n", cmd, flags, 801 cmd->ncmd.args ? cmd->ncmd.args->narg.text : "")); 802 setstackmark(&smark); 803 back_exitstatus = 0; 804 805 line_number = cmd->ncmd.lineno; 806 807 arglist.lastp = &arglist.list; 808 varflag = 1; 809 /* Expand arguments, ignoring the initial 'name=value' ones */ 810 for (argp = cmd->ncmd.args ; argp ; argp = argp->narg.next) { 811 char *p = argp->narg.text; 812 813 line_number = argp->narg.lineno; 814 if (varflag && is_name(*p)) { 815 do { 816 p++; 817 } while (is_in_name(*p)); 818 if (*p == '=') 819 continue; 820 } 821 expandarg(argp, &arglist, EXP_FULL | EXP_TILDE); 822 varflag = 0; 823 } 824 *arglist.lastp = NULL; 825 826 expredir(cmd->ncmd.redirect); 827 828 /* Now do the initial 'name=value' ones we skipped above */ 829 varlist.lastp = &varlist.list; 830 for (argp = cmd->ncmd.args ; argp ; argp = argp->narg.next) { 831 char *p = argp->narg.text; 832 833 line_number = argp->narg.lineno; 834 if (!is_name(*p)) 835 break; 836 do 837 p++; 838 while (is_in_name(*p)); 839 if (*p != '=') 840 break; 841 expandarg(argp, &varlist, EXP_VARTILDE); 842 } 843 *varlist.lastp = NULL; 844 845 argc = 0; 846 for (sp = arglist.list ; sp ; sp = sp->next) 847 argc++; 848 argv = stalloc(sizeof (char *) * (argc + 1)); 849 850 for (sp = arglist.list ; sp ; sp = sp->next) { 851 VTRACE(DBG_EVAL, ("evalcommand arg: %s\n", sp->text)); 852 *argv++ = sp->text; 853 } 854 *argv = NULL; 855 lastarg = NULL; 856 if (iflag && funcnest == 0 && argc > 0) 857 lastarg = argv[-1]; 858 argv -= argc; 859 860 /* Print the command if xflag is set. */ 861 if (xflag) { 862 char sep = 0; 863 union node *rn; 864 865 outxstr(expandstr(ps4val(), line_number)); 866 for (sp = varlist.list ; sp ; sp = sp->next) { 867 char *p; 868 869 if (sep != 0) 870 outxc(sep); 871 872 /* 873 * The "var=" part should not be quoted, regardless 874 * of the value, or it would not represent an 875 * assignment, but rather a command 876 */ 877 p = strchr(sp->text, '='); 878 if (p != NULL) { 879 *p = '\0'; /*XXX*/ 880 outxshstr(sp->text); 881 outxc('='); 882 *p++ = '='; /*XXX*/ 883 } else 884 p = sp->text; 885 outxshstr(p); 886 sep = ' '; 887 } 888 for (sp = arglist.list ; sp ; sp = sp->next) { 889 if (sep != 0) 890 outxc(sep); 891 outxshstr(sp->text); 892 sep = ' '; 893 } 894 for (rn = cmd->ncmd.redirect; rn; rn = rn->nfile.next) 895 if (outredir(outx, rn, sep)) 896 sep = ' '; 897 outxc('\n'); 898 flushout(outx); 899 } 900 901 /* Now locate the command. */ 902 if (argc == 0) { 903 cmdentry.cmdtype = CMDSPLBLTIN; 904 cmdentry.u.bltin = bltincmd; 905 } else { 906 static const char PATH[] = "PATH="; 907 int cmd_flags = DO_ERR; 908 909 /* 910 * Modify the command lookup path, if a PATH= assignment 911 * is present 912 */ 913 for (sp = varlist.list; sp; sp = sp->next) 914 if (strncmp(sp->text, PATH, sizeof(PATH) - 1) == 0) 915 path = sp->text + sizeof(PATH) - 1; 916 917 do { 918 int argsused, use_syspath; 919 920 find_command(argv[0], &cmdentry, cmd_flags, path); 921 if (cmdentry.cmdtype == CMDUNKNOWN) { 922 exitstatus = 127; 923 flushout(&errout); 924 goto out; 925 } 926 927 /* implement the 'command' builtin here */ 928 if (cmdentry.cmdtype != CMDBUILTIN || 929 cmdentry.u.bltin != bltincmd) 930 break; 931 cmd_flags |= DO_NOFUNC; 932 argsused = parse_command_args(argc, argv, &use_syspath); 933 if (argsused == 0) { 934 /* use 'type' builtin to display info */ 935 cmdentry.u.bltin = typecmd; 936 break; 937 } 938 argc -= argsused; 939 argv += argsused; 940 if (use_syspath) 941 path = syspath() + 5; 942 } while (argc != 0); 943 if (cmdentry.cmdtype == CMDSPLBLTIN && cmd_flags & DO_NOFUNC) 944 /* posix mandates that 'command <splbltin>' act as if 945 <splbltin> was a normal builtin */ 946 cmdentry.cmdtype = CMDBUILTIN; 947 } 948 949 /* Fork off a child process if necessary. */ 950 if (cmd->ncmd.backgnd || (trap[0] && (flags & EV_EXIT) != 0) 951 || (cmdentry.cmdtype == CMDNORMAL && (flags & EV_EXIT) == 0) 952 || ((flags & EV_BACKCMD) != 0 953 && ((cmdentry.cmdtype != CMDBUILTIN && cmdentry.cmdtype != CMDSPLBLTIN) 954 || cmdentry.u.bltin == dotcmd 955 || cmdentry.u.bltin == evalcmd))) { 956 INTOFF; 957 jp = makejob(cmd, 1); 958 mode = cmd->ncmd.backgnd; 959 if (mode) 960 flags &= ~EV_MORE; 961 if (flags & EV_BACKCMD) { 962 mode = FORK_NOJOB; 963 if (sh_pipe(pip) < 0) 964 error("Pipe call failed"); 965 } 966 #ifdef DO_SHAREDVFORK 967 /* It is essential that if DO_SHAREDVFORK is defined that the 968 * child's address space is actually shared with the parent as 969 * we rely on this. 970 */ 971 if (usefork == 0 && cmdentry.cmdtype == CMDNORMAL) { 972 pid_t pid; 973 int serrno; 974 975 savelocalvars = localvars; 976 localvars = NULL; 977 vforked = 1; 978 VFORK_BLOCK 979 switch (pid = vfork()) { 980 case -1: 981 serrno = errno; 982 VTRACE(DBG_EVAL, ("vfork() failed, errno=%d\n", 983 serrno)); 984 INTON; 985 error("Cannot vfork (%s)", strerror(serrno)); 986 break; 987 case 0: 988 /* Make sure that exceptions only unwind to 989 * after the vfork(2) 990 */ 991 SHELL_FORKED(); 992 if (setjmp(jmploc.loc)) { 993 if (exception == EXSHELLPROC) { 994 /* 995 * We can't progress with the 996 * vfork, so, set vforked = 2 997 * so the parent knows, 998 * and _exit(); 999 */ 1000 vforked = 2; 1001 _exit(0); 1002 } else { 1003 _exit(exerrno); 1004 } 1005 } 1006 savehandler = handler; 1007 handler = &jmploc; 1008 listmklocal(varlist.list, VEXPORT | VNOFUNC); 1009 forkchild(jp, cmd, mode, vforked); 1010 break; 1011 default: 1012 VFORK_UNDO(); 1013 /* restore from vfork(2) */ 1014 handler = savehandler; 1015 poplocalvars(); 1016 localvars = savelocalvars; 1017 if (vforked == 2) { 1018 vforked = 0; 1019 1020 (void)waitpid(pid, NULL, 0); 1021 /* 1022 * We need to progress in a 1023 * normal fork fashion 1024 */ 1025 goto normal_fork; 1026 } 1027 /* 1028 * Here the child has left home, 1029 * getting on with its life, so 1030 * so must we... 1031 */ 1032 vforked = 0; 1033 forkparent(jp, cmd, mode, pid); 1034 goto parent; 1035 } 1036 VFORK_END 1037 } else { 1038 normal_fork: 1039 #endif 1040 if (forkshell(jp, cmd, mode) != 0) 1041 goto parent; /* at end of routine */ 1042 FORCEINTON; 1043 #ifdef DO_SHAREDVFORK 1044 } 1045 #endif 1046 if (flags & EV_BACKCMD) { 1047 if (!vforked) { 1048 FORCEINTON; 1049 } 1050 close(pip[0]); 1051 movefd(pip[1], 1); 1052 } 1053 flags |= EV_EXIT; 1054 } 1055 1056 /* This is the child process if a fork occurred. */ 1057 /* Execute the command. */ 1058 switch (cmdentry.cmdtype) { 1059 case CMDFUNCTION: 1060 VXTRACE(DBG_EVAL, ("Shell function%s: ",vforked?" VF":""), 1061 trargs(argv)); 1062 redirect(cmd->ncmd.redirect, flags & EV_MORE ? REDIR_PUSH : 0); 1063 saveparam = shellparam; 1064 shellparam.malloc = 0; 1065 shellparam.reset = 1; 1066 shellparam.nparam = argc - 1; 1067 shellparam.p = argv + 1; 1068 shellparam.optnext = NULL; 1069 INTOFF; 1070 savelocalvars = localvars; 1071 localvars = NULL; 1072 reffunc(cmdentry.u.func); 1073 INTON; 1074 if (setjmp(jmploc.loc)) { 1075 if (exception == EXSHELLPROC) { 1076 freeparam((volatile struct shparam *) 1077 &saveparam); 1078 } else { 1079 freeparam(&shellparam); 1080 shellparam = saveparam; 1081 } 1082 unreffunc(cmdentry.u.func); 1083 poplocalvars(); 1084 localvars = savelocalvars; 1085 funclinebase = savefuncline; 1086 funclineabs = savefuncabs; 1087 handler = savehandler; 1088 longjmp(handler->loc, 1); 1089 } 1090 savehandler = handler; 1091 handler = &jmploc; 1092 if (cmdentry.u.func) { 1093 if (cmdentry.lno_frel) 1094 funclinebase = cmdentry.lineno - 1; 1095 else 1096 funclinebase = 0; 1097 funclineabs = cmdentry.lineno; 1098 1099 VTRACE(DBG_EVAL, 1100 ("function: node: %d '%s' # %d%s; funclinebase=%d\n", 1101 getfuncnode(cmdentry.u.func)->type, 1102 NODETYPENAME(getfuncnode(cmdentry.u.func)->type), 1103 cmdentry.lineno, cmdentry.lno_frel?" (=1)":"", 1104 funclinebase)); 1105 } 1106 listmklocal(varlist.list, VEXPORT); 1107 /* stop shell blowing its stack */ 1108 if (++funcnest > 1000) 1109 error("too many nested function calls"); 1110 evaltree(getfuncnode(cmdentry.u.func), flags & EV_TESTED); 1111 funcnest--; 1112 INTOFF; 1113 unreffunc(cmdentry.u.func); 1114 poplocalvars(); 1115 localvars = savelocalvars; 1116 funclinebase = savefuncline; 1117 funclineabs = savefuncabs; 1118 freeparam(&shellparam); 1119 shellparam = saveparam; 1120 handler = savehandler; 1121 if (flags & EV_MORE) 1122 popredir(); 1123 INTON; 1124 if (evalskip == SKIPFUNC) { 1125 evalskip = SKIPNONE; 1126 skipcount = 0; 1127 } 1128 if (flags & EV_EXIT) 1129 exitshell(exitstatus); 1130 break; 1131 1132 case CMDBUILTIN: 1133 case CMDSPLBLTIN: 1134 VXTRACE(DBG_EVAL, ("builtin command%s: ",vforked?" VF":""), trargs(argv)); 1135 mode = (cmdentry.u.bltin == execcmd) ? 0 : REDIR_PUSH; 1136 if (flags == EV_BACKCMD) { 1137 memout.nleft = 0; 1138 memout.nextc = memout.buf; 1139 memout.bufsize = 64; 1140 mode |= REDIR_BACKQ; 1141 } 1142 e = -1; 1143 savehandler = handler; 1144 savecmdname = commandname; 1145 handler = &jmploc; 1146 temp_path = 0; 1147 if (!setjmp(jmploc.loc)) { 1148 /* 1149 * We need to ensure the command hash table isn't 1150 * corrupted by temporary PATH assignments. 1151 * However we must ensure the 'local' command works! 1152 */ 1153 if (path != pathval() && (cmdentry.u.bltin == hashcmd || 1154 cmdentry.u.bltin == typecmd)) { 1155 savelocalvars = localvars; 1156 localvars = 0; 1157 temp_path = 1; 1158 mklocal(path - 5 /* PATH= */, 0); 1159 } 1160 redirect(cmd->ncmd.redirect, mode); 1161 1162 /* exec is a special builtin, but needs this list... */ 1163 cmdenviron = varlist.list; 1164 /* we must check 'readonly' flag for all builtins */ 1165 listsetvar(varlist.list, 1166 cmdentry.cmdtype == CMDSPLBLTIN ? 0 : VNOSET); 1167 commandname = argv[0]; 1168 /* initialize nextopt */ 1169 argptr = argv + 1; 1170 optptr = NULL; 1171 /* and getopt */ 1172 optreset = 1; 1173 optind = 1; 1174 builtin_flags = flags; 1175 exitstatus = cmdentry.u.bltin(argc, argv); 1176 } else { 1177 e = exception; 1178 exitstatus = e == EXINT ? SIGINT + 128 : 1179 e == EXEXEC ? exerrno : 2; 1180 } 1181 handler = savehandler; 1182 flushall(); 1183 out1 = &output; 1184 out2 = &errout; 1185 freestdout(); 1186 if (temp_path) { 1187 poplocalvars(); 1188 localvars = savelocalvars; 1189 } 1190 cmdenviron = NULL; 1191 if (e != EXSHELLPROC) { 1192 commandname = savecmdname; 1193 if (flags & EV_EXIT) 1194 exitshell(exitstatus); 1195 } 1196 if (e != -1) { 1197 if ((e != EXERROR && e != EXEXEC) 1198 || cmdentry.cmdtype == CMDSPLBLTIN) 1199 exraise(e); 1200 FORCEINTON; 1201 } 1202 if (cmdentry.u.bltin != execcmd) 1203 popredir(); 1204 if (flags == EV_BACKCMD) { 1205 backcmd->buf = memout.buf; 1206 backcmd->nleft = memout.nextc - memout.buf; 1207 memout.buf = NULL; 1208 } 1209 break; 1210 1211 default: 1212 VXTRACE(DBG_EVAL, ("normal command%s: ", vforked?" VF":""), 1213 trargs(argv)); 1214 redirect(cmd->ncmd.redirect, 1215 (vforked ? REDIR_VFORK : 0) | REDIR_KEEP); 1216 if (!vforked) 1217 for (sp = varlist.list ; sp ; sp = sp->next) 1218 setvareq(sp->text, VEXPORT|VSTACK); 1219 envp = environment(); 1220 shellexec(argv, envp, path, cmdentry.u.index, vforked); 1221 break; 1222 } 1223 goto out; 1224 1225 parent: /* parent process gets here (if we forked) */ 1226 1227 exitstatus = 0; /* if not altered just below */ 1228 if (mode == FORK_FG) { /* argument to fork */ 1229 exitstatus = waitforjob(jp); 1230 } else if (mode == FORK_NOJOB) { 1231 backcmd->fd = pip[0]; 1232 close(pip[1]); 1233 backcmd->jp = jp; 1234 } 1235 FORCEINTON; 1236 1237 out: 1238 if (lastarg) 1239 /* implement $_ for whatever use that really is */ 1240 (void) setvarsafe("_", lastarg, VNOERROR); 1241 popstackmark(&smark); 1242 } 1243 1244 1245 /* 1246 * Search for a command. This is called before we fork so that the 1247 * location of the command will be available in the parent as well as 1248 * the child. The check for "goodname" is an overly conservative 1249 * check that the name will not be subject to expansion. 1250 */ 1251 1252 STATIC void 1253 prehash(union node *n) 1254 { 1255 struct cmdentry entry; 1256 1257 if (n && n->type == NCMD && n->ncmd.args) 1258 if (goodname(n->ncmd.args->narg.text)) 1259 find_command(n->ncmd.args->narg.text, &entry, 0, 1260 pathval()); 1261 } 1262 1263 int 1264 in_function(void) 1265 { 1266 return funcnest; 1267 } 1268 1269 enum skipstate 1270 current_skipstate(void) 1271 { 1272 return evalskip; 1273 } 1274 1275 void 1276 stop_skipping(void) 1277 { 1278 evalskip = SKIPNONE; 1279 skipcount = 0; 1280 } 1281 1282 /* 1283 * Builtin commands. Builtin commands whose functions are closely 1284 * tied to evaluation are implemented here. 1285 */ 1286 1287 /* 1288 * No command given. 1289 */ 1290 1291 int 1292 bltincmd(int argc, char **argv) 1293 { 1294 /* 1295 * Preserve exitstatus of a previous possible redirection 1296 * as POSIX mandates 1297 */ 1298 return back_exitstatus; 1299 } 1300 1301 1302 /* 1303 * Handle break and continue commands. Break, continue, and return are 1304 * all handled by setting the evalskip flag. The evaluation routines 1305 * above all check this flag, and if it is set they start skipping 1306 * commands rather than executing them. The variable skipcount is 1307 * the number of loops to break/continue, or the number of function 1308 * levels to return. (The latter is always 1.) It should probably 1309 * be an error to break out of more loops than exist, but it isn't 1310 * in the standard shell so we don't make it one here. 1311 */ 1312 1313 int 1314 breakcmd(int argc, char **argv) 1315 { 1316 int n = argc > 1 ? number(argv[1]) : 1; 1317 1318 if (n <= 0) 1319 error("invalid count: %d", n); 1320 if (n > loopnest) 1321 n = loopnest; 1322 if (n > 0) { 1323 evalskip = (**argv == 'c')? SKIPCONT : SKIPBREAK; 1324 skipcount = n; 1325 } 1326 return 0; 1327 } 1328 1329 int 1330 dotcmd(int argc, char **argv) 1331 { 1332 exitstatus = 0; 1333 1334 if (argc >= 2) { /* That's what SVR2 does */ 1335 char *fullname; 1336 /* 1337 * dot_funcnest needs to be 0 when not in a dotcmd, so it 1338 * cannot be restored with (funcnest + 1). 1339 */ 1340 int dot_funcnest_old; 1341 struct stackmark smark; 1342 1343 setstackmark(&smark); 1344 fullname = find_dot_file(argv[1]); 1345 setinputfile(fullname, 1); 1346 commandname = fullname; 1347 dot_funcnest_old = dot_funcnest; 1348 dot_funcnest = funcnest + 1; 1349 cmdloop(0); 1350 dot_funcnest = dot_funcnest_old; 1351 popfile(); 1352 popstackmark(&smark); 1353 } 1354 return exitstatus; 1355 } 1356 1357 /* 1358 * Take commands from a file. To be compatible we should do a path 1359 * search for the file, which is necessary to find sub-commands. 1360 */ 1361 1362 STATIC char * 1363 find_dot_file(char *basename) 1364 { 1365 char *fullname; 1366 const char *path = pathval(); 1367 struct stat statb; 1368 1369 /* don't try this for absolute or relative paths */ 1370 if (strchr(basename, '/')) { 1371 if (stat(basename, &statb) == 0) { 1372 if (S_ISDIR(statb.st_mode)) 1373 error("%s: is a directory", basename); 1374 if (S_ISBLK(statb.st_mode)) 1375 error("%s: is a block device", basename); 1376 return basename; 1377 } 1378 } else while ((fullname = padvance(&path, basename, 1)) != NULL) { 1379 if ((stat(fullname, &statb) == 0)) { 1380 /* weird format is to ease future code... */ 1381 if (S_ISDIR(statb.st_mode) || S_ISBLK(statb.st_mode)) 1382 ; 1383 #if notyet 1384 else if (unreadable()) { 1385 /* 1386 * testing this via st_mode is ugly to get 1387 * correct (and would ignore ACLs). 1388 * better way is just to open the file. 1389 * But doing that here would (currently) 1390 * mean opening the file twice, which 1391 * might not be safe. So, defer this 1392 * test until code is restructures so 1393 * we can return a fd. Then we also 1394 * get to fix the mem leak just below... 1395 */ 1396 } 1397 #endif 1398 else { 1399 /* 1400 * Don't bother freeing here, since 1401 * it will be freed by the caller. 1402 * XXX no it won't - a bug for later. 1403 */ 1404 return fullname; 1405 } 1406 } 1407 stunalloc(fullname); 1408 } 1409 1410 /* not found in the PATH */ 1411 error("%s: not found", basename); 1412 /* NOTREACHED */ 1413 } 1414 1415 1416 1417 /* 1418 * The return command. 1419 * 1420 * Quoth the POSIX standard: 1421 * The return utility shall cause the shell to stop executing the current 1422 * function or dot script. If the shell is not currently executing 1423 * a function or dot script, the results are unspecified. 1424 * 1425 * As for the unspecified part, there seems to be no de-facto standard: bash 1426 * ignores the return with a warning, zsh ignores the return in interactive 1427 * mode but seems to liken it to exit in a script. (checked May 2014) 1428 * 1429 * We choose to silently ignore the return. Older versions of this shell 1430 * set evalskip to SKIPFILE causing the shell to (indirectly) exit. This 1431 * had at least the problem of circumventing the check for stopped jobs, 1432 * which would occur for exit or ^D. 1433 */ 1434 1435 int 1436 returncmd(int argc, char **argv) 1437 { 1438 int ret = argc > 1 ? number(argv[1]) : exitstatus; 1439 1440 if ((dot_funcnest == 0 && funcnest) 1441 || (dot_funcnest > 0 && funcnest - (dot_funcnest - 1) > 0)) { 1442 evalskip = SKIPFUNC; 1443 skipcount = 1; 1444 } else if (dot_funcnest > 0) { 1445 evalskip = SKIPFILE; 1446 skipcount = 1; 1447 } else { 1448 /* XXX: should a warning be issued? */ 1449 ret = 0; 1450 } 1451 1452 return ret; 1453 } 1454 1455 1456 int 1457 falsecmd(int argc, char **argv) 1458 { 1459 return 1; 1460 } 1461 1462 1463 int 1464 truecmd(int argc, char **argv) 1465 { 1466 return 0; 1467 } 1468 1469 1470 int 1471 execcmd(int argc, char **argv) 1472 { 1473 if (argc > 1) { 1474 struct strlist *sp; 1475 1476 iflag = 0; /* exit on error */ 1477 mflag = 0; 1478 optschanged(); 1479 for (sp = cmdenviron; sp; sp = sp->next) 1480 setvareq(sp->text, VEXPORT|VSTACK); 1481 shellexec(argv + 1, environment(), pathval(), 0, 0); 1482 } 1483 return 0; 1484 } 1485 1486 static int 1487 conv_time(clock_t ticks, char *seconds, size_t l) 1488 { 1489 static clock_t tpm = 0; 1490 clock_t mins; 1491 int i; 1492 1493 if (!tpm) 1494 tpm = sysconf(_SC_CLK_TCK) * 60; 1495 1496 mins = ticks / tpm; 1497 snprintf(seconds, l, "%.4f", (ticks - mins * tpm) * 60.0 / tpm ); 1498 1499 if (seconds[0] == '6' && seconds[1] == '0') { 1500 /* 59.99995 got rounded up... */ 1501 mins++; 1502 strlcpy(seconds, "0.0", l); 1503 return mins; 1504 } 1505 1506 /* suppress trailing zeros */ 1507 i = strlen(seconds) - 1; 1508 for (; seconds[i] == '0' && seconds[i - 1] != '.'; i--) 1509 seconds[i] = 0; 1510 return mins; 1511 } 1512 1513 int 1514 timescmd(int argc, char **argv) 1515 { 1516 struct tms tms; 1517 int u, s, cu, cs; 1518 char us[8], ss[8], cus[8], css[8]; 1519 1520 nextopt(""); 1521 1522 times(&tms); 1523 1524 u = conv_time(tms.tms_utime, us, sizeof(us)); 1525 s = conv_time(tms.tms_stime, ss, sizeof(ss)); 1526 cu = conv_time(tms.tms_cutime, cus, sizeof(cus)); 1527 cs = conv_time(tms.tms_cstime, css, sizeof(css)); 1528 1529 outfmt(out1, "%dm%ss %dm%ss\n%dm%ss %dm%ss\n", 1530 u, us, s, ss, cu, cus, cs, css); 1531 1532 return 0; 1533 } 1534