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