/bin/sh/eval.c

https://bitbucket.org/freebsd/freebsd-head/ · C · 1345 lines · 1055 code · 116 blank · 174 comment · 366 complexity · 7a8d1af215c4fcca30f6e9bd5bc2e30d MD5 · raw file

  1. /*-
  2. * Copyright (c) 1993
  3. * The Regents of the University of California. All rights reserved.
  4. *
  5. * This code is derived from software contributed to Berkeley by
  6. * Kenneth Almquist.
  7. *
  8. * Redistribution and use in source and binary forms, with or without
  9. * modification, are permitted provided that the following conditions
  10. * are met:
  11. * 1. Redistributions of source code must retain the above copyright
  12. * notice, this list of conditions and the following disclaimer.
  13. * 2. Redistributions in binary form must reproduce the above copyright
  14. * notice, this list of conditions and the following disclaimer in the
  15. * documentation and/or other materials provided with the distribution.
  16. * 4. Neither the name of the University nor the names of its contributors
  17. * may be used to endorse or promote products derived from this software
  18. * without specific prior written permission.
  19. *
  20. * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
  21. * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
  22. * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
  23. * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
  24. * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
  25. * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
  26. * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
  27. * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
  28. * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
  29. * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
  30. * SUCH DAMAGE.
  31. */
  32. #ifndef lint
  33. #if 0
  34. static char sccsid[] = "@(#)eval.c 8.9 (Berkeley) 6/8/95";
  35. #endif
  36. #endif /* not lint */
  37. #include <sys/cdefs.h>
  38. __FBSDID("$FreeBSD$");
  39. #include <paths.h>
  40. #include <signal.h>
  41. #include <stdlib.h>
  42. #include <unistd.h>
  43. #include <sys/resource.h>
  44. #include <sys/wait.h> /* For WIFSIGNALED(status) */
  45. #include <errno.h>
  46. /*
  47. * Evaluate a command.
  48. */
  49. #include "shell.h"
  50. #include "nodes.h"
  51. #include "syntax.h"
  52. #include "expand.h"
  53. #include "parser.h"
  54. #include "jobs.h"
  55. #include "eval.h"
  56. #include "builtins.h"
  57. #include "options.h"
  58. #include "exec.h"
  59. #include "redir.h"
  60. #include "input.h"
  61. #include "output.h"
  62. #include "trap.h"
  63. #include "var.h"
  64. #include "memalloc.h"
  65. #include "error.h"
  66. #include "show.h"
  67. #include "mystring.h"
  68. #ifndef NO_HISTORY
  69. #include "myhistedit.h"
  70. #endif
  71. int evalskip; /* set if we are skipping commands */
  72. int skipcount; /* number of levels to skip */
  73. MKINIT int loopnest; /* current loop nesting level */
  74. int funcnest; /* depth of function calls */
  75. static int builtin_flags; /* evalcommand flags for builtins */
  76. char *commandname;
  77. struct strlist *cmdenviron;
  78. int exitstatus; /* exit status of last command */
  79. int oexitstatus; /* saved exit status */
  80. static void evalloop(union node *, int);
  81. static void evalfor(union node *, int);
  82. static union node *evalcase(union node *);
  83. static void evalsubshell(union node *, int);
  84. static void evalredir(union node *, int);
  85. static void expredir(union node *);
  86. static void evalpipe(union node *);
  87. static int is_valid_fast_cmdsubst(union node *n);
  88. static void evalcommand(union node *, int, struct backcmd *);
  89. static void prehash(union node *);
  90. /*
  91. * Called to reset things after an exception.
  92. */
  93. #ifdef mkinit
  94. INCLUDE "eval.h"
  95. RESET {
  96. evalskip = 0;
  97. loopnest = 0;
  98. funcnest = 0;
  99. }
  100. #endif
  101. /*
  102. * The eval command.
  103. */
  104. int
  105. evalcmd(int argc, char **argv)
  106. {
  107. char *p;
  108. char *concat;
  109. char **ap;
  110. if (argc > 1) {
  111. p = argv[1];
  112. if (argc > 2) {
  113. STARTSTACKSTR(concat);
  114. ap = argv + 2;
  115. for (;;) {
  116. STPUTS(p, concat);
  117. if ((p = *ap++) == NULL)
  118. break;
  119. STPUTC(' ', concat);
  120. }
  121. STPUTC('\0', concat);
  122. p = grabstackstr(concat);
  123. }
  124. evalstring(p, builtin_flags);
  125. } else
  126. exitstatus = 0;
  127. return exitstatus;
  128. }
  129. /*
  130. * Execute a command or commands contained in a string.
  131. */
  132. void
  133. evalstring(char *s, int flags)
  134. {
  135. union node *n;
  136. struct stackmark smark;
  137. int flags_exit;
  138. int any;
  139. flags_exit = flags & EV_EXIT;
  140. flags &= ~EV_EXIT;
  141. any = 0;
  142. setstackmark(&smark);
  143. setinputstring(s, 1);
  144. while ((n = parsecmd(0)) != NEOF) {
  145. if (n != NULL && !nflag) {
  146. if (flags_exit && preadateof())
  147. evaltree(n, flags | EV_EXIT);
  148. else
  149. evaltree(n, flags);
  150. any = 1;
  151. }
  152. popstackmark(&smark);
  153. }
  154. popfile();
  155. popstackmark(&smark);
  156. if (!any)
  157. exitstatus = 0;
  158. if (flags_exit)
  159. exraise(EXEXIT);
  160. }
  161. /*
  162. * Evaluate a parse tree. The value is left in the global variable
  163. * exitstatus.
  164. */
  165. void
  166. evaltree(union node *n, int flags)
  167. {
  168. int do_etest;
  169. union node *next;
  170. do_etest = 0;
  171. if (n == NULL) {
  172. TRACE(("evaltree(NULL) called\n"));
  173. exitstatus = 0;
  174. goto out;
  175. }
  176. do {
  177. next = NULL;
  178. #ifndef NO_HISTORY
  179. displayhist = 1; /* show history substitutions done with fc */
  180. #endif
  181. TRACE(("evaltree(%p: %d) called\n", (void *)n, n->type));
  182. switch (n->type) {
  183. case NSEMI:
  184. evaltree(n->nbinary.ch1, flags & ~EV_EXIT);
  185. if (evalskip)
  186. goto out;
  187. next = n->nbinary.ch2;
  188. break;
  189. case NAND:
  190. evaltree(n->nbinary.ch1, EV_TESTED);
  191. if (evalskip || exitstatus != 0) {
  192. goto out;
  193. }
  194. next = n->nbinary.ch2;
  195. break;
  196. case NOR:
  197. evaltree(n->nbinary.ch1, EV_TESTED);
  198. if (evalskip || exitstatus == 0)
  199. goto out;
  200. next = n->nbinary.ch2;
  201. break;
  202. case NREDIR:
  203. evalredir(n, flags);
  204. break;
  205. case NSUBSHELL:
  206. evalsubshell(n, flags);
  207. do_etest = !(flags & EV_TESTED);
  208. break;
  209. case NBACKGND:
  210. evalsubshell(n, flags);
  211. break;
  212. case NIF: {
  213. evaltree(n->nif.test, EV_TESTED);
  214. if (evalskip)
  215. goto out;
  216. if (exitstatus == 0)
  217. next = n->nif.ifpart;
  218. else if (n->nif.elsepart)
  219. next = n->nif.elsepart;
  220. else
  221. exitstatus = 0;
  222. break;
  223. }
  224. case NWHILE:
  225. case NUNTIL:
  226. evalloop(n, flags & ~EV_EXIT);
  227. break;
  228. case NFOR:
  229. evalfor(n, flags & ~EV_EXIT);
  230. break;
  231. case NCASE:
  232. next = evalcase(n);
  233. break;
  234. case NCLIST:
  235. next = n->nclist.body;
  236. break;
  237. case NCLISTFALLTHRU:
  238. if (n->nclist.body) {
  239. evaltree(n->nclist.body, flags & ~EV_EXIT);
  240. if (evalskip)
  241. goto out;
  242. }
  243. next = n->nclist.next;
  244. break;
  245. case NDEFUN:
  246. defun(n->narg.text, n->narg.next);
  247. exitstatus = 0;
  248. break;
  249. case NNOT:
  250. evaltree(n->nnot.com, EV_TESTED);
  251. exitstatus = !exitstatus;
  252. break;
  253. case NPIPE:
  254. evalpipe(n);
  255. do_etest = !(flags & EV_TESTED);
  256. break;
  257. case NCMD:
  258. evalcommand(n, flags, (struct backcmd *)NULL);
  259. do_etest = !(flags & EV_TESTED);
  260. break;
  261. default:
  262. out1fmt("Node type = %d\n", n->type);
  263. flushout(&output);
  264. break;
  265. }
  266. n = next;
  267. } while (n != NULL);
  268. out:
  269. if (pendingsigs)
  270. dotrap();
  271. if (eflag && exitstatus != 0 && do_etest)
  272. exitshell(exitstatus);
  273. if (flags & EV_EXIT)
  274. exraise(EXEXIT);
  275. }
  276. static void
  277. evalloop(union node *n, int flags)
  278. {
  279. int status;
  280. loopnest++;
  281. status = 0;
  282. for (;;) {
  283. evaltree(n->nbinary.ch1, EV_TESTED);
  284. if (evalskip) {
  285. skipping: if (evalskip == SKIPCONT && --skipcount <= 0) {
  286. evalskip = 0;
  287. continue;
  288. }
  289. if (evalskip == SKIPBREAK && --skipcount <= 0)
  290. evalskip = 0;
  291. if (evalskip == SKIPFUNC || evalskip == SKIPFILE)
  292. status = exitstatus;
  293. break;
  294. }
  295. if (n->type == NWHILE) {
  296. if (exitstatus != 0)
  297. break;
  298. } else {
  299. if (exitstatus == 0)
  300. break;
  301. }
  302. evaltree(n->nbinary.ch2, flags);
  303. status = exitstatus;
  304. if (evalskip)
  305. goto skipping;
  306. }
  307. loopnest--;
  308. exitstatus = status;
  309. }
  310. static void
  311. evalfor(union node *n, int flags)
  312. {
  313. struct arglist arglist;
  314. union node *argp;
  315. struct strlist *sp;
  316. struct stackmark smark;
  317. int status;
  318. setstackmark(&smark);
  319. arglist.lastp = &arglist.list;
  320. for (argp = n->nfor.args ; argp ; argp = argp->narg.next) {
  321. oexitstatus = exitstatus;
  322. expandarg(argp, &arglist, EXP_FULL | EXP_TILDE);
  323. }
  324. *arglist.lastp = NULL;
  325. loopnest++;
  326. status = 0;
  327. for (sp = arglist.list ; sp ; sp = sp->next) {
  328. setvar(n->nfor.var, sp->text, 0);
  329. evaltree(n->nfor.body, flags);
  330. status = exitstatus;
  331. if (evalskip) {
  332. if (evalskip == SKIPCONT && --skipcount <= 0) {
  333. evalskip = 0;
  334. continue;
  335. }
  336. if (evalskip == SKIPBREAK && --skipcount <= 0)
  337. evalskip = 0;
  338. break;
  339. }
  340. }
  341. loopnest--;
  342. popstackmark(&smark);
  343. exitstatus = status;
  344. }
  345. /*
  346. * Evaluate a case statement, returning the selected tree.
  347. *
  348. * The exit status needs care to get right.
  349. */
  350. static union node *
  351. evalcase(union node *n)
  352. {
  353. union node *cp;
  354. union node *patp;
  355. struct arglist arglist;
  356. struct stackmark smark;
  357. setstackmark(&smark);
  358. arglist.lastp = &arglist.list;
  359. oexitstatus = exitstatus;
  360. expandarg(n->ncase.expr, &arglist, EXP_TILDE);
  361. for (cp = n->ncase.cases ; cp ; cp = cp->nclist.next) {
  362. for (patp = cp->nclist.pattern ; patp ; patp = patp->narg.next) {
  363. if (casematch(patp, arglist.list->text)) {
  364. popstackmark(&smark);
  365. while (cp->nclist.next &&
  366. cp->type == NCLISTFALLTHRU &&
  367. cp->nclist.body == NULL)
  368. cp = cp->nclist.next;
  369. if (cp->nclist.next &&
  370. cp->type == NCLISTFALLTHRU)
  371. return (cp);
  372. if (cp->nclist.body == NULL)
  373. exitstatus = 0;
  374. return (cp->nclist.body);
  375. }
  376. }
  377. }
  378. popstackmark(&smark);
  379. exitstatus = 0;
  380. return (NULL);
  381. }
  382. /*
  383. * Kick off a subshell to evaluate a tree.
  384. */
  385. static void
  386. evalsubshell(union node *n, int flags)
  387. {
  388. struct job *jp;
  389. int backgnd = (n->type == NBACKGND);
  390. oexitstatus = exitstatus;
  391. expredir(n->nredir.redirect);
  392. if ((!backgnd && flags & EV_EXIT && !have_traps()) ||
  393. forkshell(jp = makejob(n, 1), n, backgnd) == 0) {
  394. if (backgnd)
  395. flags &=~ EV_TESTED;
  396. redirect(n->nredir.redirect, 0);
  397. evaltree(n->nredir.n, flags | EV_EXIT); /* never returns */
  398. } else if (! backgnd) {
  399. INTOFF;
  400. exitstatus = waitforjob(jp, (int *)NULL);
  401. INTON;
  402. } else
  403. exitstatus = 0;
  404. }
  405. /*
  406. * Evaluate a redirected compound command.
  407. */
  408. static void
  409. evalredir(union node *n, int flags)
  410. {
  411. struct jmploc jmploc;
  412. struct jmploc *savehandler;
  413. volatile int in_redirect = 1;
  414. oexitstatus = exitstatus;
  415. expredir(n->nredir.redirect);
  416. savehandler = handler;
  417. if (setjmp(jmploc.loc)) {
  418. int e;
  419. handler = savehandler;
  420. e = exception;
  421. popredir();
  422. if (e == EXERROR || e == EXEXEC) {
  423. if (in_redirect) {
  424. exitstatus = 2;
  425. return;
  426. }
  427. }
  428. longjmp(handler->loc, 1);
  429. } else {
  430. INTOFF;
  431. handler = &jmploc;
  432. redirect(n->nredir.redirect, REDIR_PUSH);
  433. in_redirect = 0;
  434. INTON;
  435. evaltree(n->nredir.n, flags);
  436. }
  437. INTOFF;
  438. handler = savehandler;
  439. popredir();
  440. INTON;
  441. }
  442. /*
  443. * Compute the names of the files in a redirection list.
  444. */
  445. static void
  446. expredir(union node *n)
  447. {
  448. union node *redir;
  449. for (redir = n ; redir ; redir = redir->nfile.next) {
  450. struct arglist fn;
  451. fn.lastp = &fn.list;
  452. switch (redir->type) {
  453. case NFROM:
  454. case NTO:
  455. case NFROMTO:
  456. case NAPPEND:
  457. case NCLOBBER:
  458. expandarg(redir->nfile.fname, &fn, EXP_TILDE | EXP_REDIR);
  459. redir->nfile.expfname = fn.list->text;
  460. break;
  461. case NFROMFD:
  462. case NTOFD:
  463. if (redir->ndup.vname) {
  464. expandarg(redir->ndup.vname, &fn, EXP_TILDE | EXP_REDIR);
  465. fixredir(redir, fn.list->text, 1);
  466. }
  467. break;
  468. }
  469. }
  470. }
  471. /*
  472. * Evaluate a pipeline. All the processes in the pipeline are children
  473. * of the process creating the pipeline. (This differs from some versions
  474. * of the shell, which make the last process in a pipeline the parent
  475. * of all the rest.)
  476. */
  477. static void
  478. evalpipe(union node *n)
  479. {
  480. struct job *jp;
  481. struct nodelist *lp;
  482. int pipelen;
  483. int prevfd;
  484. int pip[2];
  485. TRACE(("evalpipe(%p) called\n", (void *)n));
  486. pipelen = 0;
  487. for (lp = n->npipe.cmdlist ; lp ; lp = lp->next)
  488. pipelen++;
  489. INTOFF;
  490. jp = makejob(n, pipelen);
  491. prevfd = -1;
  492. for (lp = n->npipe.cmdlist ; lp ; lp = lp->next) {
  493. prehash(lp->n);
  494. pip[1] = -1;
  495. if (lp->next) {
  496. if (pipe(pip) < 0) {
  497. close(prevfd);
  498. error("Pipe call failed: %s", strerror(errno));
  499. }
  500. }
  501. if (forkshell(jp, lp->n, n->npipe.backgnd) == 0) {
  502. INTON;
  503. if (prevfd > 0) {
  504. dup2(prevfd, 0);
  505. close(prevfd);
  506. }
  507. if (pip[1] >= 0) {
  508. if (!(prevfd >= 0 && pip[0] == 0))
  509. close(pip[0]);
  510. if (pip[1] != 1) {
  511. dup2(pip[1], 1);
  512. close(pip[1]);
  513. }
  514. }
  515. evaltree(lp->n, EV_EXIT);
  516. }
  517. if (prevfd >= 0)
  518. close(prevfd);
  519. prevfd = pip[0];
  520. if (pip[1] != -1)
  521. close(pip[1]);
  522. }
  523. INTON;
  524. if (n->npipe.backgnd == 0) {
  525. INTOFF;
  526. exitstatus = waitforjob(jp, (int *)NULL);
  527. TRACE(("evalpipe: job done exit status %d\n", exitstatus));
  528. INTON;
  529. } else
  530. exitstatus = 0;
  531. }
  532. static int
  533. is_valid_fast_cmdsubst(union node *n)
  534. {
  535. return (n->type == NCMD);
  536. }
  537. /*
  538. * Execute a command inside back quotes. If it's a builtin command, we
  539. * want to save its output in a block obtained from malloc. Otherwise
  540. * we fork off a subprocess and get the output of the command via a pipe.
  541. * Should be called with interrupts off.
  542. */
  543. void
  544. evalbackcmd(union node *n, struct backcmd *result)
  545. {
  546. int pip[2];
  547. struct job *jp;
  548. struct stackmark smark; /* unnecessary */
  549. struct jmploc jmploc;
  550. struct jmploc *savehandler;
  551. struct localvar *savelocalvars;
  552. setstackmark(&smark);
  553. result->fd = -1;
  554. result->buf = NULL;
  555. result->nleft = 0;
  556. result->jp = NULL;
  557. if (n == NULL) {
  558. exitstatus = 0;
  559. goto out;
  560. }
  561. if (is_valid_fast_cmdsubst(n)) {
  562. exitstatus = oexitstatus;
  563. savelocalvars = localvars;
  564. localvars = NULL;
  565. forcelocal++;
  566. savehandler = handler;
  567. if (setjmp(jmploc.loc)) {
  568. if (exception == EXERROR || exception == EXEXEC)
  569. exitstatus = 2;
  570. else if (exception != 0) {
  571. handler = savehandler;
  572. forcelocal--;
  573. poplocalvars();
  574. localvars = savelocalvars;
  575. longjmp(handler->loc, 1);
  576. }
  577. } else {
  578. handler = &jmploc;
  579. evalcommand(n, EV_BACKCMD, result);
  580. }
  581. handler = savehandler;
  582. forcelocal--;
  583. poplocalvars();
  584. localvars = savelocalvars;
  585. } else {
  586. exitstatus = 0;
  587. if (pipe(pip) < 0)
  588. error("Pipe call failed: %s", strerror(errno));
  589. jp = makejob(n, 1);
  590. if (forkshell(jp, n, FORK_NOJOB) == 0) {
  591. FORCEINTON;
  592. close(pip[0]);
  593. if (pip[1] != 1) {
  594. dup2(pip[1], 1);
  595. close(pip[1]);
  596. }
  597. evaltree(n, EV_EXIT);
  598. }
  599. close(pip[1]);
  600. result->fd = pip[0];
  601. result->jp = jp;
  602. }
  603. out:
  604. popstackmark(&smark);
  605. TRACE(("evalbackcmd done: fd=%d buf=%p nleft=%d jp=%p\n",
  606. result->fd, result->buf, result->nleft, result->jp));
  607. }
  608. static int
  609. mustexpandto(const char *argtext, const char *mask)
  610. {
  611. for (;;) {
  612. if (*argtext == CTLQUOTEMARK || *argtext == CTLQUOTEEND) {
  613. argtext++;
  614. continue;
  615. }
  616. if (*argtext == CTLESC)
  617. argtext++;
  618. else if (BASESYNTAX[(int)*argtext] == CCTL)
  619. return (0);
  620. if (*argtext != *mask)
  621. return (0);
  622. if (*argtext == '\0')
  623. return (1);
  624. argtext++;
  625. mask++;
  626. }
  627. }
  628. static int
  629. isdeclarationcmd(struct narg *arg)
  630. {
  631. int have_command = 0;
  632. if (arg == NULL)
  633. return (0);
  634. while (mustexpandto(arg->text, "command")) {
  635. have_command = 1;
  636. arg = &arg->next->narg;
  637. if (arg == NULL)
  638. return (0);
  639. /*
  640. * To also allow "command -p" and "command --" as part of
  641. * a declaration command, add code here.
  642. * We do not do this, as ksh does not do it either and it
  643. * is not required by POSIX.
  644. */
  645. }
  646. return (mustexpandto(arg->text, "export") ||
  647. mustexpandto(arg->text, "readonly") ||
  648. (mustexpandto(arg->text, "local") &&
  649. (have_command || !isfunc("local"))));
  650. }
  651. /*
  652. * Check if a builtin can safely be executed in the same process,
  653. * even though it should be in a subshell (command substitution).
  654. * Note that jobid, jobs, times and trap can show information not
  655. * available in a child process; this is deliberate.
  656. * The arguments should already have been expanded.
  657. */
  658. static int
  659. safe_builtin(int idx, int argc, char **argv)
  660. {
  661. if (idx == BLTINCMD || idx == COMMANDCMD || idx == ECHOCMD ||
  662. idx == FALSECMD || idx == JOBIDCMD || idx == JOBSCMD ||
  663. idx == KILLCMD || idx == PRINTFCMD || idx == PWDCMD ||
  664. idx == TESTCMD || idx == TIMESCMD || idx == TRUECMD ||
  665. idx == TYPECMD)
  666. return (1);
  667. if (idx == EXPORTCMD || idx == TRAPCMD || idx == ULIMITCMD ||
  668. idx == UMASKCMD)
  669. return (argc <= 1 || (argc == 2 && argv[1][0] == '-'));
  670. if (idx == SETCMD)
  671. return (argc <= 1 || (argc == 2 && (argv[1][0] == '-' ||
  672. argv[1][0] == '+') && argv[1][1] == 'o' &&
  673. argv[1][2] == '\0'));
  674. return (0);
  675. }
  676. /*
  677. * Execute a simple command.
  678. * Note: This may or may not return if (flags & EV_EXIT).
  679. */
  680. static void
  681. evalcommand(union node *cmd, int flags, struct backcmd *backcmd)
  682. {
  683. struct stackmark smark;
  684. union node *argp;
  685. struct arglist arglist;
  686. struct arglist varlist;
  687. char **argv;
  688. int argc;
  689. char **envp;
  690. int varflag;
  691. struct strlist *sp;
  692. int mode;
  693. int pip[2];
  694. struct cmdentry cmdentry;
  695. struct job *jp;
  696. struct jmploc jmploc;
  697. struct jmploc *savehandler;
  698. char *savecmdname;
  699. struct shparam saveparam;
  700. struct localvar *savelocalvars;
  701. struct parsefile *savetopfile;
  702. volatile int e;
  703. char *lastarg;
  704. int realstatus;
  705. int do_clearcmdentry;
  706. const char *path = pathval();
  707. /* First expand the arguments. */
  708. TRACE(("evalcommand(%p, %d) called\n", (void *)cmd, flags));
  709. setstackmark(&smark);
  710. arglist.lastp = &arglist.list;
  711. varlist.lastp = &varlist.list;
  712. varflag = 1;
  713. jp = NULL;
  714. do_clearcmdentry = 0;
  715. oexitstatus = exitstatus;
  716. exitstatus = 0;
  717. for (argp = cmd->ncmd.args ; argp ; argp = argp->narg.next) {
  718. if (varflag && isassignment(argp->narg.text)) {
  719. expandarg(argp, varflag == 1 ? &varlist : &arglist,
  720. EXP_VARTILDE);
  721. continue;
  722. } else if (varflag == 1)
  723. varflag = isdeclarationcmd(&argp->narg) ? 2 : 0;
  724. expandarg(argp, &arglist, EXP_FULL | EXP_TILDE);
  725. }
  726. *arglist.lastp = NULL;
  727. *varlist.lastp = NULL;
  728. expredir(cmd->ncmd.redirect);
  729. argc = 0;
  730. for (sp = arglist.list ; sp ; sp = sp->next)
  731. argc++;
  732. /* Add one slot at the beginning for tryexec(). */
  733. argv = stalloc(sizeof (char *) * (argc + 2));
  734. argv++;
  735. for (sp = arglist.list ; sp ; sp = sp->next) {
  736. TRACE(("evalcommand arg: %s\n", sp->text));
  737. *argv++ = sp->text;
  738. }
  739. *argv = NULL;
  740. lastarg = NULL;
  741. if (iflag && funcnest == 0 && argc > 0)
  742. lastarg = argv[-1];
  743. argv -= argc;
  744. /* Print the command if xflag is set. */
  745. if (xflag) {
  746. char sep = 0;
  747. const char *p, *ps4;
  748. ps4 = expandstr(ps4val());
  749. out2str(ps4 != NULL ? ps4 : ps4val());
  750. for (sp = varlist.list ; sp ; sp = sp->next) {
  751. if (sep != 0)
  752. out2c(' ');
  753. p = strchr(sp->text, '=');
  754. if (p != NULL) {
  755. p++;
  756. outbin(sp->text, p - sp->text, out2);
  757. out2qstr(p);
  758. } else
  759. out2qstr(sp->text);
  760. sep = ' ';
  761. }
  762. for (sp = arglist.list ; sp ; sp = sp->next) {
  763. if (sep != 0)
  764. out2c(' ');
  765. /* Disambiguate command looking like assignment. */
  766. if (sp == arglist.list &&
  767. strchr(sp->text, '=') != NULL &&
  768. strchr(sp->text, '\'') == NULL) {
  769. out2c('\'');
  770. out2str(sp->text);
  771. out2c('\'');
  772. } else
  773. out2qstr(sp->text);
  774. sep = ' ';
  775. }
  776. out2c('\n');
  777. flushout(&errout);
  778. }
  779. /* Now locate the command. */
  780. if (argc == 0) {
  781. /* Variable assignment(s) without command */
  782. cmdentry.cmdtype = CMDBUILTIN;
  783. cmdentry.u.index = BLTINCMD;
  784. cmdentry.special = 0;
  785. } else {
  786. static const char PATH[] = "PATH=";
  787. int cmd_flags = 0, bltinonly = 0;
  788. /*
  789. * Modify the command lookup path, if a PATH= assignment
  790. * is present
  791. */
  792. for (sp = varlist.list ; sp ; sp = sp->next)
  793. if (strncmp(sp->text, PATH, sizeof(PATH) - 1) == 0) {
  794. path = sp->text + sizeof(PATH) - 1;
  795. /*
  796. * On `PATH=... command`, we need to make
  797. * sure that the command isn't using the
  798. * non-updated hash table of the outer PATH
  799. * setting and we need to make sure that
  800. * the hash table isn't filled with items
  801. * from the temporary setting.
  802. *
  803. * It would be better to forbit using and
  804. * updating the table while this command
  805. * runs, by the command finding mechanism
  806. * is heavily integrated with hash handling,
  807. * so we just delete the hash before and after
  808. * the command runs. Partly deleting like
  809. * changepatch() does doesn't seem worth the
  810. * bookinging effort, since most such runs add
  811. * directories in front of the new PATH.
  812. */
  813. clearcmdentry();
  814. do_clearcmdentry = 1;
  815. }
  816. for (;;) {
  817. if (bltinonly) {
  818. cmdentry.u.index = find_builtin(*argv, &cmdentry.special);
  819. if (cmdentry.u.index < 0) {
  820. cmdentry.u.index = BLTINCMD;
  821. argv--;
  822. argc++;
  823. break;
  824. }
  825. } else
  826. find_command(argv[0], &cmdentry, cmd_flags, path);
  827. /* implement the bltin and command builtins here */
  828. if (cmdentry.cmdtype != CMDBUILTIN)
  829. break;
  830. if (cmdentry.u.index == BLTINCMD) {
  831. if (argc == 1)
  832. break;
  833. argv++;
  834. argc--;
  835. bltinonly = 1;
  836. } else if (cmdentry.u.index == COMMANDCMD) {
  837. if (argc == 1)
  838. break;
  839. if (!strcmp(argv[1], "-p")) {
  840. if (argc == 2)
  841. break;
  842. if (argv[2][0] == '-') {
  843. if (strcmp(argv[2], "--"))
  844. break;
  845. if (argc == 3)
  846. break;
  847. argv += 3;
  848. argc -= 3;
  849. } else {
  850. argv += 2;
  851. argc -= 2;
  852. }
  853. path = _PATH_STDPATH;
  854. clearcmdentry();
  855. do_clearcmdentry = 1;
  856. } else if (!strcmp(argv[1], "--")) {
  857. if (argc == 2)
  858. break;
  859. argv += 2;
  860. argc -= 2;
  861. } else if (argv[1][0] == '-')
  862. break;
  863. else {
  864. argv++;
  865. argc--;
  866. }
  867. cmd_flags |= DO_NOFUNC;
  868. bltinonly = 0;
  869. } else
  870. break;
  871. }
  872. /*
  873. * Special builtins lose their special properties when
  874. * called via 'command'.
  875. */
  876. if (cmd_flags & DO_NOFUNC)
  877. cmdentry.special = 0;
  878. }
  879. /* Fork off a child process if necessary. */
  880. if (((cmdentry.cmdtype == CMDNORMAL || cmdentry.cmdtype == CMDUNKNOWN)
  881. && ((flags & EV_EXIT) == 0 || have_traps()))
  882. || ((flags & EV_BACKCMD) != 0
  883. && (cmdentry.cmdtype != CMDBUILTIN ||
  884. !safe_builtin(cmdentry.u.index, argc, argv)))) {
  885. jp = makejob(cmd, 1);
  886. mode = FORK_FG;
  887. if (flags & EV_BACKCMD) {
  888. mode = FORK_NOJOB;
  889. if (pipe(pip) < 0)
  890. error("Pipe call failed: %s", strerror(errno));
  891. }
  892. if (cmdentry.cmdtype == CMDNORMAL &&
  893. cmd->ncmd.redirect == NULL &&
  894. varlist.list == NULL &&
  895. (mode == FORK_FG || mode == FORK_NOJOB) &&
  896. !disvforkset() && !iflag && !mflag) {
  897. vforkexecshell(jp, argv, environment(), path,
  898. cmdentry.u.index, flags & EV_BACKCMD ? pip : NULL);
  899. goto parent;
  900. }
  901. if (forkshell(jp, cmd, mode) != 0)
  902. goto parent; /* at end of routine */
  903. if (flags & EV_BACKCMD) {
  904. FORCEINTON;
  905. close(pip[0]);
  906. if (pip[1] != 1) {
  907. dup2(pip[1], 1);
  908. close(pip[1]);
  909. }
  910. flags &= ~EV_BACKCMD;
  911. }
  912. flags |= EV_EXIT;
  913. }
  914. /* This is the child process if a fork occurred. */
  915. /* Execute the command. */
  916. if (cmdentry.cmdtype == CMDFUNCTION) {
  917. #ifdef DEBUG
  918. trputs("Shell function: "); trargs(argv);
  919. #endif
  920. saveparam = shellparam;
  921. shellparam.malloc = 0;
  922. shellparam.reset = 1;
  923. shellparam.nparam = argc - 1;
  924. shellparam.p = argv + 1;
  925. shellparam.optnext = NULL;
  926. INTOFF;
  927. savelocalvars = localvars;
  928. localvars = NULL;
  929. reffunc(cmdentry.u.func);
  930. savehandler = handler;
  931. if (setjmp(jmploc.loc)) {
  932. freeparam(&shellparam);
  933. shellparam = saveparam;
  934. popredir();
  935. unreffunc(cmdentry.u.func);
  936. poplocalvars();
  937. localvars = savelocalvars;
  938. funcnest--;
  939. handler = savehandler;
  940. longjmp(handler->loc, 1);
  941. }
  942. handler = &jmploc;
  943. funcnest++;
  944. redirect(cmd->ncmd.redirect, REDIR_PUSH);
  945. INTON;
  946. for (sp = varlist.list ; sp ; sp = sp->next)
  947. mklocal(sp->text);
  948. exitstatus = oexitstatus;
  949. evaltree(getfuncnode(cmdentry.u.func),
  950. flags & (EV_TESTED | EV_EXIT));
  951. INTOFF;
  952. unreffunc(cmdentry.u.func);
  953. poplocalvars();
  954. localvars = savelocalvars;
  955. freeparam(&shellparam);
  956. shellparam = saveparam;
  957. handler = savehandler;
  958. funcnest--;
  959. popredir();
  960. INTON;
  961. if (evalskip == SKIPFUNC) {
  962. evalskip = 0;
  963. skipcount = 0;
  964. }
  965. if (jp)
  966. exitshell(exitstatus);
  967. } else if (cmdentry.cmdtype == CMDBUILTIN) {
  968. #ifdef DEBUG
  969. trputs("builtin command: "); trargs(argv);
  970. #endif
  971. mode = (cmdentry.u.index == EXECCMD)? 0 : REDIR_PUSH;
  972. if (flags == EV_BACKCMD) {
  973. memout.nleft = 0;
  974. memout.nextc = memout.buf;
  975. memout.bufsize = 64;
  976. mode |= REDIR_BACKQ;
  977. }
  978. savecmdname = commandname;
  979. savetopfile = getcurrentfile();
  980. cmdenviron = varlist.list;
  981. e = -1;
  982. savehandler = handler;
  983. if (setjmp(jmploc.loc)) {
  984. e = exception;
  985. if (e == EXINT)
  986. exitstatus = SIGINT+128;
  987. else if (e != EXEXIT)
  988. exitstatus = 2;
  989. goto cmddone;
  990. }
  991. handler = &jmploc;
  992. redirect(cmd->ncmd.redirect, mode);
  993. /*
  994. * If there is no command word, redirection errors should
  995. * not be fatal but assignment errors should.
  996. */
  997. if (argc == 0)
  998. cmdentry.special = 1;
  999. listsetvar(cmdenviron, cmdentry.special ? 0 : VNOSET);
  1000. if (argc > 0)
  1001. bltinsetlocale();
  1002. commandname = argv[0];
  1003. argptr = argv + 1;
  1004. nextopt_optptr = NULL; /* initialize nextopt */
  1005. builtin_flags = flags;
  1006. exitstatus = (*builtinfunc[cmdentry.u.index])(argc, argv);
  1007. flushall();
  1008. cmddone:
  1009. if (argc > 0)
  1010. bltinunsetlocale();
  1011. cmdenviron = NULL;
  1012. out1 = &output;
  1013. out2 = &errout;
  1014. freestdout();
  1015. handler = savehandler;
  1016. commandname = savecmdname;
  1017. if (jp)
  1018. exitshell(exitstatus);
  1019. if (flags == EV_BACKCMD) {
  1020. backcmd->buf = memout.buf;
  1021. backcmd->nleft = memout.nextc - memout.buf;
  1022. memout.buf = NULL;
  1023. }
  1024. if (cmdentry.u.index != EXECCMD)
  1025. popredir();
  1026. if (e != -1) {
  1027. if ((e != EXERROR && e != EXEXEC)
  1028. || cmdentry.special)
  1029. exraise(e);
  1030. popfilesupto(savetopfile);
  1031. if (flags != EV_BACKCMD)
  1032. FORCEINTON;
  1033. }
  1034. } else {
  1035. #ifdef DEBUG
  1036. trputs("normal command: "); trargs(argv);
  1037. #endif
  1038. redirect(cmd->ncmd.redirect, 0);
  1039. for (sp = varlist.list ; sp ; sp = sp->next)
  1040. setvareq(sp->text, VEXPORT|VSTACK);
  1041. envp = environment();
  1042. shellexec(argv, envp, path, cmdentry.u.index);
  1043. /*NOTREACHED*/
  1044. }
  1045. goto out;
  1046. parent: /* parent process gets here (if we forked) */
  1047. if (mode == FORK_FG) { /* argument to fork */
  1048. INTOFF;
  1049. exitstatus = waitforjob(jp, &realstatus);
  1050. INTON;
  1051. if (iflag && loopnest > 0 && WIFSIGNALED(realstatus)) {
  1052. evalskip = SKIPBREAK;
  1053. skipcount = loopnest;
  1054. }
  1055. } else if (mode == FORK_NOJOB) {
  1056. backcmd->fd = pip[0];
  1057. close(pip[1]);
  1058. backcmd->jp = jp;
  1059. }
  1060. out:
  1061. if (lastarg)
  1062. setvar("_", lastarg, 0);
  1063. if (do_clearcmdentry)
  1064. clearcmdentry();
  1065. popstackmark(&smark);
  1066. }
  1067. /*
  1068. * Search for a command. This is called before we fork so that the
  1069. * location of the command will be available in the parent as well as
  1070. * the child. The check for "goodname" is an overly conservative
  1071. * check that the name will not be subject to expansion.
  1072. */
  1073. static void
  1074. prehash(union node *n)
  1075. {
  1076. struct cmdentry entry;
  1077. if (n && n->type == NCMD && n->ncmd.args)
  1078. if (goodname(n->ncmd.args->narg.text))
  1079. find_command(n->ncmd.args->narg.text, &entry, 0,
  1080. pathval());
  1081. }
  1082. /*
  1083. * Builtin commands. Builtin commands whose functions are closely
  1084. * tied to evaluation are implemented here.
  1085. */
  1086. /*
  1087. * No command given, a bltin command with no arguments, or a bltin command
  1088. * with an invalid name.
  1089. */
  1090. int
  1091. bltincmd(int argc, char **argv)
  1092. {
  1093. if (argc > 1) {
  1094. out2fmt_flush("%s: not found\n", argv[1]);
  1095. return 127;
  1096. }
  1097. /*
  1098. * Preserve exitstatus of a previous possible redirection
  1099. * as POSIX mandates
  1100. */
  1101. return exitstatus;
  1102. }
  1103. /*
  1104. * Handle break and continue commands. Break, continue, and return are
  1105. * all handled by setting the evalskip flag. The evaluation routines
  1106. * above all check this flag, and if it is set they start skipping
  1107. * commands rather than executing them. The variable skipcount is
  1108. * the number of loops to break/continue, or the number of function
  1109. * levels to return. (The latter is always 1.) It should probably
  1110. * be an error to break out of more loops than exist, but it isn't
  1111. * in the standard shell so we don't make it one here.
  1112. */
  1113. int
  1114. breakcmd(int argc, char **argv)
  1115. {
  1116. int n = argc > 1 ? number(argv[1]) : 1;
  1117. if (n > loopnest)
  1118. n = loopnest;
  1119. if (n > 0) {
  1120. evalskip = (**argv == 'c')? SKIPCONT : SKIPBREAK;
  1121. skipcount = n;
  1122. }
  1123. return 0;
  1124. }
  1125. /*
  1126. * The `command' command.
  1127. */
  1128. int
  1129. commandcmd(int argc __unused, char **argv __unused)
  1130. {
  1131. const char *path;
  1132. int ch;
  1133. int cmd = -1;
  1134. path = bltinlookup("PATH", 1);
  1135. while ((ch = nextopt("pvV")) != '\0') {
  1136. switch (ch) {
  1137. case 'p':
  1138. path = _PATH_STDPATH;
  1139. break;
  1140. case 'v':
  1141. cmd = TYPECMD_SMALLV;
  1142. break;
  1143. case 'V':
  1144. cmd = TYPECMD_BIGV;
  1145. break;
  1146. }
  1147. }
  1148. if (cmd != -1) {
  1149. if (*argptr == NULL || argptr[1] != NULL)
  1150. error("wrong number of arguments");
  1151. return typecmd_impl(2, argptr - 1, cmd, path);
  1152. }
  1153. if (*argptr != NULL)
  1154. error("commandcmd bad call");
  1155. /*
  1156. * Do nothing successfully if no command was specified;
  1157. * ksh also does this.
  1158. */
  1159. return 0;
  1160. }
  1161. /*
  1162. * The return command.
  1163. */
  1164. int
  1165. returncmd(int argc, char **argv)
  1166. {
  1167. int ret = argc > 1 ? number(argv[1]) : oexitstatus;
  1168. if (funcnest) {
  1169. evalskip = SKIPFUNC;
  1170. skipcount = 1;
  1171. } else {
  1172. /* skip the rest of the file */
  1173. evalskip = SKIPFILE;
  1174. skipcount = 1;
  1175. }
  1176. return ret;
  1177. }
  1178. int
  1179. falsecmd(int argc __unused, char **argv __unused)
  1180. {
  1181. return 1;
  1182. }
  1183. int
  1184. truecmd(int argc __unused, char **argv __unused)
  1185. {
  1186. return 0;
  1187. }
  1188. int
  1189. execcmd(int argc, char **argv)
  1190. {
  1191. /*
  1192. * Because we have historically not supported any options,
  1193. * only treat "--" specially.
  1194. */
  1195. if (argc > 1 && strcmp(argv[1], "--") == 0)
  1196. argc--, argv++;
  1197. if (argc > 1) {
  1198. struct strlist *sp;
  1199. iflag = 0; /* exit on error */
  1200. mflag = 0;
  1201. optschanged();
  1202. for (sp = cmdenviron; sp ; sp = sp->next)
  1203. setvareq(sp->text, VEXPORT|VSTACK);
  1204. shellexec(argv + 1, environment(), pathval(), 0);
  1205. }
  1206. return 0;
  1207. }
  1208. int
  1209. timescmd(int argc __unused, char **argv __unused)
  1210. {
  1211. struct rusage ru;
  1212. long shumins, shsmins, chumins, chsmins;
  1213. double shusecs, shssecs, chusecs, chssecs;
  1214. if (getrusage(RUSAGE_SELF, &ru) < 0)
  1215. return 1;
  1216. shumins = ru.ru_utime.tv_sec / 60;
  1217. shusecs = ru.ru_utime.tv_sec % 60 + ru.ru_utime.tv_usec / 1000000.;
  1218. shsmins = ru.ru_stime.tv_sec / 60;
  1219. shssecs = ru.ru_stime.tv_sec % 60 + ru.ru_stime.tv_usec / 1000000.;
  1220. if (getrusage(RUSAGE_CHILDREN, &ru) < 0)
  1221. return 1;
  1222. chumins = ru.ru_utime.tv_sec / 60;
  1223. chusecs = ru.ru_utime.tv_sec % 60 + ru.ru_utime.tv_usec / 1000000.;
  1224. chsmins = ru.ru_stime.tv_sec / 60;
  1225. chssecs = ru.ru_stime.tv_sec % 60 + ru.ru_stime.tv_usec / 1000000.;
  1226. out1fmt("%ldm%.3fs %ldm%.3fs\n%ldm%.3fs %ldm%.3fs\n", shumins,
  1227. shusecs, shsmins, shssecs, chumins, chusecs, chsmins, chssecs);
  1228. return 0;
  1229. }