26763: fix problem on failed cd -s to relative path
[zsh.git] / Src / exec.c
blob4f15ebefa06de5d6ee9b10ef8f5fbac9085199a4
1 /*
2 * exec.c - command execution
4 * This file is part of zsh, the Z shell.
6 * Copyright (c) 1992-1997 Paul Falstad
7 * All rights reserved.
9 * Permission is hereby granted, without written agreement and without
10 * license or royalty fees, to use, copy, modify, and distribute this
11 * software and to distribute modified versions of this software for any
12 * purpose, provided that the above copyright notice and the following
13 * two paragraphs appear in all copies of this software.
15 * In no event shall Paul Falstad or the Zsh Development Group be liable
16 * to any party for direct, indirect, special, incidental, or consequential
17 * damages arising out of the use of this software and its documentation,
18 * even if Paul Falstad and the Zsh Development Group have been advised of
19 * the possibility of such damage.
21 * Paul Falstad and the Zsh Development Group specifically disclaim any
22 * warranties, including, but not limited to, the implied warranties of
23 * merchantability and fitness for a particular purpose. The software
24 * provided hereunder is on an "as is" basis, and Paul Falstad and the
25 * Zsh Development Group have no obligation to provide maintenance,
26 * support, updates, enhancements, or modifications.
30 #include "zsh.mdh"
31 #include "exec.pro"
33 /* Flags for last argument of addvars */
35 enum {
36 /* Export the variable for "VAR=val cmd ..." */
37 ADDVAR_EXPORT = 1 << 0,
38 /* Apply restrictions for variable */
39 ADDVAR_RESTRICT = 1 << 1,
40 /* Variable list is being restored later */
41 ADDVAR_RESTORE = 1 << 2
44 /* used to suppress ERREXIT and trapping of SIGZERR, SIGEXIT. */
46 /**/
47 int noerrexit;
50 * noerrs = 1: suppress error messages
51 * noerrs = 2: don't set errflag on parse error, either
54 /**/
55 mod_export int noerrs;
57 /* do not save history on exec and exit */
59 /**/
60 int nohistsave;
62 /* error/break flag */
64 /**/
65 mod_export int errflag;
68 * State of trap return value. Value is from enum trap_state.
71 /**/
72 int trap_state;
75 * Value associated with return from a trap.
76 * This is only active if we are inside a trap, else its value
77 * is irrelevant. It is initialised to -1 for a function trap and
78 * -2 for a non-function trap and if negative is decremented as
79 * we go deeper into functions and incremented as we come back up.
80 * The value is used to decide if an explicit "return" should cause
81 * a return from the caller of the trap; it does this by setting
82 * trap_return to a status (i.e. a non-negative value).
84 * In summary, trap_return is
85 * - zero unless we are in a trap
86 * - negative in a trap unless it has triggered. Code uses this
87 * to detect an active trap.
88 * - non-negative in a trap once it was triggered. It should remain
89 * non-negative until restored after execution of the trap.
92 /**/
93 int trap_return;
95 /* != 0 if this is a subshell */
97 /**/
98 int subsh;
100 /* != 0 if we have a return pending */
102 /**/
103 mod_export int retflag;
105 /**/
106 long lastval2;
108 /* The table of file descriptors. A table element is zero if the *
109 * corresponding fd is not used by the shell. It is greater than *
110 * 1 if the fd is used by a <(...) or >(...) substitution and 1 if *
111 * it is an internal file descriptor which must be closed before *
112 * executing an external command. The first ten elements of the *
113 * table is not used. A table element is set by movefd and cleard *
114 * by zclose. */
116 /**/
117 mod_export unsigned char *fdtable;
119 /* The allocated size of fdtable */
121 /**/
122 int fdtable_size;
124 /* The highest fd that marked with nonzero in fdtable */
126 /**/
127 mod_export int max_zsh_fd;
129 /* input fd from the coprocess */
131 /**/
132 mod_export int coprocin;
134 /* output fd from the coprocess */
136 /**/
137 mod_export int coprocout;
139 /* != 0 if the line editor is active */
141 /**/
142 mod_export int zleactive;
144 /* pid of process undergoing 'process substitution' */
146 /**/
147 pid_t cmdoutpid;
149 /* exit status of process undergoing 'process substitution' */
151 /**/
152 int cmdoutval;
154 /* The context in which a shell function is called, see SFC_* in zsh.h. */
156 /**/
157 mod_export int sfcontext;
159 /* Stack to save some variables before executing a signal handler function */
161 /**/
162 struct execstack *exstack;
164 /* Stack with names of functions currently active. */
166 /**/
167 mod_export Funcstack funcstack;
169 #define execerr() if (!forked) { lastval = 1; goto done; } else _exit(1)
171 static int doneps4;
172 static char *STTYval;
173 static char *blank_env[] = { NULL };
175 /* Execution functions. */
177 static int (*execfuncs[WC_COUNT-WC_CURSH]) _((Estate, int)) = {
178 execcursh, exectime, execfuncdef, execfor, execselect,
179 execwhile, execrepeat, execcase, execif, execcond,
180 execarith, execautofn, exectry
183 /* structure for command builtin for when it is used with -v or -V */
184 static struct builtin commandbn =
185 BUILTIN(0, 0, bin_whence, 0, -1, BIN_COMMAND, "vV", NULL);
187 /* parse string into a list */
189 /**/
190 mod_export Eprog
191 parse_string(char *s, int reset_lineno)
193 Eprog p;
194 zlong oldlineno;
196 lexsave();
197 inpush(s, INP_LINENO, NULL);
198 strinbeg(0);
199 oldlineno = lineno;
200 if (reset_lineno)
201 lineno = 1;
202 p = parse_list();
203 lineno = oldlineno;
204 if (tok == LEXERR && !lastval)
205 lastval = 1;
206 strinend();
207 inpop();
208 lexrestore();
209 return p;
212 /**/
213 #ifdef HAVE_GETRLIMIT
215 /* the resource limits for the shell and its children */
217 /**/
218 mod_export struct rlimit current_limits[RLIM_NLIMITS], limits[RLIM_NLIMITS];
220 /**/
221 mod_export int
222 zsetlimit(int limnum, char *nam)
224 if (limits[limnum].rlim_max != current_limits[limnum].rlim_max ||
225 limits[limnum].rlim_cur != current_limits[limnum].rlim_cur) {
226 if (setrlimit(limnum, limits + limnum)) {
227 if (nam)
228 zwarnnam(nam, "setrlimit failed: %e", errno);
229 return -1;
231 current_limits[limnum] = limits[limnum];
233 return 0;
236 /**/
237 mod_export int
238 setlimits(char *nam)
240 int limnum;
241 int ret = 0;
243 for (limnum = 0; limnum < RLIM_NLIMITS; limnum++)
244 if (zsetlimit(limnum, nam))
245 ret++;
246 return ret;
249 /**/
250 #endif /* HAVE_GETRLIMIT */
252 /* fork and set limits */
254 /**/
255 static pid_t
256 zfork(struct timeval *tv)
258 pid_t pid;
259 struct timezone dummy_tz;
262 * Is anybody willing to explain this test?
264 if (thisjob != -1 && thisjob >= jobtabsize - 1 && !expandjobtab()) {
265 zerr("job table full");
266 return -1;
268 if (tv)
269 gettimeofday(tv, &dummy_tz);
271 * Queueing signals is necessary on Linux because fork()
272 * manipulates mutexes, leading to deadlock in memory
273 * allocation. We don't expect fork() to be particularly
274 * zippy anyway.
276 queue_signals();
277 pid = fork();
278 unqueue_signals();
279 if (pid == -1) {
280 zerr("fork failed: %e", errno);
281 return -1;
283 #ifdef HAVE_GETRLIMIT
284 if (!pid)
285 /* set resource limits for the child process */
286 setlimits(NULL);
287 #endif
288 return pid;
292 * Allen Edeln gebiet ich Andacht,
293 * Hohen und Niedern von Heimdalls Geschlecht;
294 * Ich will list_pipe's Wirken kuenden
295 * Die aeltesten Sagen, der ich mich entsinne...
297 * In most shells, if you do something like:
299 * cat foo | while read a; do grep $a bar; done
301 * the shell forks and executes the loop in the sub-shell thus created.
302 * In zsh this traditionally executes the loop in the current shell, which
303 * is nice to have if the loop does something to change the shell, like
304 * setting parameters or calling builtins.
305 * Putting the loop in a sub-shell makes life easy, because the shell only
306 * has to put it into the job-structure and then treats it as a normal
307 * process. Suspending and interrupting is no problem then.
308 * Some years ago, zsh either couldn't suspend such things at all, or
309 * it got really messed up when users tried to do it. As a solution, we
310 * implemented the list_pipe-stuff, which has since then become a reason
311 * for many nightmares.
312 * Pipelines like the one above are executed by the functions in this file
313 * which call each other (and sometimes recursively). The one above, for
314 * example would lead to a function call stack roughly like:
316 * execlist->execpline->execcmd->execwhile->execlist->execpline
318 * (when waiting for the grep, ignoring execpline2 for now). At this time,
319 * zsh has built two job-table entries for it: one for the cat and one for
320 * the grep. If the user hits ^Z at this point (and jobbing is used), the
321 * shell is notified that the grep was suspended. The list_pipe flag is
322 * used to tell the execpline where it was waiting that it was in a pipeline
323 * with a shell construct at the end (which may also be a shell function or
324 * several other things). When zsh sees the suspended grep, it forks to let
325 * the sub-shell execute the rest of the while loop. The parent shell walks
326 * up in the function call stack to the first execpline. There it has to find
327 * out that it has just forked and then has to add information about the sub-
328 * shell (its pid and the text for it) in the job entry of the cat. The pid
329 * is passed down in the list_pipe_pid variable.
330 * But there is a problem: the suspended grep is a child of the parent shell
331 * and can't be adopted by the sub-shell. So the parent shell also has to
332 * keep the information about this process (more precisely: this pipeline)
333 * by keeping the job table entry it created for it. The fact that there
334 * are two jobs which have to be treated together is remembered by setting
335 * the STAT_SUPERJOB flag in the entry for the cat-job (which now also
336 * contains a process-entry for the whole loop -- the sub-shell) and by
337 * setting STAT_SUBJOB in the job of the grep-job. With that we can keep
338 * sub-jobs from being displayed and we can handle an fg/bg on the super-
339 * job correctly. When the super-job is continued, the shell also wakes up
340 * the sub-job. But then, the grep will exit sometime. Now the parent shell
341 * has to remember not to try to wake it up again (in case of another ^Z).
342 * It also has to wake up the sub-shell (which suspended itself immediately
343 * after creation), so that the rest of the loop is executed by it.
344 * But there is more: when the sub-shell is created, the cat may already
345 * have exited, so we can't put the sub-shell in the process group of it.
346 * In this case, we put the sub-shell in the process group of the parent
347 * shell and in any case, the sub-shell has to put all commands executed
348 * by it into its own process group, because only this way the parent
349 * shell can control them since it only knows the process group of the sub-
350 * shell. Of course, this information is also important when putting a job
351 * in the foreground, where we have to attach its process group to the
352 * controlling tty.
353 * All this is made more difficult because we have to handle return values
354 * correctly. If the grep is signaled, its exit status has to be propagated
355 * back to the parent shell which needs it to set the exit status of the
356 * super-job. And of course, when the grep is signaled (including ^C), the
357 * loop has to be stopped, etc.
358 * The code for all this is distributed over three files (exec.c, jobs.c,
359 * and signals.c) and none of them is a simple one. So, all in all, there
360 * may still be bugs, but considering the complexity (with race conditions,
361 * signal handling, and all that), this should probably be expected.
364 /**/
365 int list_pipe = 0, simple_pline = 0;
367 static pid_t list_pipe_pid;
368 static struct timeval list_pipe_start;
369 static int nowait, pline_level = 0;
370 static int list_pipe_child = 0, list_pipe_job;
371 static char list_pipe_text[JOBTEXTSIZE];
373 /* execute a current shell command */
375 /**/
376 static int
377 execcursh(Estate state, int do_exec)
379 Wordcode end = state->pc + WC_CURSH_SKIP(state->pc[-1]);
381 /* Skip word only used for try/always */
382 state->pc++;
384 if (!list_pipe && thisjob != list_pipe_job && !hasprocs(thisjob))
385 deletejob(jobtab + thisjob);
386 cmdpush(CS_CURSH);
387 execlist(state, 1, do_exec);
388 cmdpop();
390 state->pc = end;
392 return lastval;
395 /* execve after handling $_ and #! */
397 #define POUNDBANGLIMIT 64
399 /**/
400 static int
401 zexecve(char *pth, char **argv, char **newenvp)
403 int eno;
404 static char buf[PATH_MAX * 2];
405 char **eep;
407 unmetafy(pth, NULL);
408 for (eep = argv; *eep; eep++)
409 if (*eep != pth)
410 unmetafy(*eep, NULL);
411 buf[0] = '_';
412 buf[1] = '=';
413 if (*pth == '/')
414 strcpy(buf + 2, pth);
415 else
416 sprintf(buf + 2, "%s/%s", pwd, pth);
417 zputenv(buf);
418 closedumps();
420 if (newenvp == NULL)
421 newenvp = environ;
422 execve(pth, argv, newenvp);
424 /* If the execve returns (which in general shouldn't happen), *
425 * then check for an errno equal to ENOEXEC. This errno is set *
426 * if the process file has the appropriate access permission, *
427 * but has an invalid magic number in its header. */
428 if ((eno = errno) == ENOEXEC || eno == ENOENT) {
429 char execvebuf[POUNDBANGLIMIT + 1], *ptr, *ptr2, *argv0;
430 int fd, ct, t0;
432 if ((fd = open(pth, O_RDONLY|O_NOCTTY)) >= 0) {
433 argv0 = *argv;
434 *argv = pth;
435 ct = read(fd, execvebuf, POUNDBANGLIMIT);
436 close(fd);
437 if (ct > 0) {
438 if (execvebuf[0] == '#') {
439 if (execvebuf[1] == '!') {
440 for (t0 = 0; t0 != ct; t0++)
441 if (execvebuf[t0] == '\n')
442 break;
443 while (inblank(execvebuf[t0]))
444 execvebuf[t0--] = '\0';
445 execvebuf[POUNDBANGLIMIT] = '\0';
446 for (ptr = execvebuf + 2; *ptr && *ptr == ' '; ptr++);
447 for (ptr2 = ptr; *ptr && *ptr != ' '; ptr++);
448 if (eno == ENOENT) {
449 if (*ptr)
450 *ptr = '\0';
451 zerr("%s: bad interpreter: %s: %e", pth, ptr2,
452 eno);
453 } else if (*ptr) {
454 *ptr = '\0';
455 argv[-2] = ptr2;
456 argv[-1] = ptr + 1;
457 execve(ptr2, argv - 2, newenvp);
458 } else {
459 argv[-1] = ptr2;
460 execve(ptr2, argv - 1, newenvp);
462 } else if (eno == ENOEXEC) {
463 argv[-1] = "sh";
464 execve("/bin/sh", argv - 1, newenvp);
466 } else if (eno == ENOEXEC) {
467 for (t0 = 0; t0 != ct; t0++)
468 if (!execvebuf[t0])
469 break;
470 if (t0 == ct) {
471 argv[-1] = "sh";
472 execve("/bin/sh", argv - 1, newenvp);
475 } else
476 eno = errno;
477 *argv = argv0;
478 } else
479 eno = errno;
481 /* restore the original arguments and path but do not bother with *
482 * null characters as these cannot be passed to external commands *
483 * anyway. So the result is truncated at the first null char. */
484 pth = metafy(pth, -1, META_NOALLOC);
485 for (eep = argv; *eep; eep++)
486 if (*eep != pth)
487 (void) metafy(*eep, -1, META_NOALLOC);
488 return eno;
491 #define MAXCMDLEN (PATH_MAX*4)
493 /* test whether we really want to believe the error number */
495 /**/
496 static int
497 isgooderr(int e, char *dir)
500 * Maybe the directory was unreadable, or maybe it wasn't
501 * even a directory.
503 return ((e != EACCES || !access(dir, X_OK)) &&
504 e != ENOENT && e != ENOTDIR);
508 * Attempt to handle command not found.
509 * Return 0 if the condition was handled, non-zero otherwise.
512 /**/
513 static int
514 commandnotfound(char *arg0, LinkList args)
516 Shfunc shf = (Shfunc)
517 shfunctab->getnode(shfunctab, "command_not_found_handler");
519 if (!shf)
520 return 127;
522 pushnode(args, arg0);
523 return doshfunc(shf, args, 1);
526 /* execute an external command */
528 /**/
529 static void
530 execute(LinkList args, int flags, int defpath)
532 Cmdnam cn;
533 char buf[MAXCMDLEN], buf2[MAXCMDLEN];
534 char *s, *z, *arg0;
535 char **argv, **pp, **newenvp = NULL;
536 int eno = 0, ee;
538 arg0 = (char *) peekfirst(args);
539 if (isset(RESTRICTED) && (strchr(arg0, '/') || defpath)) {
540 zerr("%s: restricted", arg0);
541 _exit(1);
544 /* If the parameter STTY is set in the command's environment, *
545 * we first run the stty command with the value of this *
546 * parameter as it arguments. */
547 if ((s = STTYval) && isatty(0) && (GETPGRP() == getpid())) {
548 char *t = tricat("stty", " ", s);
550 STTYval = 0; /* this prevents infinite recursion */
551 zsfree(s);
552 execstring(t, 1, 0);
553 zsfree(t);
554 } else if (s) {
555 STTYval = 0;
556 zsfree(s);
559 /* If ARGV0 is in the commands environment, we use *
560 * that as argv[0] for this external command */
561 if (unset(RESTRICTED) && (z = zgetenv("ARGV0"))) {
562 setdata(firstnode(args), (void *) ztrdup(z));
564 * Note we don't do anything with the parameter structure
565 * for ARGV0: that's OK since we're about to exec or exit
566 * on failure.
568 #ifdef USE_SET_UNSET_ENV
569 unsetenv("ARGV0");
570 #else
571 delenvvalue(z - 6);
572 #endif
573 } else if (flags & BINF_DASH) {
574 /* Else if the pre-command `-' was given, we add `-' *
575 * to the front of argv[0] for this command. */
576 sprintf(buf2, "-%s", arg0);
577 setdata(firstnode(args), (void *) ztrdup(buf2));
580 argv = makecline(args);
581 if (flags & BINF_CLEARENV)
582 newenvp = blank_env;
585 * Note that we don't close fd's attached to process substitution
586 * here, which should be visible to external processes.
588 closem(FDT_XTRACE);
589 child_unblock();
590 if ((int) strlen(arg0) >= PATH_MAX) {
591 zerr("command too long: %s", arg0);
592 _exit(1);
594 for (s = arg0; *s; s++)
595 if (*s == '/') {
596 int lerrno = zexecve(arg0, argv, newenvp);
597 if (arg0 == s || unset(PATHDIRS) ||
598 (arg0[0] == '.' && (arg0 + 1 == s ||
599 (arg0[1] == '.' && arg0 + 2 == s)))) {
600 zerr("%e: %s", lerrno, arg0);
601 _exit((lerrno == EACCES || lerrno == ENOEXEC) ? 126 : 127);
603 break;
606 /* for command -p, search the default path */
607 if (defpath) {
608 char *s, pbuf[PATH_MAX];
609 char *dptr, *pe, *ps = DEFAULT_PATH;
611 for(;ps;ps = pe ? pe+1 : NULL) {
612 pe = strchr(ps, ':');
613 if (*ps == '/') {
614 s = pbuf;
615 if (pe)
616 struncpy(&s, ps, pe-ps);
617 else
618 strucpy(&s, ps);
619 *s++ = '/';
620 if ((s - pbuf) + strlen(arg0) >= PATH_MAX)
621 continue;
622 strucpy(&s, arg0);
623 if (iscom(pbuf))
624 break;
628 if (!ps) {
629 if (commandnotfound(arg0, args) == 0)
630 _exit(0);
631 zerr("command not found: %s", arg0);
632 _exit(127);
635 ee = zexecve(pbuf, argv, newenvp);
637 if ((dptr = strrchr(pbuf, '/')))
638 *dptr = '\0';
639 if (isgooderr(ee, *pbuf ? pbuf : "/"))
640 eno = ee;
642 } else {
644 if ((cn = (Cmdnam) cmdnamtab->getnode(cmdnamtab, arg0))) {
645 char nn[PATH_MAX], *dptr;
647 if (cn->node.flags & HASHED)
648 strcpy(nn, cn->u.cmd);
649 else {
650 for (pp = path; pp < cn->u.name; pp++)
651 if (!**pp || (**pp == '.' && (*pp)[1] == '\0')) {
652 ee = zexecve(arg0, argv, newenvp);
653 if (isgooderr(ee, *pp))
654 eno = ee;
655 } else if (**pp != '/') {
656 z = buf;
657 strucpy(&z, *pp);
658 *z++ = '/';
659 strcpy(z, arg0);
660 ee = zexecve(buf, argv, newenvp);
661 if (isgooderr(ee, *pp))
662 eno = ee;
664 strcpy(nn, cn->u.name ? *(cn->u.name) : "");
665 strcat(nn, "/");
666 strcat(nn, cn->node.nam);
668 ee = zexecve(nn, argv, newenvp);
670 if ((dptr = strrchr(nn, '/')))
671 *dptr = '\0';
672 if (isgooderr(ee, *nn ? nn : "/"))
673 eno = ee;
675 for (pp = path; *pp; pp++)
676 if (!(*pp)[0] || ((*pp)[0] == '.' && !(*pp)[1])) {
677 ee = zexecve(arg0, argv, newenvp);
678 if (isgooderr(ee, *pp))
679 eno = ee;
680 } else {
681 z = buf;
682 strucpy(&z, *pp);
683 *z++ = '/';
684 strcpy(z, arg0);
685 ee = zexecve(buf, argv, newenvp);
686 if (isgooderr(ee, *pp))
687 eno = ee;
691 if (eno)
692 zerr("%e: %s", eno, arg0);
693 else if (commandnotfound(arg0, args) == 0)
694 _exit(0);
695 else
696 zerr("command not found: %s", arg0);
697 _exit((eno == EACCES || eno == ENOEXEC) ? 126 : 127);
700 #define RET_IF_COM(X) { if (iscom(X)) return docopy ? dupstring(X) : arg0; }
703 * Get the full pathname of an external command.
704 * If the second argument is zero, return the first argument if found;
705 * if non-zero, return the path using heap memory. (RET_IF_COM(X), above).
708 /**/
709 mod_export char *
710 findcmd(char *arg0, int docopy)
712 char **pp;
713 char *z, *s, buf[MAXCMDLEN];
714 Cmdnam cn;
716 cn = (Cmdnam) cmdnamtab->getnode(cmdnamtab, arg0);
717 if (!cn && isset(HASHCMDS))
718 cn = hashcmd(arg0, path);
719 if ((int) strlen(arg0) > PATH_MAX)
720 return NULL;
721 for (s = arg0; *s; s++)
722 if (*s == '/') {
723 RET_IF_COM(arg0);
724 if (arg0 == s || unset(PATHDIRS)) {
725 return NULL;
727 break;
729 if (cn) {
730 char nn[PATH_MAX];
732 if (cn->node.flags & HASHED)
733 strcpy(nn, cn->u.cmd);
734 else {
735 for (pp = path; pp < cn->u.name; pp++)
736 if (**pp != '/') {
737 z = buf;
738 if (**pp) {
739 strucpy(&z, *pp);
740 *z++ = '/';
742 strcpy(z, arg0);
743 RET_IF_COM(buf);
745 strcpy(nn, cn->u.name ? *(cn->u.name) : "");
746 strcat(nn, "/");
747 strcat(nn, cn->node.nam);
749 RET_IF_COM(nn);
751 for (pp = path; *pp; pp++) {
752 z = buf;
753 if (**pp) {
754 strucpy(&z, *pp);
755 *z++ = '/';
757 strcpy(z, arg0);
758 RET_IF_COM(buf);
760 return NULL;
763 /**/
765 iscom(char *s)
767 struct stat statbuf;
768 char *us = unmeta(s);
770 return (access(us, X_OK) == 0 && stat(us, &statbuf) >= 0 &&
771 S_ISREG(statbuf.st_mode));
774 /**/
776 isreallycom(Cmdnam cn)
778 char fullnam[MAXCMDLEN];
780 if (cn->node.flags & HASHED)
781 strcpy(fullnam, cn->u.cmd);
782 else if (!cn->u.name)
783 return 0;
784 else {
785 strcpy(fullnam, *(cn->u.name));
786 strcat(fullnam, "/");
787 strcat(fullnam, cn->node.nam);
789 return iscom(fullnam);
792 /**/
794 isrelative(char *s)
796 if (*s != '/')
797 return 1;
798 for (; *s; s++)
799 if (*s == '.' && s[-1] == '/' &&
800 (s[1] == '/' || s[1] == '\0' ||
801 (s[1] == '.' && (s[2] == '/' || s[2] == '\0'))))
802 return 1;
803 return 0;
806 /**/
807 mod_export Cmdnam
808 hashcmd(char *arg0, char **pp)
810 Cmdnam cn;
811 char *s, buf[PATH_MAX];
812 char **pq;
814 for (; *pp; pp++)
815 if (**pp == '/') {
816 s = buf;
817 strucpy(&s, *pp);
818 *s++ = '/';
819 if ((s - buf) + strlen(arg0) >= PATH_MAX)
820 continue;
821 strcpy(s, arg0);
822 if (iscom(buf))
823 break;
826 if (!*pp)
827 return NULL;
829 cn = (Cmdnam) zshcalloc(sizeof *cn);
830 cn->node.flags = 0;
831 cn->u.name = pp;
832 cmdnamtab->addnode(cmdnamtab, ztrdup(arg0), cn);
834 if (isset(HASHDIRS)) {
835 for (pq = pathchecked; pq <= pp; pq++)
836 hashdir(pq);
837 pathchecked = pp + 1;
840 return cn;
843 /**/
845 forklevel;
847 /* Arguments to entersubsh() */
848 enum {
849 /* Subshell is to be run asynchronously (else synchronously) */
850 ESUB_ASYNC = 0x01,
852 * Perform process group and tty handling and clear the
853 * (real) job table, since it won't be any longer valid
855 ESUB_PGRP = 0x02,
856 /* Don't unset traps */
857 ESUB_KEEPTRAP = 0x04,
858 /* This is only a fake entry to a subshell */
859 ESUB_FAKE = 0x08,
860 /* Release the process group if pid is the shell's process group */
861 ESUB_REVERTPGRP = 0x10,
862 /* Don't handle the MONITOR option even if previously set */
863 ESUB_NOMONITOR = 0x20
866 /**/
867 static void
868 entersubsh(int flags)
870 int sig, monitor;
872 if (!(flags & ESUB_KEEPTRAP))
873 for (sig = 0; sig < VSIGCOUNT; sig++)
874 if (!(sigtrapped[sig] & ZSIG_FUNC) &&
875 sig != SIGDEBUG && sig != SIGZERR)
876 unsettrap(sig);
877 monitor = isset(MONITOR);
878 if (flags & ESUB_NOMONITOR)
879 opts[MONITOR] = 0;
880 if (!isset(MONITOR)) {
881 if (flags & ESUB_ASYNC) {
882 settrap(SIGINT, NULL, 0);
883 settrap(SIGQUIT, NULL, 0);
884 if (isatty(0)) {
885 close(0);
886 if (open("/dev/null", O_RDWR | O_NOCTTY)) {
887 zerr("can't open /dev/null: %e", errno);
888 _exit(1);
892 } else if (thisjob != -1 && (flags & ESUB_PGRP)) {
893 if (jobtab[list_pipe_job].gleader && (list_pipe || list_pipe_child)) {
894 if (setpgrp(0L, jobtab[list_pipe_job].gleader) == -1 ||
895 killpg(jobtab[list_pipe_job].gleader, 0) == -1) {
896 jobtab[list_pipe_job].gleader =
897 jobtab[thisjob].gleader = (list_pipe_child ? mypgrp : getpid());
898 setpgrp(0L, jobtab[list_pipe_job].gleader);
899 if (!(flags & ESUB_ASYNC))
900 attachtty(jobtab[thisjob].gleader);
903 else if (!jobtab[thisjob].gleader ||
904 setpgrp(0L, jobtab[thisjob].gleader) == -1) {
905 jobtab[thisjob].gleader = getpid();
906 if (list_pipe_job != thisjob &&
907 !jobtab[list_pipe_job].gleader)
908 jobtab[list_pipe_job].gleader = jobtab[thisjob].gleader;
909 setpgrp(0L, jobtab[thisjob].gleader);
910 if (!(flags & ESUB_ASYNC))
911 attachtty(jobtab[thisjob].gleader);
914 if (!(flags & ESUB_FAKE))
915 subsh = 1;
917 * Increment the visible parameter ZSH_SUBSHELL even if this
918 * is a fake subshell because we are exec'ing at the end.
919 * Logically this should be equivalent to a real subshell so
920 * we don't hang out the dirty washing.
922 zsh_subshell++;
923 if ((flags & ESUB_REVERTPGRP) && getpid() == mypgrp)
924 release_pgrp();
925 if (SHTTY != -1) {
926 shout = NULL;
927 zclose(SHTTY);
928 SHTTY = -1;
930 if (isset(MONITOR)) {
931 signal_default(SIGTTOU);
932 signal_default(SIGTTIN);
933 signal_default(SIGTSTP);
935 if (interact) {
936 signal_default(SIGTERM);
937 if (!(sigtrapped[SIGINT] & ZSIG_IGNORED))
938 signal_default(SIGINT);
940 if (!(sigtrapped[SIGQUIT] & ZSIG_IGNORED))
941 signal_default(SIGQUIT);
942 opts[MONITOR] = opts[USEZLE] = 0;
943 zleactive = 0;
944 if (flags & ESUB_PGRP)
945 clearjobtab(monitor);
946 get_usage();
947 forklevel = locallevel;
950 /* execute a string */
952 /**/
953 mod_export void
954 execstring(char *s, int dont_change_job, int exiting)
956 Eprog prog;
958 pushheap();
959 if ((prog = parse_string(s, 0)))
960 execode(prog, dont_change_job, exiting);
961 popheap();
964 /**/
965 mod_export void
966 execode(Eprog p, int dont_change_job, int exiting)
968 struct estate s;
970 s.prog = p;
971 s.pc = p->prog;
972 s.strs = p->strs;
973 useeprog(p); /* Mark as in use */
975 execlist(&s, dont_change_job, exiting);
977 freeeprog(p); /* Free if now unused */
980 /* Execute a simplified command. This is used to execute things that
981 * will run completely in the shell, so that we can by-pass all that
982 * nasty job-handling and redirection stuff in execpline and execcmd. */
984 /**/
985 static int
986 execsimple(Estate state)
988 wordcode code = *state->pc++;
989 int lv;
991 if (errflag)
992 return (lastval = 1);
994 /* In evaluated traps, don't modify the line number. */
995 if (!IN_EVAL_TRAP() && !ineval && code)
996 lineno = code - 1;
998 code = wc_code(*state->pc++);
1000 if (code == WC_ASSIGN) {
1001 cmdoutval = 0;
1002 addvars(state, state->pc - 1, 0);
1003 if (isset(XTRACE)) {
1004 fputc('\n', xtrerr);
1005 fflush(xtrerr);
1007 lv = (errflag ? errflag : cmdoutval);
1008 } else
1009 lv = (execfuncs[code - WC_CURSH])(state, 0);
1011 return lastval = lv;
1014 /* Main routine for executing a list. *
1015 * exiting means that the (sub)shell we are in is a definite goner *
1016 * after the current list is finished, so we may be able to exec the *
1017 * last command directly instead of forking. If dont_change_job is *
1018 * nonzero, then restore the current job number after executing the *
1019 * list. */
1021 /**/
1022 void
1023 execlist(Estate state, int dont_change_job, int exiting)
1025 static int donetrap;
1026 Wordcode next;
1027 wordcode code;
1028 int ret, cj, csp, ltype;
1029 int old_pline_level, old_list_pipe;
1030 zlong oldlineno;
1032 * ERREXIT only forces the shell to exit if the last command in a &&
1033 * or || fails. This is the case even if an earlier command is a
1034 * shell function or other current shell structure, so we have to set
1035 * noerrexit here if the sublist is not of type END.
1037 int oldnoerrexit = noerrexit;
1039 cj = thisjob;
1040 old_pline_level = pline_level;
1041 old_list_pipe = list_pipe;
1042 oldlineno = lineno;
1044 if (sourcelevel && unset(SHINSTDIN))
1045 pline_level = list_pipe = 0;
1047 /* Loop over all sets of comands separated by newline, *
1048 * semi-colon or ampersand (`sublists'). */
1049 code = *state->pc++;
1050 while (wc_code(code) == WC_LIST && !breaks && !retflag && !errflag) {
1051 int donedebug;
1053 ltype = WC_LIST_TYPE(code);
1054 csp = cmdsp;
1056 if (!IN_EVAL_TRAP() && !ineval) {
1058 * Ensure we have a valid line number for debugging,
1059 * unless we are in an evaluated trap in which case
1060 * we retain the line number from the context.
1061 * This was added for DEBUGBEFORECMD but I've made
1062 * it unconditional to keep dependencies to a minimum.
1064 * The line number is updated for individual pipelines.
1065 * This isn't necessary for debug traps since they only
1066 * run once per sublist.
1068 wordcode code2 = *state->pc, lnp1 = 0;
1069 if (ltype & Z_SIMPLE) {
1070 lnp1 = code2;
1071 } else if (wc_code(code2) == WC_SUBLIST) {
1072 if (WC_SUBLIST_FLAGS(code2) == WC_SUBLIST_SIMPLE)
1073 lnp1 = state->pc[1];
1074 else
1075 lnp1 = WC_PIPE_LINENO(state->pc[1]);
1077 if (lnp1)
1078 lineno = lnp1 - 1;
1081 if (sigtrapped[SIGDEBUG] && isset(DEBUGBEFORECMD) && !intrap) {
1082 Wordcode pc2 = state->pc;
1083 int oerrexit_opt = opts[ERREXIT];
1084 Param pm;
1085 opts[ERREXIT] = 0;
1086 noerrexit = 1;
1087 if (ltype & Z_SIMPLE) /* skip the line number */
1088 pc2++;
1089 pm = setsparam("ZSH_DEBUG_CMD", getpermtext(state->prog, pc2, 0));
1091 exiting = donetrap;
1092 ret = lastval;
1093 dotrap(SIGDEBUG);
1094 if (!retflag)
1095 lastval = ret;
1096 donetrap = exiting;
1097 noerrexit = oldnoerrexit;
1099 * Only execute the trap once per sublist, even
1100 * if the DEBUGBEFORECMD option changes.
1102 donedebug = isset(ERREXIT) ? 2 : 1;
1103 opts[ERREXIT] = oerrexit_opt;
1104 if (pm)
1105 unsetparam_pm(pm, 0, 1);
1106 } else
1107 donedebug = intrap ? 1 : 0;
1109 if (ltype & Z_SIMPLE) {
1110 next = state->pc + WC_LIST_SKIP(code);
1111 if (donedebug != 2)
1112 execsimple(state);
1113 state->pc = next;
1114 goto sublist_done;
1116 /* Reset donetrap: this ensures that a trap is only *
1117 * called once for each sublist that fails. */
1118 donetrap = 0;
1120 /* Loop through code followed by &&, ||, or end of sublist. */
1121 code = *state->pc++;
1122 if (donedebug == 2) {
1123 /* Skip sublist. */
1124 while (wc_code(code) == WC_SUBLIST) {
1125 state->pc = state->pc + WC_SUBLIST_SKIP(code);
1126 if (WC_SUBLIST_TYPE(code) == WC_SUBLIST_END)
1127 break;
1128 code = *state->pc++;
1130 donetrap = 1;
1131 /* yucky but consistent... */
1132 goto sublist_done;
1134 while (wc_code(code) == WC_SUBLIST) {
1135 next = state->pc + WC_SUBLIST_SKIP(code);
1136 if (!oldnoerrexit)
1137 noerrexit = (WC_SUBLIST_TYPE(code) != WC_SUBLIST_END);
1138 switch (WC_SUBLIST_TYPE(code)) {
1139 case WC_SUBLIST_END:
1140 /* End of sublist; just execute, ignoring status. */
1141 if (WC_SUBLIST_FLAGS(code) & WC_SUBLIST_SIMPLE)
1142 execsimple(state);
1143 else
1144 execpline(state, code, ltype, (ltype & Z_END) && exiting);
1145 state->pc = next;
1146 goto sublist_done;
1147 break;
1148 case WC_SUBLIST_AND:
1149 /* If the return code is non-zero, we skip pipelines until *
1150 * we find a sublist followed by ORNEXT. */
1151 if ((ret = ((WC_SUBLIST_FLAGS(code) & WC_SUBLIST_SIMPLE) ?
1152 execsimple(state) :
1153 execpline(state, code, Z_SYNC, 0)))) {
1154 state->pc = next;
1155 code = *state->pc++;
1156 next = state->pc + WC_SUBLIST_SKIP(code);
1157 while (wc_code(code) == WC_SUBLIST &&
1158 WC_SUBLIST_TYPE(code) == WC_SUBLIST_AND) {
1159 state->pc = next;
1160 code = *state->pc++;
1161 next = state->pc + WC_SUBLIST_SKIP(code);
1163 if (wc_code(code) != WC_SUBLIST) {
1164 /* We've skipped to the end of the list, not executing *
1165 * the final pipeline, so don't perform error handling *
1166 * for this sublist. */
1167 donetrap = 1;
1168 goto sublist_done;
1169 } else if (WC_SUBLIST_TYPE(code) == WC_SUBLIST_END) {
1170 donetrap = 1;
1172 * Treat this in the same way as if we reached
1173 * the end of the sublist normally.
1175 state->pc = next;
1176 goto sublist_done;
1179 cmdpush(CS_CMDAND);
1180 break;
1181 case WC_SUBLIST_OR:
1182 /* If the return code is zero, we skip pipelines until *
1183 * we find a sublist followed by ANDNEXT. */
1184 if (!(ret = ((WC_SUBLIST_FLAGS(code) & WC_SUBLIST_SIMPLE) ?
1185 execsimple(state) :
1186 execpline(state, code, Z_SYNC, 0)))) {
1187 state->pc = next;
1188 code = *state->pc++;
1189 next = state->pc + WC_SUBLIST_SKIP(code);
1190 while (wc_code(code) == WC_SUBLIST &&
1191 WC_SUBLIST_TYPE(code) == WC_SUBLIST_OR) {
1192 state->pc = next;
1193 code = *state->pc++;
1194 next = state->pc + WC_SUBLIST_SKIP(code);
1196 if (wc_code(code) != WC_SUBLIST) {
1197 /* We've skipped to the end of the list, not executing *
1198 * the final pipeline, so don't perform error handling *
1199 * for this sublist. */
1200 donetrap = 1;
1201 goto sublist_done;
1202 } else if (WC_SUBLIST_TYPE(code) == WC_SUBLIST_END) {
1203 donetrap = 1;
1205 * Treat this in the same way as if we reached
1206 * the end of the sublist normally.
1208 state->pc = next;
1209 goto sublist_done;
1212 cmdpush(CS_CMDOR);
1213 break;
1215 state->pc = next;
1216 code = *state->pc++;
1218 state->pc--;
1219 sublist_done:
1221 noerrexit = oldnoerrexit;
1223 if (sigtrapped[SIGDEBUG] && !isset(DEBUGBEFORECMD) && !donedebug) {
1225 * Save and restore ERREXIT for consistency with
1226 * DEBUGBEFORECMD, even though it's not used.
1228 int oerrexit_opt = opts[ERREXIT];
1229 opts[ERREXIT] = 0;
1230 noerrexit = 1;
1231 exiting = donetrap;
1232 ret = lastval;
1233 dotrap(SIGDEBUG);
1234 if (!retflag)
1235 lastval = ret;
1236 donetrap = exiting;
1237 noerrexit = oldnoerrexit;
1238 opts[ERREXIT] = oerrexit_opt;
1241 cmdsp = csp;
1243 /* Check whether we are suppressing traps/errexit *
1244 * (typically in init scripts) and if we haven't *
1245 * already performed them for this sublist. */
1246 if (!noerrexit && !donetrap) {
1247 if (sigtrapped[SIGZERR] && lastval) {
1248 dotrap(SIGZERR);
1249 donetrap = 1;
1251 if (lastval) {
1252 int errreturn = isset(ERRRETURN) &&
1253 (isset(INTERACTIVE) || locallevel || sourcelevel);
1254 int errexit = isset(ERREXIT) ||
1255 (isset(ERRRETURN) && !errreturn);
1256 if (errexit) {
1257 if (sigtrapped[SIGEXIT])
1258 dotrap(SIGEXIT);
1259 if (mypid != getpid())
1260 _exit(lastval);
1261 else
1262 exit(lastval);
1264 if (errreturn) {
1265 retflag = 1;
1266 breaks = loops;
1270 if (ltype & Z_END)
1271 break;
1272 code = *state->pc++;
1274 pline_level = old_pline_level;
1275 list_pipe = old_list_pipe;
1276 lineno = oldlineno;
1277 if (dont_change_job)
1278 thisjob = cj;
1281 /* Execute a pipeline. *
1282 * last1 is a flag that this command is the last command in a shell *
1283 * that is about to exit, so we can exec instead of forking. It gets *
1284 * passed all the way down to execcmd() which actually makes the *
1285 * decision. A 0 is always passed if the command is not the last in *
1286 * the pipeline. This function assumes that the sublist is not NULL. *
1287 * If last1 is zero but the command is at the end of a pipeline, we *
1288 * pass 2 down to execcmd(). *
1291 /**/
1292 static int
1293 execpline(Estate state, wordcode slcode, int how, int last1)
1295 int ipipe[2], opipe[2];
1296 int pj, newjob;
1297 int old_simple_pline = simple_pline;
1298 int slflags = WC_SUBLIST_FLAGS(slcode);
1299 wordcode code = *state->pc++;
1300 static int lastwj, lpforked;
1302 if (wc_code(code) != WC_PIPE)
1303 return lastval = (slflags & WC_SUBLIST_NOT) != 0;
1304 else if (slflags & WC_SUBLIST_NOT)
1305 last1 = 0;
1307 pj = thisjob;
1308 ipipe[0] = ipipe[1] = opipe[0] = opipe[1] = 0;
1309 child_block();
1312 * Get free entry in job table and initialize it. This is currently
1313 * the only call to initjob() (apart from a minor exception in
1314 * clearjobtab()), so this is also the only place where we can
1315 * expand the job table under us.
1317 if ((thisjob = newjob = initjob()) == -1) {
1318 child_unblock();
1319 return 1;
1321 if (how & Z_TIMED)
1322 jobtab[thisjob].stat |= STAT_TIMED;
1324 if (slflags & WC_SUBLIST_COPROC) {
1325 how = Z_ASYNC;
1326 if (coprocin >= 0) {
1327 zclose(coprocin);
1328 zclose(coprocout);
1330 mpipe(ipipe);
1331 mpipe(opipe);
1332 coprocin = ipipe[0];
1333 coprocout = opipe[1];
1334 fdtable[coprocin] = fdtable[coprocout] = FDT_UNUSED;
1336 /* This used to set list_pipe_pid=0 unconditionally, but in things
1337 * like `ls|if true; then sleep 20; cat; fi' where the sleep was
1338 * stopped, the top-level execpline() didn't get the pid for the
1339 * sub-shell because it was overwritten. */
1340 if (!pline_level++) {
1341 list_pipe_pid = 0;
1342 nowait = 0;
1343 simple_pline = (WC_PIPE_TYPE(code) == WC_PIPE_END);
1344 list_pipe_job = newjob;
1346 lastwj = lpforked = 0;
1347 execpline2(state, code, how, opipe[0], ipipe[1], last1);
1348 pline_level--;
1349 if (how & Z_ASYNC) {
1350 lastwj = newjob;
1352 if (thisjob == list_pipe_job)
1353 list_pipe_job = 0;
1354 jobtab[thisjob].stat |= STAT_NOSTTY;
1355 if (slflags & WC_SUBLIST_COPROC) {
1356 zclose(ipipe[1]);
1357 zclose(opipe[0]);
1359 if (how & Z_DISOWN) {
1360 deletejob(jobtab + thisjob);
1361 thisjob = -1;
1363 else
1364 spawnjob();
1365 child_unblock();
1366 return 0;
1367 } else {
1368 if (newjob != lastwj) {
1369 Job jn = jobtab + newjob;
1370 int updated;
1372 if (newjob == list_pipe_job && list_pipe_child)
1373 _exit(0);
1375 lastwj = thisjob = newjob;
1377 if (list_pipe || (pline_level && !(how & Z_TIMED)))
1378 jn->stat |= STAT_NOPRINT;
1380 if (nowait) {
1381 if(!pline_level) {
1382 struct process *pn, *qn;
1384 curjob = newjob;
1385 DPUTS(!list_pipe_pid, "invalid list_pipe_pid");
1386 addproc(list_pipe_pid, list_pipe_text, 0,
1387 &list_pipe_start);
1389 /* If the super-job contains only the sub-shell, the
1390 sub-shell is the group leader. */
1391 if (!jn->procs->next || lpforked == 2) {
1392 jn->gleader = list_pipe_pid;
1393 jn->stat |= STAT_SUBLEADER;
1395 for (pn = jobtab[jn->other].procs; pn; pn = pn->next)
1396 if (WIFSTOPPED(pn->status))
1397 break;
1399 if (pn) {
1400 for (qn = jn->procs; qn->next; qn = qn->next);
1401 qn->status = pn->status;
1404 jn->stat &= ~(STAT_DONE | STAT_NOPRINT);
1405 jn->stat |= STAT_STOPPED | STAT_CHANGED | STAT_LOCKED;
1406 printjob(jn, !!isset(LONGLISTJOBS), 1);
1408 else if (newjob != list_pipe_job)
1409 deletejob(jn);
1410 else
1411 lastwj = -1;
1414 errbrk_saved = 0;
1415 for (; !nowait;) {
1416 if (list_pipe_child) {
1417 jn->stat |= STAT_NOPRINT;
1418 makerunning(jn);
1420 if (!(jn->stat & STAT_LOCKED)) {
1421 updated = hasprocs(thisjob);
1422 waitjobs();
1423 child_block();
1424 } else
1425 updated = 0;
1426 if (!updated &&
1427 list_pipe_job && hasprocs(list_pipe_job) &&
1428 !(jobtab[list_pipe_job].stat & STAT_STOPPED)) {
1429 child_unblock();
1430 child_block();
1432 if (list_pipe_child &&
1433 jn->stat & STAT_DONE &&
1434 lastval2 & 0200)
1435 killpg(mypgrp, lastval2 & ~0200);
1436 if (!list_pipe_child && !lpforked && !subsh && jobbing &&
1437 (list_pipe || last1 || pline_level) &&
1438 ((jn->stat & STAT_STOPPED) ||
1439 (list_pipe_job && pline_level &&
1440 (jobtab[list_pipe_job].stat & STAT_STOPPED)))) {
1441 pid_t pid;
1442 int synch[2];
1443 struct timeval bgtime;
1445 pipe(synch);
1447 if ((pid = zfork(&bgtime)) == -1) {
1448 zleentry(ZLE_CMD_TRASH);
1449 close(synch[0]);
1450 close(synch[1]);
1451 fprintf(stderr, "zsh: job can't be suspended\n");
1452 fflush(stderr);
1453 makerunning(jn);
1454 killjb(jn, SIGCONT);
1455 thisjob = newjob;
1457 else if (pid) {
1458 char dummy;
1460 lpforked =
1461 (killpg(jobtab[list_pipe_job].gleader, 0) == -1 ? 2 : 1);
1462 list_pipe_pid = pid;
1463 list_pipe_start = bgtime;
1464 nowait = errflag = 1;
1465 breaks = loops;
1466 close(synch[1]);
1467 read(synch[0], &dummy, 1);
1468 close(synch[0]);
1469 /* If this job has finished, we leave it as a
1470 * normal (non-super-) job. */
1471 if (!(jn->stat & STAT_DONE)) {
1472 jobtab[list_pipe_job].other = newjob;
1473 jobtab[list_pipe_job].stat |= STAT_SUPERJOB;
1474 jn->stat |= STAT_SUBJOB | STAT_NOPRINT;
1475 jn->other = pid;
1477 if ((list_pipe || last1) && hasprocs(list_pipe_job))
1478 killpg(jobtab[list_pipe_job].gleader, SIGSTOP);
1479 break;
1481 else {
1482 close(synch[0]);
1483 entersubsh(ESUB_ASYNC);
1484 if (jobtab[list_pipe_job].procs) {
1485 if (setpgrp(0L, mypgrp = jobtab[list_pipe_job].gleader)
1486 == -1) {
1487 setpgrp(0L, mypgrp = getpid());
1489 } else
1490 setpgrp(0L, mypgrp = getpid());
1491 close(synch[1]);
1492 kill(getpid(), SIGSTOP);
1493 list_pipe = 0;
1494 list_pipe_child = 1;
1495 opts[INTERACTIVE] = 0;
1496 if (errbrk_saved) {
1497 errflag = prev_errflag;
1498 breaks = prev_breaks;
1500 break;
1503 else if (subsh && jn->stat & STAT_STOPPED)
1504 thisjob = newjob;
1505 else
1506 break;
1508 child_unblock();
1510 if (list_pipe && (lastval & 0200) && pj >= 0 &&
1511 (!(jn->stat & STAT_INUSE) || (jn->stat & STAT_DONE))) {
1512 deletejob(jn);
1513 jn = jobtab + pj;
1514 if (jn->gleader)
1515 killjb(jn, lastval & ~0200);
1517 if (list_pipe_child ||
1518 ((jn->stat & STAT_DONE) &&
1519 (list_pipe || (pline_level && !(jn->stat & STAT_SUBJOB)))))
1520 deletejob(jn);
1521 thisjob = pj;
1524 if (slflags & WC_SUBLIST_NOT)
1525 lastval = !lastval;
1527 if (!pline_level)
1528 simple_pline = old_simple_pline;
1529 return lastval;
1532 static int subsh_close = -1;
1534 /* execute pipeline. This function assumes the `pline' is not NULL. */
1536 /**/
1537 static void
1538 execpline2(Estate state, wordcode pcode,
1539 int how, int input, int output, int last1)
1541 pid_t pid;
1542 int pipes[2];
1544 if (breaks || retflag)
1545 return;
1547 /* In evaluated traps, don't modify the line number. */
1548 if (!IN_EVAL_TRAP() && !ineval && WC_PIPE_LINENO(pcode))
1549 lineno = WC_PIPE_LINENO(pcode) - 1;
1551 if (pline_level == 1) {
1552 if ((how & Z_ASYNC) || (!sfcontext && !sourcelevel))
1553 strcpy(list_pipe_text,
1554 getjobtext(state->prog,
1555 state->pc + (WC_PIPE_TYPE(pcode) == WC_PIPE_END ?
1556 0 : 1)));
1557 else
1558 list_pipe_text[0] = '\0';
1560 if (WC_PIPE_TYPE(pcode) == WC_PIPE_END)
1561 execcmd(state, input, output, how, last1 ? 1 : 2);
1562 else {
1563 int old_list_pipe = list_pipe;
1564 Wordcode next = state->pc + (*state->pc), pc;
1565 wordcode code;
1567 state->pc++;
1568 for (pc = state->pc; wc_code(code = *pc) == WC_REDIR;
1569 pc += WC_REDIR_WORDS(code));
1571 mpipe(pipes);
1573 /* if we are doing "foo | bar" where foo is a current *
1574 * shell command, do foo in a subshell and do the *
1575 * rest of the pipeline in the current shell. */
1576 if (wc_code(code) >= WC_CURSH && (how & Z_SYNC)) {
1577 int synch[2];
1578 struct timeval bgtime;
1580 pipe(synch);
1581 if ((pid = zfork(&bgtime)) == -1) {
1582 close(synch[0]);
1583 close(synch[1]);
1584 } else if (pid) {
1585 char dummy, *text;
1587 text = getjobtext(state->prog, state->pc);
1588 addproc(pid, text, 0, &bgtime);
1589 close(synch[1]);
1590 read(synch[0], &dummy, 1);
1591 close(synch[0]);
1592 } else {
1593 zclose(pipes[0]);
1594 close(synch[0]);
1595 entersubsh(((how & Z_ASYNC) ? ESUB_ASYNC : 0)
1596 | ESUB_PGRP | ESUB_KEEPTRAP);
1597 close(synch[1]);
1598 execcmd(state, input, pipes[1], how, 0);
1599 _exit(lastval);
1601 } else {
1602 /* otherwise just do the pipeline normally. */
1603 subsh_close = pipes[0];
1604 execcmd(state, input, pipes[1], how, 0);
1606 zclose(pipes[1]);
1607 state->pc = next;
1609 /* if another execpline() is invoked because the command is *
1610 * a list it must know that we're already in a pipeline */
1611 cmdpush(CS_PIPE);
1612 list_pipe = 1;
1613 execpline2(state, *state->pc++, how, pipes[0], output, last1);
1614 list_pipe = old_list_pipe;
1615 cmdpop();
1616 zclose(pipes[0]);
1617 subsh_close = -1;
1621 /* make the argv array */
1623 /**/
1624 static char **
1625 makecline(LinkList list)
1627 LinkNode node;
1628 char **argv, **ptr;
1630 /* A bigger argv is necessary for executing scripts */
1631 ptr = argv = 2 + (char **) hcalloc((countlinknodes(list) + 4) *
1632 sizeof(char *));
1634 if (isset(XTRACE)) {
1635 if (!doneps4)
1636 printprompt4();
1638 for (node = firstnode(list); node; incnode(node)) {
1639 *ptr++ = (char *)getdata(node);
1640 quotedzputs(getdata(node), xtrerr);
1641 if (nextnode(node))
1642 fputc(' ', xtrerr);
1644 fputc('\n', xtrerr);
1645 fflush(xtrerr);
1646 } else {
1647 for (node = firstnode(list); node; incnode(node))
1648 *ptr++ = (char *)getdata(node);
1650 *ptr = NULL;
1651 return (argv);
1654 /**/
1655 mod_export void
1656 untokenize(char *s)
1658 if (*s) {
1659 int c;
1661 while ((c = *s++))
1662 if (itok(c)) {
1663 char *p = s - 1;
1665 if (c != Nularg)
1666 *p++ = ztokens[c - Pound];
1668 while ((c = *s++)) {
1669 if (itok(c)) {
1670 if (c != Nularg)
1671 *p++ = ztokens[c - Pound];
1672 } else
1673 *p++ = c;
1675 *p = '\0';
1676 break;
1683 * Given a tokenized string, output it to standard output in
1684 * such a way that it's clear which tokens are active.
1685 * Hence Star becomes an unquoted "*", while a "*" becomes "\*".
1687 * The code here is a kind of amalgamation of the tests in
1688 * zshtokenize() and untokenize() with some outputting.
1691 /**/
1692 void
1693 quote_tokenized_output(char *str, FILE *file)
1695 char *s = str;
1697 for (; *s; s++) {
1698 switch (*s) {
1699 case Meta:
1700 putc(*++s ^ 32, file);
1701 continue;
1703 case Nularg:
1704 /* Do nothing. I think. */
1705 continue;
1707 case '\\':
1708 case '<':
1709 case '>':
1710 case '(':
1711 case '|':
1712 case ')':
1713 case '^':
1714 case '#':
1715 case '~':
1716 case '[':
1717 case ']':
1718 case '*':
1719 case '?':
1720 case '$':
1721 putc('\\', file);
1722 break;
1724 case '=':
1725 if (s == str)
1726 putc('\\', file);
1727 break;
1729 default:
1730 if (itok(*s)) {
1731 putc(ztokens[*s - Pound], file);
1732 continue;
1734 break;
1737 putc(*s, file);
1741 /* Check that we can use a parameter for allocating a file descriptor. */
1743 static int
1744 checkclobberparam(struct redir *f)
1746 struct value vbuf;
1747 Value v;
1748 char *s = f->varid;
1749 int fd;
1751 if (!s)
1752 return 1;
1754 if (!(v = getvalue(&vbuf, &s, 0)))
1755 return 1;
1757 if (v->pm->node.flags & PM_READONLY) {
1758 zwarn("can't allocate file descriptor to readonly parameter %s",
1759 f->varid);
1760 /* don't flag a system error for this */
1761 errno = 0;
1762 return 0;
1765 if (!isset(CLOBBER) && (fd = (int)getintvalue(v)) &&
1766 fd <= max_zsh_fd && fdtable[fd] == FDT_EXTERNAL) {
1767 zwarn("can't clobber parameter %s containing file descriptor %d",
1768 f->varid, fd);
1769 /* don't flag a system error for this */
1770 errno = 0;
1771 return 0;
1773 return 1;
1776 /* Open a file for writing redirection */
1778 /**/
1779 static int
1780 clobber_open(struct redir *f)
1782 struct stat buf;
1783 int fd, oerrno;
1785 /* If clobbering, just open. */
1786 if (isset(CLOBBER) || IS_CLOBBER_REDIR(f->type))
1787 return open(unmeta(f->name),
1788 O_WRONLY | O_CREAT | O_TRUNC | O_NOCTTY, 0666);
1790 /* If not clobbering, attempt to create file exclusively. */
1791 if ((fd = open(unmeta(f->name),
1792 O_WRONLY | O_CREAT | O_EXCL | O_NOCTTY, 0666)) >= 0)
1793 return fd;
1795 /* If that fails, we are still allowed to open non-regular files. *
1796 * Try opening, and if it's a regular file then close it again *
1797 * because we weren't supposed to open it. */
1798 oerrno = errno;
1799 if ((fd = open(unmeta(f->name), O_WRONLY | O_NOCTTY)) != -1) {
1800 if(!fstat(fd, &buf) && !S_ISREG(buf.st_mode))
1801 return fd;
1802 close(fd);
1804 errno = oerrno;
1805 return -1;
1808 /* size of buffer for tee and cat processes */
1809 #define TCBUFSIZE 4092
1811 /* close an multio (success) */
1813 /**/
1814 static void
1815 closemn(struct multio **mfds, int fd)
1817 if (fd >= 0 && mfds[fd] && mfds[fd]->ct >= 2) {
1818 struct multio *mn = mfds[fd];
1819 char buf[TCBUFSIZE];
1820 int len, i;
1821 pid_t pid;
1822 struct timeval bgtime;
1825 * We need to block SIGCHLD in case the process
1826 * we are spawning terminates before the job table
1827 * is set up to handle it.
1829 child_block();
1830 if ((pid = zfork(&bgtime))) {
1831 for (i = 0; i < mn->ct; i++)
1832 zclose(mn->fds[i]);
1833 zclose(mn->pipe);
1834 if (pid == -1) {
1835 mfds[fd] = NULL;
1836 child_unblock();
1837 return;
1839 mn->ct = 1;
1840 mn->fds[0] = fd;
1841 addproc(pid, NULL, 1, &bgtime);
1842 child_unblock();
1843 return;
1845 /* pid == 0 */
1846 child_unblock();
1847 closeallelse(mn);
1848 if (mn->rflag) {
1849 /* tee process */
1850 while ((len = read(mn->pipe, buf, TCBUFSIZE)) != 0) {
1851 if (len < 0) {
1852 if (errno == EINTR)
1853 continue;
1854 else
1855 break;
1857 for (i = 0; i < mn->ct; i++)
1858 write(mn->fds[i], buf, len);
1860 } else {
1861 /* cat process */
1862 for (i = 0; i < mn->ct; i++)
1863 while ((len = read(mn->fds[i], buf, TCBUFSIZE)) != 0) {
1864 if (len < 0) {
1865 if (errno == EINTR)
1866 continue;
1867 else
1868 break;
1870 write(mn->pipe, buf, len);
1873 _exit(0);
1874 } else if (fd >= 0)
1875 mfds[fd] = NULL;
1878 /* close all the mnodes (failure) */
1880 /**/
1881 static void
1882 closemnodes(struct multio **mfds)
1884 int i, j;
1886 for (i = 0; i < 10; i++)
1887 if (mfds[i]) {
1888 for (j = 0; j < mfds[i]->ct; j++)
1889 zclose(mfds[i]->fds[j]);
1890 mfds[i] = NULL;
1894 /**/
1895 static void
1896 closeallelse(struct multio *mn)
1898 int i, j;
1899 long openmax;
1901 openmax = zopenmax();
1903 for (i = 0; i < openmax; i++)
1904 if (mn->pipe != i) {
1905 for (j = 0; j < mn->ct; j++)
1906 if (mn->fds[j] == i)
1907 break;
1908 if (j == mn->ct)
1909 zclose(i);
1914 * A multio is a list of fds associated with a certain fd.
1915 * Thus if you do "foo >bar >ble", the multio for fd 1 will have
1916 * two fds, the result of open("bar",...), and the result of
1917 * open("ble",....).
1921 * Add a fd to an multio. fd1 must be < 10, and may be in any state.
1922 * fd2 must be open, and is `consumed' by this function. Note that
1923 * fd1 == fd2 is possible, and indicates that fd1 was really closed.
1924 * We effectively do `fd2 = movefd(fd2)' at the beginning of this
1925 * function, but in most cases we can avoid an extra dup by delaying
1926 * the movefd: we only >need< to move it if we're actually doing a
1927 * multiple redirection.
1929 * If varid is not NULL, we open an fd above 10 and set the parameter
1930 * named varid to that value. fd1 is not used.
1933 /**/
1934 static void
1935 addfd(int forked, int *save, struct multio **mfds, int fd1, int fd2, int rflag,
1936 char *varid)
1938 int pipes[2];
1940 if (varid) {
1941 /* fd will be over 10, don't touch mfds */
1942 fd1 = movefd(fd2);
1943 fdtable[fd1] = FDT_EXTERNAL;
1944 setiparam(varid, (zlong)fd1);
1946 * If setting the parameter failed, close the fd else
1947 * it will leak.
1949 if (errflag)
1950 zclose(fd1);
1951 } else if (!mfds[fd1] || unset(MULTIOS)) {
1952 if(!mfds[fd1]) { /* starting a new multio */
1953 mfds[fd1] = (struct multio *) zhalloc(sizeof(struct multio));
1954 if (!forked && save[fd1] == -2) {
1955 if (fd1 == fd2)
1956 save[fd1] = -1;
1957 else {
1958 int fdN = movefd(fd1);
1960 * fd1 may already be closed here, so
1961 * ignore bad file descriptor error
1963 if (fdN < 0 && errno != EBADF) {
1964 zerr("cannot duplicate fd %d: %e", fd1, errno);
1965 closemnodes(mfds);
1966 return;
1968 save[fd1] = fdN;
1972 if (!varid)
1973 redup(fd2, fd1);
1974 mfds[fd1]->ct = 1;
1975 mfds[fd1]->fds[0] = fd1;
1976 mfds[fd1]->rflag = rflag;
1977 } else {
1978 if (mfds[fd1]->rflag != rflag) {
1979 zerr("file mode mismatch on fd %d", fd1);
1980 closemnodes(mfds);
1981 return;
1983 if (mfds[fd1]->ct == 1) { /* split the stream */
1984 int fdN = movefd(fd1);
1985 if (fdN < 0) {
1986 zerr("multio failed for fd %d: %e", fd1, errno);
1987 closemnodes(mfds);
1988 return;
1990 mfds[fd1]->fds[0] = fdN;
1991 fdN = movefd(fd2);
1992 if (fdN < 0) {
1993 zerr("multio failed for fd %d: %e", fd2, errno);
1994 closemnodes(mfds);
1995 return;
1997 mfds[fd1]->fds[1] = fdN;
1998 mpipe(pipes);
1999 mfds[fd1]->pipe = pipes[1 - rflag];
2000 redup(pipes[rflag], fd1);
2001 mfds[fd1]->ct = 2;
2002 } else { /* add another fd to an already split stream */
2003 int fdN;
2004 if(!(mfds[fd1]->ct % MULTIOUNIT)) {
2005 int new = sizeof(struct multio) + sizeof(int) * mfds[fd1]->ct;
2006 int old = new - sizeof(int) * MULTIOUNIT;
2007 mfds[fd1] = hrealloc((char *)mfds[fd1], old, new);
2009 if ((fdN = movefd(fd2)) < 0) {
2010 zerr("multio failed for fd %d: %e", fd2, errno);
2011 closemnodes(mfds);
2012 return;
2014 mfds[fd1]->fds[mfds[fd1]->ct++] = fdN;
2017 if (subsh_close >= 0 && fdtable[subsh_close] == FDT_UNUSED)
2018 subsh_close = -1;
2021 /**/
2022 static void
2023 addvars(Estate state, Wordcode pc, int addflags)
2025 LinkList vl;
2026 int xtr, isstr, htok = 0;
2027 char **arr, **ptr, *name;
2028 int flags;
2030 Wordcode opc = state->pc;
2031 wordcode ac;
2032 local_list1(svl);
2035 * Warn when creating a global without using typeset -g in a
2036 * function. Don't do this if there is a list of variables marked
2037 * to be restored after the command, since then the assignment
2038 * is implicitly scoped.
2040 flags = (!(addflags & ADDVAR_RESTORE) &&
2041 locallevel > 0 && isset(WARNCREATEGLOBAL)) ?
2042 ASSPM_WARN_CREATE : 0;
2043 xtr = isset(XTRACE);
2044 if (xtr) {
2045 printprompt4();
2046 doneps4 = 1;
2048 state->pc = pc;
2049 while (wc_code(ac = *state->pc++) == WC_ASSIGN) {
2050 int myflags = flags;
2051 name = ecgetstr(state, EC_DUPTOK, &htok);
2052 if (htok)
2053 untokenize(name);
2054 if (WC_ASSIGN_TYPE2(ac) == WC_ASSIGN_INC)
2055 myflags |= ASSPM_AUGMENT;
2056 if (xtr)
2057 fprintf(xtrerr,
2058 WC_ASSIGN_TYPE2(ac) == WC_ASSIGN_INC ? "%s+=" : "%s=", name);
2059 if ((isstr = (WC_ASSIGN_TYPE(ac) == WC_ASSIGN_SCALAR))) {
2060 init_list1(svl, ecgetstr(state, EC_DUPTOK, &htok));
2061 vl = &svl;
2062 } else
2063 vl = ecgetlist(state, WC_ASSIGN_NUM(ac), EC_DUPTOK, &htok);
2065 if (vl && htok) {
2066 prefork(vl, (isstr ? (PF_SINGLE|PF_ASSIGN) :
2067 PF_ASSIGN));
2068 if (errflag) {
2069 state->pc = opc;
2070 return;
2072 if (isset(GLOBASSIGN) || !isstr)
2073 globlist(vl, 0);
2074 if (errflag) {
2075 state->pc = opc;
2076 return;
2079 if (isstr && (empty(vl) || !nextnode(firstnode(vl)))) {
2080 Param pm;
2081 char *val;
2082 int allexp;
2084 if (empty(vl))
2085 val = ztrdup("");
2086 else {
2087 untokenize(peekfirst(vl));
2088 val = ztrdup(ugetnode(vl));
2090 if (xtr) {
2091 quotedzputs(val, xtrerr);
2092 fputc(' ', xtrerr);
2094 if ((addflags & ADDVAR_EXPORT) && !strchr(name, '[')) {
2095 if ((addflags & ADDVAR_RESTRICT) && isset(RESTRICTED) &&
2096 (pm = (Param) paramtab->removenode(paramtab, name)) &&
2097 (pm->node.flags & PM_RESTRICTED)) {
2098 zerr("%s: restricted", pm->node.nam);
2099 zsfree(val);
2100 state->pc = opc;
2101 return;
2103 if (strcmp(name, "STTY") == 0) {
2104 zsfree(STTYval);
2105 STTYval = ztrdup(val);
2107 allexp = opts[ALLEXPORT];
2108 opts[ALLEXPORT] = 1;
2109 pm = assignsparam(name, val, myflags);
2110 opts[ALLEXPORT] = allexp;
2111 } else
2112 pm = assignsparam(name, val, myflags);
2113 if (errflag) {
2114 state->pc = opc;
2115 return;
2117 continue;
2119 if (vl) {
2120 ptr = arr = (char **) zalloc(sizeof(char **) *
2121 (countlinknodes(vl) + 1));
2123 while (nonempty(vl))
2124 *ptr++ = ztrdup((char *) ugetnode(vl));
2125 } else
2126 ptr = arr = (char **) zalloc(sizeof(char **));
2128 *ptr = NULL;
2129 if (xtr) {
2130 fprintf(xtrerr, "( ");
2131 for (ptr = arr; *ptr; ptr++) {
2132 quotedzputs(*ptr, xtrerr);
2133 fputc(' ', xtrerr);
2135 fprintf(xtrerr, ") ");
2137 assignaparam(name, arr, myflags);
2138 if (errflag) {
2139 state->pc = opc;
2140 return;
2143 state->pc = opc;
2146 /**/
2147 void
2148 setunderscore(char *str)
2150 if (str && *str) {
2151 int l = strlen(str) + 1, nl = (l + 31) & ~31;
2153 if (nl > underscorelen || (underscorelen - nl) > 64) {
2154 zfree(underscore, underscorelen);
2155 underscore = (char *) zalloc(underscorelen = nl);
2157 strcpy(underscore, str);
2158 underscoreused = l;
2159 } else {
2160 if (underscorelen > 128) {
2161 zfree(underscore, underscorelen);
2162 underscore = (char *) zalloc(underscorelen = 32);
2164 *underscore = '\0';
2165 underscoreused = 1;
2169 /* These describe the type of expansions that need to be done on the words
2170 * used in the thing we are about to execute. They are set in execcmd() and
2171 * used in execsubst() which might be called from one of the functions
2172 * called from execcmd() (like execfor() and so on). */
2174 static int esprefork, esglob = 1;
2176 /**/
2177 void
2178 execsubst(LinkList strs)
2180 if (strs) {
2181 prefork(strs, esprefork);
2182 if (esglob) {
2183 LinkList ostrs = strs;
2184 globlist(strs, 0);
2185 strs = ostrs;
2191 * Check if a builtin requires an autoload and if so
2192 * deal with it. This may return NULL.
2195 /**/
2196 static HashNode
2197 resolvebuiltin(const char *cmdarg, HashNode hn)
2199 if (!((Builtin) hn)->handlerfunc) {
2201 * Ensure the module is loaded and the
2202 * feature corresponding to the builtin
2203 * is enabled.
2205 (void)ensurefeature(((Builtin) hn)->optstr, "b:",
2206 (hn->flags & BINF_AUTOALL) ? NULL :
2207 hn->nam);
2208 hn = builtintab->getnode(builtintab, cmdarg);
2209 if (!hn) {
2210 lastval = 1;
2211 zerr("unknown builtin: %s", cmdarg);
2212 return NULL;
2215 return hn;
2218 /**/
2219 static void
2220 execcmd(Estate state, int input, int output, int how, int last1)
2222 HashNode hn = NULL;
2223 LinkList args;
2224 LinkNode node;
2225 Redir fn;
2226 struct multio *mfds[10];
2227 char *text;
2228 int save[10];
2229 int fil, dfil, is_cursh, type, do_exec = 0, i, htok = 0;
2230 int nullexec = 0, assign = 0, forked = 0;
2231 int is_shfunc = 0, is_builtin = 0, is_exec = 0, use_defpath = 0;
2232 /* Various flags to the command. */
2233 int cflags = 0, checked = 0, oautocont = -1;
2234 LinkList redir;
2235 wordcode code;
2236 Wordcode beg = state->pc, varspc;
2237 FILE *oxtrerr = xtrerr, *newxtrerr = NULL;
2239 doneps4 = 0;
2240 redir = (wc_code(*state->pc) == WC_REDIR ? ecgetredirs(state) : NULL);
2241 if (wc_code(*state->pc) == WC_ASSIGN) {
2242 cmdoutval = 0;
2243 varspc = state->pc;
2244 while (wc_code((code = *state->pc)) == WC_ASSIGN)
2245 state->pc += (WC_ASSIGN_TYPE(code) == WC_ASSIGN_SCALAR ?
2246 3 : WC_ASSIGN_NUM(code) + 2);
2247 } else
2248 varspc = NULL;
2250 code = *state->pc++;
2252 type = wc_code(code);
2254 /* It would be nice if we could use EC_DUPTOK instead of EC_DUP here.
2255 * But for that we would need to check/change all builtins so that
2256 * they don't modify their argument strings. */
2257 args = (type == WC_SIMPLE ?
2258 ecgetlist(state, WC_SIMPLE_ARGC(code), EC_DUP, &htok) : NULL);
2260 * If assignment but no command get the status from variable
2261 * assignment.
2263 if (!args && varspc)
2264 lastval = errflag ? errflag : cmdoutval;
2266 for (i = 0; i < 10; i++) {
2267 save[i] = -2;
2268 mfds[i] = NULL;
2271 /* If the command begins with `%', then assume it is a *
2272 * reference to a job in the job table. */
2273 if (type == WC_SIMPLE && args && nonempty(args) &&
2274 *(char *)peekfirst(args) == '%') {
2275 if (how & Z_DISOWN) {
2276 oautocont = opts[AUTOCONTINUE];
2277 opts[AUTOCONTINUE] = 1;
2279 pushnode(args, dupstring((how & Z_DISOWN)
2280 ? "disown" : (how & Z_ASYNC) ? "bg" : "fg"));
2281 how = Z_SYNC;
2284 /* If AUTORESUME is set, the command is SIMPLE, and doesn't have *
2285 * any redirections, then check if it matches as a prefix of a *
2286 * job currently in the job table. If it does, then we treat it *
2287 * as a command to resume this job. */
2288 if (isset(AUTORESUME) && type == WC_SIMPLE && (how & Z_SYNC) &&
2289 args && nonempty(args) && (!redir || empty(redir)) && !input &&
2290 !nextnode(firstnode(args))) {
2291 if (unset(NOTIFY))
2292 scanjobs();
2293 if (findjobnam(peekfirst(args)) != -1)
2294 pushnode(args, dupstring("fg"));
2297 /* Check if it's a builtin needing automatic MAGIC_EQUALS_SUBST *
2298 * handling. Things like typeset need this. We can't detect the *
2299 * command if it contains some tokens (e.g. x=ex; ${x}port), so this *
2300 * only works in simple cases. has_token() is called to make sure *
2301 * this really is a simple case. */
2302 if (type == WC_SIMPLE) {
2303 while (args && nonempty(args)) {
2304 char *cmdarg = (char *) peekfirst(args);
2305 checked = !has_token(cmdarg);
2306 if (!checked)
2307 break;
2308 if (!(cflags & (BINF_BUILTIN | BINF_COMMAND)) &&
2309 (hn = shfunctab->getnode(shfunctab, cmdarg))) {
2310 is_shfunc = 1;
2311 break;
2313 if (!(hn = builtintab->getnode(builtintab, cmdarg))) {
2314 checked = !(cflags & BINF_BUILTIN);
2315 break;
2317 if (!(hn->flags & BINF_PREFIX)) {
2318 is_builtin = 1;
2320 /* autoload the builtin if necessary */
2321 if (!(hn = resolvebuiltin(cmdarg, hn)))
2322 return;
2323 assign = (hn->flags & BINF_MAGICEQUALS);
2324 break;
2326 cflags &= ~BINF_BUILTIN & ~BINF_COMMAND;
2327 cflags |= hn->flags;
2328 checked = 0;
2329 if ((cflags & BINF_COMMAND) && nextnode(firstnode(args))) {
2330 /* check for options to command builtin */
2331 char *next = (char *) getdata(nextnode(firstnode(args)));
2332 char *cmdopt;
2333 if (next && *next == '-' && strlen(next) == 2 &&
2334 (cmdopt = strchr("pvV", next[1])))
2336 if (*cmdopt == 'p') {
2337 uremnode(args, firstnode(args));
2338 use_defpath = 1;
2339 if (nextnode(firstnode(args)))
2340 next = (char *) getdata(nextnode(firstnode(args)));
2341 } else {
2342 hn = &commandbn.node;
2343 is_builtin = 1;
2344 break;
2347 if (!strcmp(next, "--"))
2348 uremnode(args, firstnode(args));
2350 if ((cflags & BINF_EXEC) && nextnode(firstnode(args))) {
2352 * Check for compatibility options to exec builtin.
2353 * It would be nice to do these more generically,
2354 * but currently we don't have a mechanism for
2355 * precommand modifiers.
2357 char *next = (char *) getdata(nextnode(firstnode(args)));
2358 char *cmdopt, *exec_argv0 = NULL;
2360 * Careful here: we want to make sure a final dash
2361 * is passed through in order that it still behaves
2362 * as a precommand modifier (zsh equivalent of -l).
2363 * It has to be last, but I think that's OK since
2364 * people aren't likely to mix the option style
2365 * with the zsh style.
2367 while (next && *next == '-' && strlen(next) >= 2) {
2368 uremnode(args, firstnode(args));
2369 if (!strcmp(next, "--"))
2370 break;
2371 for (cmdopt = &next[1]; *cmdopt; ++cmdopt) {
2372 switch (*cmdopt) {
2373 case 'a':
2374 /* argument is ARGV0 string */
2375 if (cmdopt[1]) {
2376 exec_argv0 = cmdopt+1;
2377 /* position on last non-NULL character */
2378 cmdopt += strlen(cmdopt+1);
2379 } else {
2380 if (!nextnode(firstnode(args))) {
2381 zerr("exec flag -a requires a parameter");
2382 errflag = lastval = 1;
2383 return;
2385 exec_argv0 = (char *)
2386 getdata(nextnode(firstnode(args)));
2387 uremnode(args, firstnode(args));
2389 break;
2390 case 'c':
2391 cflags |= BINF_CLEARENV;
2392 break;
2393 case 'l':
2394 cflags |= BINF_DASH;
2395 break;
2396 default:
2397 zerr("unknown exec flag -%c", *cmdopt);
2398 errflag = lastval = 1;
2399 return;
2402 next = (char *) getdata(nextnode(firstnode(args)));
2404 if (exec_argv0) {
2405 char *str, *s;
2406 size_t sz = strlen(exec_argv0);
2407 str = s = zalloc(5 + 1 + sz + 1);
2408 strcpy(s, "ARGV0=");
2409 s+=6;
2410 strcpy(s, exec_argv0);
2411 zputenv(str);
2414 uremnode(args, firstnode(args));
2415 hn = NULL;
2416 if ((cflags & BINF_COMMAND) && unset(POSIXBUILTINS))
2417 break;
2421 /* Do prefork substitutions */
2422 esprefork = (assign || isset(MAGICEQUALSUBST)) ? PF_TYPESET : 0;
2423 if (args && htok)
2424 prefork(args, esprefork);
2426 if (type == WC_SIMPLE) {
2427 int unglobbed = 0;
2429 for (;;) {
2430 char *cmdarg;
2432 if (!(cflags & BINF_NOGLOB))
2433 while (!checked && !errflag && args && nonempty(args) &&
2434 has_token((char *) peekfirst(args)))
2435 zglob(args, firstnode(args), 0);
2436 else if (!unglobbed) {
2437 for (node = firstnode(args); node; incnode(node))
2438 untokenize((char *) getdata(node));
2439 unglobbed = 1;
2442 /* Current shell should not fork unless the *
2443 * exec occurs at the end of a pipeline. */
2444 if ((cflags & BINF_EXEC) && last1)
2445 do_exec = 1;
2447 /* Empty command */
2448 if (!args || empty(args)) {
2449 if (redir && nonempty(redir)) {
2450 if (do_exec) {
2451 /* Was this "exec < foobar"? */
2452 nullexec = 1;
2453 break;
2454 } else if (varspc) {
2455 nullexec = 2;
2456 break;
2457 } else if (!nullcmd || !*nullcmd || opts[CSHNULLCMD] ||
2458 (cflags & BINF_PREFIX)) {
2459 zerr("redirection with no command");
2460 errflag = lastval = 1;
2461 return;
2462 } else if (!nullcmd || !*nullcmd || opts[SHNULLCMD]) {
2463 if (!args)
2464 args = newlinklist();
2465 addlinknode(args, dupstring(":"));
2466 } else if (readnullcmd && *readnullcmd &&
2467 ((Redir) peekfirst(redir))->type == REDIR_READ &&
2468 !nextnode(firstnode(redir))) {
2469 if (!args)
2470 args = newlinklist();
2471 addlinknode(args, dupstring(readnullcmd));
2472 } else {
2473 if (!args)
2474 args = newlinklist();
2475 addlinknode(args, dupstring(nullcmd));
2477 } else if ((cflags & BINF_PREFIX) && (cflags & BINF_COMMAND)) {
2478 lastval = 0;
2479 return;
2480 } else {
2481 cmdoutval = lastval;
2482 if (varspc)
2483 addvars(state, varspc, 0);
2484 if (errflag)
2485 lastval = errflag;
2486 else
2487 lastval = cmdoutval;
2488 if (isset(XTRACE)) {
2489 fputc('\n', xtrerr);
2490 fflush(xtrerr);
2492 return;
2494 } else if (isset(RESTRICTED) && (cflags & BINF_EXEC) && do_exec) {
2495 zerrnam("exec", "%s: restricted",
2496 (char *) getdata(firstnode(args)));
2497 lastval = 1;
2498 return;
2502 * Quit looking for a command if:
2503 * - there was an error; or
2504 * - we checked the simple cases needing MAGIC_EQUAL_SUBST; or
2505 * - we know we already found a builtin (because either:
2506 * - we loaded a builtin from a module, or
2507 * - we have determined there are options which would
2508 * require us to use the "command" builtin); or
2509 * - we aren't using POSIX and so BINF_COMMAND indicates a zsh
2510 * precommand modifier is being used in place of the builtin
2512 if (errflag || checked || is_builtin ||
2513 (unset(POSIXBUILTINS) && (cflags & BINF_COMMAND)))
2514 break;
2516 cmdarg = (char *) peekfirst(args);
2517 if (!(cflags & (BINF_BUILTIN | BINF_COMMAND)) &&
2518 (hn = shfunctab->getnode(shfunctab, cmdarg))) {
2519 is_shfunc = 1;
2520 break;
2522 if (!(hn = builtintab->getnode(builtintab, cmdarg))) {
2523 if (cflags & BINF_BUILTIN) {
2524 zwarn("no such builtin: %s", cmdarg);
2525 lastval = 1;
2526 if (oautocont >= 0)
2527 opts[AUTOCONTINUE] = oautocont;
2528 return;
2530 break;
2532 if (!(hn->flags & BINF_PREFIX)) {
2533 is_builtin = 1;
2535 /* autoload the builtin if necessary */
2536 if (!(hn = resolvebuiltin(cmdarg, hn)))
2537 return;
2538 break;
2540 cflags &= ~BINF_BUILTIN & ~BINF_COMMAND;
2541 cflags |= hn->flags;
2542 uremnode(args, firstnode(args));
2543 hn = NULL;
2547 if (errflag) {
2548 lastval = 1;
2549 if (oautocont >= 0)
2550 opts[AUTOCONTINUE] = oautocont;
2551 return;
2554 /* Get the text associated with this command. */
2555 if ((how & Z_ASYNC) ||
2556 (!sfcontext && !sourcelevel && (jobbing || (how & Z_TIMED))))
2557 text = getjobtext(state->prog, beg);
2558 else
2559 text = NULL;
2561 /* Set up special parameter $_ */
2563 setunderscore((args && nonempty(args)) ? ((char *) getdata(lastnode(args))) : "");
2565 /* Warn about "rm *" */
2566 if (type == WC_SIMPLE && interact && unset(RMSTARSILENT) &&
2567 isset(SHINSTDIN) && args && nonempty(args) &&
2568 nextnode(firstnode(args)) && !strcmp(peekfirst(args), "rm")) {
2569 LinkNode node, next;
2571 for (node = nextnode(firstnode(args)); node && !errflag; node = next) {
2572 char *s = (char *) getdata(node);
2573 int l = strlen(s);
2575 next = nextnode(node);
2576 if (s[0] == Star && !s[1]) {
2577 if (!checkrmall(pwd))
2578 uremnode(args, node);
2579 } else if (l > 2 && s[l - 2] == '/' && s[l - 1] == Star) {
2580 char t = s[l - 2];
2582 s[l - 2] = 0;
2583 if (!checkrmall(s))
2584 uremnode(args, node);
2585 s[l - 2] = t;
2588 if (!nextnode(firstnode(args)))
2589 errflag = 1;
2592 if (errflag) {
2593 lastval = 1;
2594 if (oautocont >= 0)
2595 opts[AUTOCONTINUE] = oautocont;
2596 return;
2599 if (type == WC_SIMPLE && !nullexec) {
2600 char *s;
2601 char trycd = (isset(AUTOCD) && isset(SHINSTDIN) &&
2602 (!redir || empty(redir)) && args && !empty(args) &&
2603 !nextnode(firstnode(args)) && *(char *)peekfirst(args));
2605 DPUTS((!args || empty(args)), "BUG: empty(args) in exec.c");
2606 if (!hn) {
2607 /* Resolve external commands */
2608 char *cmdarg = (char *) peekfirst(args);
2609 char **checkpath = pathchecked;
2610 int dohashcmd = isset(HASHCMDS);
2612 hn = cmdnamtab->getnode(cmdnamtab, cmdarg);
2613 if (hn && trycd && !isreallycom((Cmdnam)hn)) {
2614 if (!(((Cmdnam)hn)->node.flags & HASHED)) {
2615 checkpath = path;
2616 dohashcmd = 1;
2618 cmdnamtab->removenode(cmdnamtab, cmdarg);
2619 cmdnamtab->freenode(hn);
2620 hn = NULL;
2622 if (!hn && dohashcmd && strcmp(cmdarg, "..")) {
2623 for (s = cmdarg; *s && *s != '/'; s++);
2624 if (!*s)
2625 hn = (HashNode) hashcmd(cmdarg, checkpath);
2629 /* If no command found yet, see if it *
2630 * is a directory we should AUTOCD to. */
2631 if (!hn && trycd && (s = cancd(peekfirst(args)))) {
2632 peekfirst(args) = (void *) s;
2633 pushnode(args, dupstring("cd"));
2634 if ((hn = builtintab->getnode(builtintab, "cd")))
2635 is_builtin = 1;
2639 /* This is nonzero if the command is a current shell procedure? */
2640 is_cursh = (is_builtin || is_shfunc || nullexec || type >= WC_CURSH);
2642 /**************************************************************************
2643 * Do we need to fork? We need to fork if: *
2644 * 1) The command is supposed to run in the background. (or) *
2645 * 2) There is no `exec' flag, and either: *
2646 * a) This is a builtin or shell function with output piped somewhere. *
2647 * b) This is an external command and we can't do a `fake exec'. *
2649 * A `fake exec' is possible if we have all the following conditions: *
2650 * 1) last1 flag is 1. This indicates that the current shell will not *
2651 * be needed after the current command. This is typically the case *
2652 * when when the command is the last stage in a subshell, or is the *
2653 * last command after the option `-c'. *
2654 * 2) We don't have any traps set. *
2655 * 3) We don't have any files to delete. *
2657 * The condition above for a `fake exec' will also work for a current *
2658 * shell command such as a builtin, but doesn't really buy us anything *
2659 * (doesn't save us a process), since it is already running in the *
2660 * current shell. *
2661 **************************************************************************/
2663 if ((how & Z_ASYNC) ||
2664 (!do_exec &&
2665 (((is_builtin || is_shfunc) && output) ||
2666 (!is_cursh && (last1 != 1 || nsigtrapped || havefiles()))))) {
2668 pid_t pid;
2669 int synch[2], flags;
2670 char dummy;
2671 struct timeval bgtime;
2673 child_block();
2674 pipe(synch);
2676 if ((pid = zfork(&bgtime)) == -1) {
2677 close(synch[0]);
2678 close(synch[1]);
2679 if (oautocont >= 0)
2680 opts[AUTOCONTINUE] = oautocont;
2681 return;
2683 if (pid) {
2685 close(synch[1]);
2686 read(synch[0], &dummy, 1);
2687 close(synch[0]);
2688 #ifdef PATH_DEV_FD
2689 closem(FDT_PROC_SUBST);
2690 #endif
2691 if (how & Z_ASYNC) {
2692 lastpid = (zlong) pid;
2693 } else if (!jobtab[thisjob].stty_in_env && varspc) {
2694 /* search for STTY=... */
2695 Wordcode p = varspc;
2696 wordcode ac;
2698 while (wc_code(ac = *p) == WC_ASSIGN) {
2699 if (!strcmp(ecrawstr(state->prog, p + 1, NULL), "STTY")) {
2700 jobtab[thisjob].stty_in_env = 1;
2701 break;
2703 p += (WC_ASSIGN_TYPE(ac) == WC_ASSIGN_SCALAR ?
2704 3 : WC_ASSIGN_NUM(ac) + 2);
2707 addproc(pid, text, 0, &bgtime);
2708 if (oautocont >= 0)
2709 opts[AUTOCONTINUE] = oautocont;
2710 return;
2712 /* pid == 0 */
2713 close(synch[0]);
2714 flags = ((how & Z_ASYNC) ? ESUB_ASYNC : 0) | ESUB_PGRP;
2715 if ((type != WC_SUBSH) && !(how & Z_ASYNC))
2716 flags |= ESUB_KEEPTRAP;
2717 entersubsh(flags);
2718 close(synch[1]);
2719 forked = 1;
2720 if (sigtrapped[SIGINT] & ZSIG_IGNORED)
2721 holdintr();
2722 #ifdef HAVE_NICE
2723 /* Check if we should run background jobs at a lower priority. */
2724 if ((how & Z_ASYNC) && isset(BGNICE))
2725 if (nice(5) < 0)
2726 zwarn("nice(5) failed: %e", errno);
2727 #endif /* HAVE_NICE */
2729 } else if (is_cursh) {
2730 /* This is a current shell procedure that didn't need to fork. *
2731 * This includes current shell procedures that are being exec'ed, *
2732 * as well as null execs. */
2733 jobtab[thisjob].stat |= STAT_CURSH|STAT_NOPRINT;
2734 } else {
2735 /* This is an exec (real or fake) for an external command. *
2736 * Note that any form of exec means that the subshell is fake *
2737 * (but we may be in a subshell already). */
2738 is_exec = 1;
2741 if ((esglob = !(cflags & BINF_NOGLOB)) && args && htok) {
2742 LinkList oargs = args;
2743 globlist(args, 0);
2744 args = oargs;
2746 if (errflag) {
2747 lastval = 1;
2748 goto err;
2751 /* Make a copy of stderr for xtrace output before redirecting */
2752 fflush(xtrerr);
2753 if (isset(XTRACE) && xtrerr == stderr &&
2754 (type < WC_SUBSH || type == WC_TIMED)) {
2755 if ((newxtrerr = fdopen(movefd(dup(fileno(stderr))), "w"))) {
2756 xtrerr = newxtrerr;
2757 fdtable[fileno(xtrerr)] = FDT_XTRACE;
2761 /* Add pipeline input/output to mnodes */
2762 if (input)
2763 addfd(forked, save, mfds, 0, input, 0, NULL);
2764 if (output)
2765 addfd(forked, save, mfds, 1, output, 1, NULL);
2767 /* Do process substitutions */
2768 if (redir)
2769 spawnpipes(redir, nullexec);
2771 /* Do io redirections */
2772 while (redir && nonempty(redir)) {
2773 fn = (Redir) ugetnode(redir);
2775 DPUTS(fn->type == REDIR_HEREDOC || fn->type == REDIR_HEREDOCDASH,
2776 "BUG: unexpanded here document");
2777 if (fn->type == REDIR_INPIPE) {
2778 if (!checkclobberparam(fn) || fn->fd2 == -1) {
2779 if (fn->fd2 != -1)
2780 zclose(fn->fd2);
2781 closemnodes(mfds);
2782 fixfds(save);
2783 execerr();
2785 addfd(forked, save, mfds, fn->fd1, fn->fd2, 0, fn->varid);
2786 } else if (fn->type == REDIR_OUTPIPE) {
2787 if (!checkclobberparam(fn) || fn->fd2 == -1) {
2788 if (fn->fd2 != -1)
2789 zclose(fn->fd2);
2790 closemnodes(mfds);
2791 fixfds(save);
2792 execerr();
2794 addfd(forked, save, mfds, fn->fd1, fn->fd2, 1, fn->varid);
2795 } else {
2796 if (fn->type != REDIR_HERESTR && xpandredir(fn, redir))
2797 continue;
2798 if (errflag) {
2799 closemnodes(mfds);
2800 fixfds(save);
2801 execerr();
2803 if (isset(RESTRICTED) && IS_WRITE_FILE(fn->type)) {
2804 zwarn("writing redirection not allowed in restricted mode");
2805 execerr();
2807 if (unset(EXECOPT))
2808 continue;
2809 switch(fn->type) {
2810 case REDIR_HERESTR:
2811 if (!checkclobberparam(fn))
2812 fil = -1;
2813 else
2814 fil = getherestr(fn);
2815 if (fil == -1) {
2816 if (errno && errno != EINTR)
2817 zwarn("can't create temp file for here document: %e",
2818 errno);
2819 closemnodes(mfds);
2820 fixfds(save);
2821 execerr();
2823 addfd(forked, save, mfds, fn->fd1, fil, 0, fn->varid);
2824 break;
2825 case REDIR_READ:
2826 case REDIR_READWRITE:
2827 if (!checkclobberparam(fn))
2828 fil = -1;
2829 else if (fn->type == REDIR_READ)
2830 fil = open(unmeta(fn->name), O_RDONLY | O_NOCTTY);
2831 else
2832 fil = open(unmeta(fn->name),
2833 O_RDWR | O_CREAT | O_NOCTTY, 0666);
2834 if (fil == -1) {
2835 closemnodes(mfds);
2836 fixfds(save);
2837 if (errno != EINTR)
2838 zwarn("%e: %s", errno, fn->name);
2839 execerr();
2841 addfd(forked, save, mfds, fn->fd1, fil, 0, fn->varid);
2842 /* If this is 'exec < file', read from stdin, *
2843 * not terminal, unless `file' is a terminal. */
2844 if (nullexec == 1 && fn->fd1 == 0 &&
2845 isset(SHINSTDIN) && interact && !zleactive)
2846 init_io();
2847 break;
2848 case REDIR_CLOSE:
2849 if (fn->varid) {
2850 char *s = fn->varid;
2851 struct value vbuf;
2852 Value v;
2853 int bad = 0;
2855 if (!(v = getvalue(&vbuf, &s, 0))) {
2856 bad = 1;
2857 } else if (v->pm->node.flags & PM_READONLY) {
2858 bad = 2;
2859 } else {
2860 fn->fd1 = (int)getintvalue(v);
2861 if (errflag)
2862 bad = 1;
2863 else if (fn->fd1 > max_zsh_fd)
2864 bad = 3;
2865 else if (fn->fd1 >= 10 &&
2866 fdtable[fn->fd1] == FDT_INTERNAL)
2867 bad = 4;
2869 if (bad) {
2870 const char *bad_msg[] = {
2871 "parameter %s does not contain a file descriptor",
2872 "can't close file descriptor from readonly parameter %s",
2873 "file descriptor %d out of range, not closed",
2874 "file descriptor %d used by shell, not closed"
2876 if (bad > 2)
2877 zwarn(bad_msg[bad-1], fn->fd1);
2878 else
2879 zwarn(bad_msg[bad-1], fn->varid);
2880 execerr();
2883 if (!forked && fn->fd1 < 10 && save[fn->fd1] == -2)
2884 save[fn->fd1] = movefd(fn->fd1);
2885 if (fn->fd1 < 10)
2886 closemn(mfds, fn->fd1);
2887 zclose(fn->fd1);
2888 break;
2889 case REDIR_MERGEIN:
2890 case REDIR_MERGEOUT:
2891 if (fn->fd2 < 10)
2892 closemn(mfds, fn->fd2);
2893 if (!checkclobberparam(fn))
2894 fil = -1;
2895 else if (fn->fd2 > 9 &&
2896 ((fdtable[fn->fd2] != FDT_UNUSED &&
2897 fdtable[fn->fd2] != FDT_EXTERNAL) ||
2898 fn->fd2 == coprocin ||
2899 fn->fd2 == coprocout)) {
2900 fil = -1;
2901 errno = EBADF;
2902 } else {
2903 int fd = fn->fd2;
2904 if(fd == -2)
2905 fd = (fn->type == REDIR_MERGEOUT) ? coprocout : coprocin;
2906 fil = dup(fd);
2908 if (fil == -1) {
2909 char fdstr[4];
2911 closemnodes(mfds);
2912 fixfds(save);
2913 if (fn->fd2 != -2)
2914 sprintf(fdstr, "%d", fn->fd2);
2915 if (errno)
2916 zwarn("%s: %e", fn->fd2 == -2 ? "coprocess" : fdstr,
2917 errno);
2918 execerr();
2920 addfd(forked, save, mfds, fn->fd1, fil,
2921 fn->type == REDIR_MERGEOUT, fn->varid);
2922 break;
2923 default:
2924 if (!checkclobberparam(fn))
2925 fil = -1;
2926 else if (IS_APPEND_REDIR(fn->type))
2927 fil = open(unmeta(fn->name),
2928 (unset(CLOBBER) && !IS_CLOBBER_REDIR(fn->type)) ?
2929 O_WRONLY | O_APPEND | O_NOCTTY :
2930 O_WRONLY | O_APPEND | O_CREAT | O_NOCTTY, 0666);
2931 else
2932 fil = clobber_open(fn);
2933 if(fil != -1 && IS_ERROR_REDIR(fn->type))
2934 dfil = dup(fil);
2935 else
2936 dfil = 0;
2937 if (fil == -1 || dfil == -1) {
2938 if(fil != -1)
2939 close(fil);
2940 closemnodes(mfds);
2941 fixfds(save);
2942 if (errno && errno != EINTR)
2943 zwarn("%e: %s", errno, fn->name);
2944 execerr();
2946 addfd(forked, save, mfds, fn->fd1, fil, 1, fn->varid);
2947 if(IS_ERROR_REDIR(fn->type))
2948 addfd(forked, save, mfds, 2, dfil, 1, NULL);
2949 break;
2951 /* May be error in addfd due to setting parameter. */
2952 if (errflag) {
2953 closemnodes(mfds);
2954 fixfds(save);
2955 execerr();
2960 /* We are done with redirection. close the mnodes, *
2961 * spawning tee/cat processes as necessary. */
2962 for (i = 0; i < 10; i++)
2963 if (mfds[i] && mfds[i]->ct >= 2)
2964 closemn(mfds, i);
2966 xtrerr = stderr;
2967 if (nullexec) {
2968 if (nullexec == 1) {
2970 * If nullexec is 1 we specifically *don't* restore the original
2971 * fd's before returning.
2973 for (i = 0; i < 10; i++)
2974 if (save[i] != -2)
2975 zclose(save[i]);
2976 goto done;
2979 * If nullexec is 2, we have variables to add with the redirections
2980 * in place.
2982 if (varspc)
2983 addvars(state, varspc, 0);
2984 lastval = errflag ? errflag : cmdoutval;
2985 if (isset(XTRACE)) {
2986 fputc('\n', xtrerr);
2987 fflush(xtrerr);
2989 } else if (isset(EXECOPT) && !errflag) {
2991 * We delay the entersubsh() to here when we are exec'ing
2992 * the current shell (including a fake exec to run a builtin then
2993 * exit) in case there is an error return.
2995 if (is_exec) {
2996 int flags = ((how & Z_ASYNC) ? ESUB_ASYNC : 0) |
2997 ESUB_PGRP | ESUB_FAKE;
2998 if (type != WC_SUBSH)
2999 flags |= ESUB_KEEPTRAP;
3000 if ((do_exec || (type >= WC_CURSH && last1 == 1))
3001 && !forked)
3002 flags |= ESUB_REVERTPGRP;
3003 entersubsh(flags);
3005 if (type >= WC_CURSH) {
3006 if (last1 == 1)
3007 do_exec = 1;
3008 lastval = (execfuncs[type - WC_CURSH])(state, do_exec);
3009 } else if (is_builtin || is_shfunc) {
3010 LinkList restorelist = 0, removelist = 0;
3011 /* builtin or shell function */
3013 if (!forked && ((cflags & BINF_COMMAND) ||
3014 (unset(POSIXBUILTINS) && !assign) ||
3015 (isset(POSIXBUILTINS) && !is_shfunc &&
3016 !(hn->flags & BINF_PSPECIAL)))) {
3017 if (varspc)
3018 save_params(state, varspc, &restorelist, &removelist);
3019 else
3020 restorelist = removelist = NULL;
3022 if (varspc) {
3023 /* Export this if the command is a shell function,
3024 * but not if it's a builtin.
3026 int flags = 0;
3027 if (is_shfunc)
3028 flags |= ADDVAR_EXPORT;
3029 if (restorelist)
3030 flags |= ADDVAR_RESTORE;
3032 addvars(state, varspc, flags);
3033 if (errflag) {
3034 if (restorelist)
3035 restore_params(restorelist, removelist);
3036 lastval = 1;
3037 fixfds(save);
3038 goto done;
3042 if (is_shfunc) {
3043 /* It's a shell function */
3045 #ifdef PATH_DEV_FD
3046 int i;
3048 for (i = 10; i <= max_zsh_fd; i++)
3049 if (fdtable[i] >= FDT_PROC_SUBST)
3050 fdtable[i]++;
3051 #endif
3052 if (subsh_close >= 0)
3053 zclose(subsh_close);
3054 subsh_close = -1;
3056 execshfunc((Shfunc) hn, args);
3057 #ifdef PATH_DEV_FD
3058 for (i = 10; i <= max_zsh_fd; i++)
3059 if (fdtable[i] >= FDT_PROC_SUBST)
3060 if (--(fdtable[i]) <= FDT_PROC_SUBST)
3061 zclose(i);
3062 #endif
3063 } else {
3064 /* It's a builtin */
3065 if (forked)
3066 closem(FDT_INTERNAL);
3067 lastval = execbuiltin(args, (Builtin) hn);
3068 #ifdef PATH_DEV_FD
3069 closem(FDT_PROC_SUBST);
3070 #endif
3071 fflush(stdout);
3072 if (save[1] == -2) {
3073 if (ferror(stdout)) {
3074 zwarn("write error: %e", errno);
3075 clearerr(stdout);
3077 } else
3078 clearerr(stdout);
3080 if (isset(PRINTEXITVALUE) && isset(SHINSTDIN) &&
3081 lastval && !subsh) {
3082 fprintf(stderr, "zsh: exit %ld\n", (long)lastval);
3085 if (do_exec) {
3086 if (subsh)
3087 _exit(lastval);
3089 /* If we are exec'ing a command, and we are not in a subshell, *
3090 * then check if we should save the history file. */
3091 if (isset(RCS) && interact && !nohistsave)
3092 savehistfile(NULL, 1, HFILE_USE_OPTIONS);
3093 exit(lastval);
3095 if (restorelist)
3096 restore_params(restorelist, removelist);
3098 } else {
3099 if (!forked)
3100 setiparam("SHLVL", --shlvl);
3101 if (do_exec) {
3102 /* If we are exec'ing a command, and we are not *
3103 * in a subshell, then save the history file. */
3104 if (!subsh && isset(RCS) && interact && !nohistsave)
3105 savehistfile(NULL, 1, HFILE_USE_OPTIONS);
3107 if (type == WC_SIMPLE) {
3108 if (varspc) {
3109 addvars(state, varspc, ADDVAR_EXPORT|ADDVAR_RESTRICT);
3110 if (errflag)
3111 _exit(1);
3113 closem(FDT_INTERNAL);
3114 if (coprocin)
3115 zclose(coprocin);
3116 if (coprocout)
3117 zclose(coprocout);
3118 #ifdef HAVE_GETRLIMIT
3119 if (!forked)
3120 setlimits(NULL);
3121 #endif
3122 if (how & Z_ASYNC) {
3123 zsfree(STTYval);
3124 STTYval = 0;
3126 execute(args, cflags, use_defpath);
3127 } else { /* ( ... ) */
3128 DPUTS(varspc,
3129 "BUG: assignment before complex command");
3130 list_pipe = 0;
3131 if (subsh_close >= 0)
3132 zclose(subsh_close);
3133 subsh_close = -1;
3134 /* If we're forked (and we should be), no need to return */
3135 DPUTS(last1 != 1 && !forked, "BUG: not exiting?");
3136 DPUTS(type != WC_SUBSH, "Not sure what we're doing.");
3137 /* Skip word only used for try/always blocks */
3138 state->pc++;
3139 execlist(state, 0, 1);
3144 err:
3145 if (forked) {
3147 * So what's going on here then? Well, I'm glad you asked.
3149 * If we create multios for use in a subshell we do
3150 * this after forking, in this function above. That
3151 * means that the current (sub)process is responsible
3152 * for clearing them up. However, the processes won't
3153 * go away until we have closed the fd's talking to them.
3154 * Since we're about to exit the shell there's nothing
3155 * to stop us closing all fd's (including the ones 0 to 9
3156 * that we usually leave alone).
3158 * Then we wait for any processes. When we forked,
3159 * we cleared the jobtable and started a new job just for
3160 * any oddments like this, so if there aren't any we won't
3161 * need to wait. The result of not waiting is that
3162 * the multios haven't flushed the fd's properly, leading
3163 * to obscure missing data.
3165 * It would probably be cleaner to ensure that the
3166 * parent shell handled multios, but that requires
3167 * some architectural changes which are likely to be
3168 * hairy.
3170 for (i = 0; i < 10; i++)
3171 if (fdtable[i] != FDT_UNUSED)
3172 close(i);
3173 closem(FDT_UNUSED);
3174 if (thisjob != -1)
3175 waitjobs();
3176 _exit(lastval);
3178 fixfds(save);
3180 done:
3181 if (newxtrerr) {
3182 fil = fileno(newxtrerr);
3183 fclose(newxtrerr);
3184 xtrerr = oxtrerr;
3185 zclose(fil);
3188 zsfree(STTYval);
3189 STTYval = 0;
3190 if (oautocont >= 0)
3191 opts[AUTOCONTINUE] = oautocont;
3194 /* Arrange to have variables restored. */
3196 /**/
3197 static void
3198 save_params(Estate state, Wordcode pc, LinkList *restore_p, LinkList *remove_p)
3200 Param pm;
3201 char *s;
3202 wordcode ac;
3204 *restore_p = newlinklist();
3205 *remove_p = newlinklist();
3207 while (wc_code(ac = *pc) == WC_ASSIGN) {
3208 s = ecrawstr(state->prog, pc + 1, NULL);
3209 if ((pm = (Param) paramtab->getnode(paramtab, s))) {
3210 if (pm->env)
3211 delenv(pm);
3212 if (!(pm->node.flags & PM_SPECIAL)) {
3213 paramtab->removenode(paramtab, s);
3214 } else if (!(pm->node.flags & PM_READONLY) &&
3215 (unset(RESTRICTED) || !(pm->node.flags & PM_RESTRICTED))) {
3216 Param tpm = (Param) hcalloc(sizeof *tpm);
3217 tpm->node.nam = pm->node.nam;
3218 copyparam(tpm, pm, 1);
3219 pm = tpm;
3221 addlinknode(*remove_p, dupstring(s));
3222 addlinknode(*restore_p, pm);
3223 } else
3224 addlinknode(*remove_p, dupstring(s));
3226 pc += (WC_ASSIGN_TYPE(ac) == WC_ASSIGN_SCALAR ?
3227 3 : WC_ASSIGN_NUM(ac) + 2);
3231 /* Restore saved parameters after executing a shfunc or builtin */
3233 /**/
3234 static void
3235 restore_params(LinkList restorelist, LinkList removelist)
3237 Param pm;
3238 char *s;
3240 /* remove temporary parameters */
3241 while ((s = (char *) ugetnode(removelist))) {
3242 if ((pm = (Param) paramtab->getnode(paramtab, s)) &&
3243 !(pm->node.flags & PM_SPECIAL)) {
3244 pm->node.flags &= ~PM_READONLY;
3245 unsetparam_pm(pm, 0, 0);
3249 if (restorelist) {
3250 /* restore saved parameters */
3251 while ((pm = (Param) ugetnode(restorelist))) {
3252 if (pm->node.flags & PM_SPECIAL) {
3253 Param tpm = (Param) paramtab->getnode(paramtab, pm->node.nam);
3255 DPUTS(!tpm || PM_TYPE(pm->node.flags) != PM_TYPE(tpm->node.flags) ||
3256 !(pm->node.flags & PM_SPECIAL),
3257 "BUG: in restoring special parameters");
3258 if (!pm->env && tpm->env)
3259 delenv(tpm);
3260 tpm->node.flags = pm->node.flags;
3261 switch (PM_TYPE(pm->node.flags)) {
3262 case PM_SCALAR:
3263 tpm->gsu.s->setfn(tpm, pm->u.str);
3264 break;
3265 case PM_INTEGER:
3266 tpm->gsu.i->setfn(tpm, pm->u.val);
3267 break;
3268 case PM_EFLOAT:
3269 case PM_FFLOAT:
3270 tpm->gsu.f->setfn(tpm, pm->u.dval);
3271 break;
3272 case PM_ARRAY:
3273 tpm->gsu.a->setfn(tpm, pm->u.arr);
3274 break;
3275 case PM_HASHED:
3276 tpm->gsu.h->setfn(tpm, pm->u.hash);
3277 break;
3279 pm = tpm;
3280 } else
3281 paramtab->addnode(paramtab, pm->node.nam, pm);
3282 if ((pm->node.flags & PM_EXPORTED) && ((s = getsparam(pm->node.nam))))
3283 addenv(pm, s);
3288 /* restore fds after redirecting a builtin */
3290 /**/
3291 static void
3292 fixfds(int *save)
3294 int old_errno = errno;
3295 int i;
3297 for (i = 0; i != 10; i++)
3298 if (save[i] != -2)
3299 redup(save[i], i);
3300 errno = old_errno;
3304 * Close internal shell fds.
3306 * Close any that are marked as used if "how" is FDT_UNUSED, else
3307 * close any with the value "how".
3310 /**/
3311 mod_export void
3312 closem(int how)
3314 int i;
3316 for (i = 10; i <= max_zsh_fd; i++)
3317 if (fdtable[i] != FDT_UNUSED &&
3318 (how == FDT_UNUSED || fdtable[i] == how))
3319 zclose(i);
3322 /* convert here document into a here string */
3324 /**/
3325 char *
3326 gethere(char *str, int typ)
3328 char *buf;
3329 int bsiz, qt = 0, strip = 0;
3330 char *s, *t, *bptr, c;
3332 for (s = str; *s; s++)
3333 if (inull(*s)) {
3334 qt = 1;
3335 break;
3337 str = quotesubst(str);
3338 untokenize(str);
3339 if (typ == REDIR_HEREDOCDASH) {
3340 strip = 1;
3341 while (*str == '\t')
3342 str++;
3344 bptr = buf = zalloc(bsiz = 256);
3345 for (;;) {
3346 t = bptr;
3348 while ((c = hgetc()) == '\t' && strip)
3350 for (;;) {
3351 if (bptr == buf + bsiz) {
3352 char *newbuf = realloc(buf, 2 * bsiz);
3353 if (!newbuf) {
3354 /* out of memory */
3355 zfree(buf, bsiz);
3356 return NULL;
3358 buf = newbuf;
3359 t = buf + bsiz - (bptr - t);
3360 bptr = buf + bsiz;
3361 bsiz *= 2;
3363 if (lexstop || c == '\n')
3364 break;
3365 *bptr++ = c;
3366 c = hgetc();
3368 *bptr = '\0';
3369 if (!strcmp(t, str))
3370 break;
3371 if (lexstop) {
3372 t = bptr;
3373 break;
3375 *bptr++ = '\n';
3377 if (t > buf && t[-1] == '\n')
3378 t--;
3379 *t = '\0';
3380 if (!qt) {
3381 int ef = errflag;
3383 parsestr(buf);
3385 if (!errflag)
3386 errflag = ef;
3388 s = dupstring(buf);
3389 zfree(buf, bsiz);
3390 return s;
3393 /* open here string fd */
3395 /**/
3396 static int
3397 getherestr(struct redir *fn)
3399 char *s, *t;
3400 int fd, len;
3402 t = fn->name;
3403 singsub(&t);
3404 untokenize(t);
3405 unmetafy(t, &len);
3406 t[len++] = '\n';
3407 if ((fd = gettempfile(NULL, 1, &s)) < 0)
3408 return -1;
3409 write(fd, t, len);
3410 close(fd);
3411 fd = open(s, O_RDONLY | O_NOCTTY);
3412 unlink(s);
3413 return fd;
3417 * Test if some wordcode starts with a simple redirection of type
3418 * redir_type. If it does, return the name of the file, copied onto
3419 * the heap. If it doesn't, return NULL.
3422 static char *
3423 simple_redir_name(Eprog prog, int redir_type)
3425 Wordcode pc;
3427 pc = prog->prog;
3428 if (prog != &dummy_eprog &&
3429 wc_code(pc[0]) == WC_LIST && (WC_LIST_TYPE(pc[0]) & Z_END) &&
3430 wc_code(pc[1]) == WC_SUBLIST && !WC_SUBLIST_FLAGS(pc[1]) &&
3431 WC_SUBLIST_TYPE(pc[1]) == WC_SUBLIST_END &&
3432 wc_code(pc[2]) == WC_PIPE && WC_PIPE_TYPE(pc[2]) == WC_PIPE_END &&
3433 wc_code(pc[3]) == WC_REDIR && WC_REDIR_TYPE(pc[3]) == redir_type &&
3434 !WC_REDIR_VARID(pc[3]) &&
3435 !pc[4] &&
3436 wc_code(pc[6]) == WC_SIMPLE && !WC_SIMPLE_ARGC(pc[6])) {
3437 return dupstring(ecrawstr(prog, pc + 5, NULL));
3440 return NULL;
3443 /* $(...) */
3445 /**/
3446 LinkList
3447 getoutput(char *cmd, int qt)
3449 Eprog prog;
3450 int pipes[2];
3451 pid_t pid;
3452 char *s;
3454 if (!(prog = parse_string(cmd, 0)))
3455 return NULL;
3457 if ((s = simple_redir_name(prog, REDIR_READ))) {
3458 /* $(< word) */
3459 int stream;
3461 singsub(&s);
3462 if (errflag)
3463 return NULL;
3464 untokenize(s);
3465 if ((stream = open(unmeta(s), O_RDONLY | O_NOCTTY)) == -1) {
3466 zerr("%e: %s", errno, s);
3467 return NULL;
3469 return readoutput(stream, qt);
3471 mpipe(pipes);
3472 child_block();
3473 cmdoutval = 0;
3474 if ((cmdoutpid = pid = zfork(NULL)) == -1) {
3475 /* fork error */
3476 zclose(pipes[0]);
3477 zclose(pipes[1]);
3478 errflag = 1;
3479 cmdoutpid = 0;
3480 child_unblock();
3481 return NULL;
3482 } else if (pid) {
3483 LinkList retval;
3485 zclose(pipes[1]);
3486 retval = readoutput(pipes[0], qt);
3487 fdtable[pipes[0]] = FDT_UNUSED;
3488 waitforpid(pid, 0); /* unblocks */
3489 lastval = cmdoutval;
3490 return retval;
3492 /* pid == 0 */
3493 child_unblock();
3494 zclose(pipes[0]);
3495 redup(pipes[1], 1);
3496 entersubsh(ESUB_PGRP|ESUB_NOMONITOR);
3497 cmdpush(CS_CMDSUBST);
3498 execode(prog, 0, 1);
3499 cmdpop();
3500 close(1);
3501 _exit(lastval);
3502 zerr("exit returned in child!!");
3503 kill(getpid(), SIGKILL);
3504 return NULL;
3507 /* read output of command substitution */
3509 /**/
3510 mod_export LinkList
3511 readoutput(int in, int qt)
3513 LinkList ret;
3514 char *buf, *ptr;
3515 int bsiz, c, cnt = 0;
3516 FILE *fin;
3518 fin = fdopen(in, "r");
3519 ret = newlinklist();
3520 ptr = buf = (char *) hcalloc(bsiz = 64);
3521 while ((c = fgetc(fin)) != EOF || errno == EINTR) {
3522 if (c == EOF) {
3523 errno = 0;
3524 clearerr(fin);
3525 continue;
3527 if (imeta(c)) {
3528 *ptr++ = Meta;
3529 c ^= 32;
3530 cnt++;
3532 if (++cnt >= bsiz) {
3533 char *pp = (char *) hcalloc(bsiz *= 2);
3535 memcpy(pp, buf, cnt - 1);
3536 ptr = (buf = pp) + cnt - 1;
3538 *ptr++ = c;
3540 fclose(fin);
3541 while (cnt && ptr[-1] == '\n')
3542 ptr--, cnt--;
3543 *ptr = '\0';
3544 if (qt) {
3545 if (!cnt) {
3546 *ptr++ = Nularg;
3547 *ptr = '\0';
3549 addlinknode(ret, buf);
3550 } else {
3551 char **words = spacesplit(buf, 0, 1, 0);
3553 while (*words) {
3554 if (isset(GLOBSUBST))
3555 shtokenize(*words);
3556 addlinknode(ret, *words++);
3559 return ret;
3562 /**/
3563 static Eprog
3564 parsecmd(char *cmd, char **eptr)
3566 char *str;
3567 Eprog prog;
3569 for (str = cmd + 2; *str && *str != Outpar; str++);
3570 if (!*str || cmd[1] != Inpar) {
3571 zerr("oops.");
3572 return NULL;
3574 *str = '\0';
3575 if (eptr)
3576 *eptr = str+1;
3577 if (!(prog = parse_string(cmd + 2, 0))) {
3578 zerr("parse error in process substitution");
3579 return NULL;
3581 return prog;
3584 /* =(...) */
3586 /**/
3587 char *
3588 getoutputfile(char *cmd, char **eptr)
3590 pid_t pid;
3591 char *nam;
3592 Eprog prog;
3593 int fd;
3594 char *s;
3596 if (thisjob == -1)
3597 return NULL;
3598 if (!(prog = parsecmd(cmd, eptr)))
3599 return NULL;
3600 if (!(nam = gettempname(NULL, 0)))
3601 return NULL;
3603 if ((s = simple_redir_name(prog, REDIR_HERESTR))) {
3605 * =(<<<stuff). Optimise a la $(<file). It's
3606 * effectively the reverse, converting a string into a file name
3607 * rather than vice versa.
3609 singsub(&s);
3610 if (errflag)
3611 s = NULL;
3612 else
3613 untokenize(s);
3616 if (!jobtab[thisjob].filelist)
3617 jobtab[thisjob].filelist = znewlinklist();
3618 zaddlinknode(jobtab[thisjob].filelist, nam);
3620 if (!s)
3621 child_block();
3622 fd = open(nam, O_WRONLY | O_CREAT | O_EXCL | O_NOCTTY, 0600);
3624 if (s) {
3625 /* optimised here-string */
3626 int len;
3627 unmetafy(s, &len);
3628 write(fd, s, len);
3629 close(fd);
3630 return nam;
3633 if (fd < 0 || (cmdoutpid = pid = zfork(NULL)) == -1) {
3634 /* fork or open error */
3635 child_unblock();
3636 return nam;
3637 } else if (pid) {
3638 int os;
3640 close(fd);
3641 os = jobtab[thisjob].stat;
3642 waitforpid(pid, 0);
3643 cmdoutval = 0;
3644 jobtab[thisjob].stat = os;
3645 return nam;
3648 /* pid == 0 */
3649 redup(fd, 1);
3650 entersubsh(ESUB_PGRP|ESUB_NOMONITOR);
3651 cmdpush(CS_CMDSUBST);
3652 execode(prog, 0, 1);
3653 cmdpop();
3654 close(1);
3655 _exit(lastval);
3656 zerr("exit returned in child!!");
3657 kill(getpid(), SIGKILL);
3658 return NULL;
3661 #if !defined(PATH_DEV_FD) && defined(HAVE_FIFOS)
3662 /* get a temporary named pipe */
3664 static char *
3665 namedpipe(void)
3667 char *tnam = gettempname(NULL, 1);
3669 # ifdef HAVE_MKFIFO
3670 if (mkfifo(tnam, 0600) < 0)
3671 # else
3672 if (mknod(tnam, 0010600, 0) < 0)
3673 # endif
3674 return NULL;
3675 return tnam;
3677 #endif /* ! PATH_DEV_FD && HAVE_FIFOS */
3679 /* <(...) or >(...) */
3681 /**/
3682 char *
3683 getproc(char *cmd, char **eptr)
3685 #if !defined(HAVE_FIFOS) && !defined(PATH_DEV_FD)
3686 zerr("doesn't look like your system supports FIFOs.");
3687 return NULL;
3688 #else
3689 Eprog prog;
3690 int out = *cmd == Inang;
3691 char *pnam;
3692 pid_t pid;
3693 struct timeval bgtime;
3695 #ifndef PATH_DEV_FD
3696 int fd;
3698 if (thisjob == -1)
3699 return NULL;
3700 if (!(pnam = namedpipe()))
3701 return NULL;
3702 if (!(prog = parsecmd(cmd, eptr)))
3703 return NULL;
3704 if (!jobtab[thisjob].filelist)
3705 jobtab[thisjob].filelist = znewlinklist();
3706 zaddlinknode(jobtab[thisjob].filelist, ztrdup(pnam));
3708 if ((pid = zfork(&bgtime))) {
3709 if (pid == -1)
3710 return NULL;
3711 if (!out)
3712 addproc(pid, NULL, 1, &bgtime);
3713 return pnam;
3715 closem(FDT_UNUSED);
3716 fd = open(pnam, out ? O_WRONLY | O_NOCTTY : O_RDONLY | O_NOCTTY);
3717 if (fd == -1) {
3718 zerr("can't open %s: %e", pnam, errno);
3719 _exit(1);
3721 entersubsh(ESUB_ASYNC|ESUB_PGRP);
3722 redup(fd, out);
3723 #else /* PATH_DEV_FD */
3724 int pipes[2];
3726 if (thisjob == -1)
3727 return NULL;
3728 pnam = hcalloc(strlen(PATH_DEV_FD) + 6);
3729 if (!(prog = parsecmd(cmd, eptr)))
3730 return NULL;
3731 mpipe(pipes);
3732 if ((pid = zfork(&bgtime))) {
3733 sprintf(pnam, "%s/%d", PATH_DEV_FD, pipes[!out]);
3734 zclose(pipes[out]);
3735 if (pid == -1)
3737 zclose(pipes[!out]);
3738 return NULL;
3740 fdtable[pipes[!out]] = FDT_PROC_SUBST;
3741 if (!out)
3743 addproc(pid, NULL, 1, &bgtime);
3745 return pnam;
3747 entersubsh(ESUB_ASYNC|ESUB_PGRP);
3748 redup(pipes[out], out);
3749 closem(FDT_UNUSED); /* this closes pipes[!out] as well */
3750 #endif /* PATH_DEV_FD */
3752 cmdpush(CS_CMDSUBST);
3753 execode(prog, 0, 1);
3754 cmdpop();
3755 zclose(out);
3756 _exit(lastval);
3757 return NULL;
3758 #endif /* HAVE_FIFOS and PATH_DEV_FD not defined */
3762 * > >(...) or < <(...) (does not use named pipes)
3764 * If the second argument is 1, this is part of
3765 * an "exec < <(...)" or "exec > >(...)" and we shouldn't
3766 * wait for the job to finish before continuing.
3769 /**/
3770 static int
3771 getpipe(char *cmd, int nullexec)
3773 Eprog prog;
3774 int pipes[2], out = *cmd == Inang;
3775 pid_t pid;
3776 struct timeval bgtime;
3777 char *ends;
3779 if (!(prog = parsecmd(cmd, &ends)))
3780 return -1;
3781 if (*ends) {
3782 zerr("invalid syntax for process substitution in redirection");
3783 return -1;
3785 mpipe(pipes);
3786 if ((pid = zfork(&bgtime))) {
3787 zclose(pipes[out]);
3788 if (pid == -1) {
3789 zclose(pipes[!out]);
3790 return -1;
3792 if (!nullexec)
3793 addproc(pid, NULL, 1, &bgtime);
3794 return pipes[!out];
3796 entersubsh(ESUB_ASYNC|ESUB_PGRP);
3797 redup(pipes[out], out);
3798 closem(FDT_UNUSED); /* this closes pipes[!out] as well */
3799 cmdpush(CS_CMDSUBST);
3800 execode(prog, 0, 1);
3801 cmdpop();
3802 _exit(lastval);
3803 return 0;
3806 /* open pipes with fds >= 10 */
3808 /**/
3809 static void
3810 mpipe(int *pp)
3812 pipe(pp);
3813 pp[0] = movefd(pp[0]);
3814 pp[1] = movefd(pp[1]);
3818 * Do process substitution with redirection
3820 * If the second argument is 1, this is part of
3821 * an "exec < <(...)" or "exec > >(...)" and we shouldn't
3822 * wait for the job to finish before continuing.
3823 * Likewise, we shouldn't wait if we are opening the file
3824 * descriptor using the {fd}>>(...) notation since it stays
3825 * valid for subsequent commands.
3828 /**/
3829 static void
3830 spawnpipes(LinkList l, int nullexec)
3832 LinkNode n;
3833 Redir f;
3834 char *str;
3836 n = firstnode(l);
3837 for (; n; incnode(n)) {
3838 f = (Redir) getdata(n);
3839 if (f->type == REDIR_OUTPIPE || f->type == REDIR_INPIPE) {
3840 str = f->name;
3841 f->fd2 = getpipe(str, nullexec || f->varid);
3846 extern int tracingcond;
3848 /* evaluate a [[ ... ]] */
3850 /**/
3851 static int
3852 execcond(Estate state, UNUSED(int do_exec))
3854 int stat;
3856 state->pc--;
3857 if (isset(XTRACE)) {
3858 printprompt4();
3859 fprintf(xtrerr, "[[");
3860 tracingcond++;
3862 cmdpush(CS_COND);
3863 stat = evalcond(state, NULL);
3865 * 2 indicates a syntax error. For compatibility, turn this
3866 * into a shell error.
3868 if (stat == 2)
3869 errflag = 1;
3870 cmdpop();
3871 if (isset(XTRACE)) {
3872 fprintf(xtrerr, " ]]\n");
3873 fflush(xtrerr);
3874 tracingcond--;
3876 return stat;
3879 /* evaluate a ((...)) arithmetic command */
3881 /**/
3882 static int
3883 execarith(Estate state, UNUSED(int do_exec))
3885 char *e;
3886 mnumber val = zero_mnumber;
3887 int htok = 0;
3889 if (isset(XTRACE)) {
3890 printprompt4();
3891 fprintf(xtrerr, "((");
3893 cmdpush(CS_MATH);
3894 e = ecgetstr(state, EC_DUPTOK, &htok);
3895 if (htok)
3896 singsub(&e);
3897 if (isset(XTRACE))
3898 fprintf(xtrerr, " %s", e);
3900 val = matheval(e);
3902 cmdpop();
3904 if (isset(XTRACE)) {
3905 fprintf(xtrerr, " ))\n");
3906 fflush(xtrerr);
3908 if (errflag) {
3909 errflag = 0;
3910 return 2;
3912 /* should test for fabs(val.u.d) < epsilon? */
3913 return (val.type == MN_INTEGER) ? val.u.l == 0 : val.u.d == 0.0;
3916 /* perform time ... command */
3918 /**/
3919 static int
3920 exectime(Estate state, UNUSED(int do_exec))
3922 int jb;
3924 jb = thisjob;
3925 if (WC_TIMED_TYPE(state->pc[-1]) == WC_TIMED_EMPTY) {
3926 shelltime();
3927 return 0;
3929 execpline(state, *state->pc++, Z_TIMED|Z_SYNC, 0);
3930 thisjob = jb;
3931 return lastval;
3934 /* Define a shell function */
3936 /**/
3937 static int
3938 execfuncdef(Estate state, UNUSED(int do_exec))
3940 Shfunc shf;
3941 char *s = NULL;
3942 int signum, nprg, sbeg, nstrs, npats, len, plen, i, htok = 0, ret = 0;
3943 Wordcode beg = state->pc, end;
3944 Eprog prog;
3945 Patprog *pp;
3946 LinkList names;
3948 end = beg + WC_FUNCDEF_SKIP(state->pc[-1]);
3949 names = ecgetlist(state, *state->pc++, EC_DUPTOK, &htok);
3950 nprg = end - beg;
3951 sbeg = *state->pc++;
3952 nstrs = *state->pc++;
3953 npats = *state->pc++;
3955 nprg = (end - state->pc);
3956 plen = nprg * sizeof(wordcode);
3957 len = plen + (npats * sizeof(Patprog)) + nstrs;
3959 if (htok && names)
3960 execsubst(names);
3962 while (!names || (s = (char *) ugetnode(names))) {
3963 if (!names) {
3964 prog = (Eprog) zhalloc(sizeof(*prog));
3965 prog->nref = -1; /* on the heap */
3966 } else {
3967 prog = (Eprog) zalloc(sizeof(*prog));
3968 prog->nref = 1; /* allocated from permanent storage */
3970 prog->npats = npats;
3971 prog->len = len;
3972 if (state->prog->dump || !names) {
3973 if (!names) {
3974 prog->flags = EF_HEAP;
3975 prog->dump = NULL;
3976 prog->pats = pp = (Patprog *) zhalloc(npats * sizeof(Patprog));
3977 } else {
3978 prog->flags = EF_MAP;
3979 incrdumpcount(state->prog->dump);
3980 prog->dump = state->prog->dump;
3981 prog->pats = pp = (Patprog *) zalloc(npats * sizeof(Patprog));
3983 prog->prog = state->pc;
3984 prog->strs = state->strs + sbeg;
3985 } else {
3986 prog->flags = EF_REAL;
3987 prog->pats = pp = (Patprog *) zalloc(len);
3988 prog->prog = (Wordcode) (prog->pats + npats);
3989 prog->strs = (char *) (prog->prog + nprg);
3990 prog->dump = NULL;
3991 memcpy(prog->prog, state->pc, plen);
3992 memcpy(prog->strs, state->strs + sbeg, nstrs);
3994 for (i = npats; i--; pp++)
3995 *pp = dummy_patprog1;
3996 prog->shf = NULL;
3998 shf = (Shfunc) zalloc(sizeof(*shf));
3999 shf->funcdef = prog;
4000 shf->node.flags = 0;
4001 shf->filename = ztrdup(scriptfilename);
4002 shf->lineno = lineno;
4003 shf->emulation = sticky_emulation;
4005 if (!names) {
4007 * Anonymous function, execute immediately.
4008 * Function name is "(anon)", parameter list is empty.
4010 LinkList args = newlinklist();
4012 shf->node.nam = "(anon)";
4013 addlinknode(args, shf->node.nam);
4015 execshfunc(shf, args);
4016 ret = lastval;
4017 break;
4018 } else {
4019 /* is this shell function a signal trap? */
4020 if (!strncmp(s, "TRAP", 4) &&
4021 (signum = getsignum(s + 4)) != -1) {
4022 if (settrap(signum, NULL, ZSIG_FUNC)) {
4023 freeeprog(shf->funcdef);
4024 zfree(shf, sizeof(*shf));
4025 state->pc = end;
4026 return 1;
4030 * Remove the old node explicitly in case it has
4031 * an alternative name
4033 removetrapnode(signum);
4035 shfunctab->addnode(shfunctab, ztrdup(s), shf);
4038 state->pc = end;
4039 return ret;
4042 /* Main entry point to execute a shell function. */
4044 /**/
4045 static void
4046 execshfunc(Shfunc shf, LinkList args)
4048 LinkList last_file_list = NULL;
4049 unsigned char *ocs;
4050 int ocsp, osfc;
4052 if (errflag)
4053 return;
4055 if (!list_pipe && thisjob != list_pipe_job && !hasprocs(thisjob)) {
4056 /* Without this deletejob the process table *
4057 * would be filled by a recursive function. */
4058 last_file_list = jobtab[thisjob].filelist;
4059 jobtab[thisjob].filelist = NULL;
4060 deletejob(jobtab + thisjob);
4063 if (isset(XTRACE)) {
4064 LinkNode lptr;
4065 printprompt4();
4066 if (args)
4067 for (lptr = firstnode(args); lptr; incnode(lptr)) {
4068 if (lptr != firstnode(args))
4069 fputc(' ', xtrerr);
4070 quotedzputs((char *)getdata(lptr), xtrerr);
4072 fputc('\n', xtrerr);
4073 fflush(xtrerr);
4075 ocs = cmdstack;
4076 ocsp = cmdsp;
4077 cmdstack = (unsigned char *) zalloc(CMDSTACKSZ);
4078 cmdsp = 0;
4079 if ((osfc = sfcontext) == SFC_NONE)
4080 sfcontext = SFC_DIRECT;
4081 doshfunc(shf, args, 0);
4082 sfcontext = osfc;
4083 free(cmdstack);
4084 cmdstack = ocs;
4085 cmdsp = ocsp;
4087 if (!list_pipe)
4088 deletefilelist(last_file_list);
4091 /* Function to execute the special type of command that represents an *
4092 * autoloaded shell function. The command structure tells us which *
4093 * function it is. This function is actually called as part of the *
4094 * execution of the autoloaded function itself, so when the function *
4095 * has been autoloaded, its list is just run with no frills. */
4097 /**/
4098 static int
4099 execautofn(Estate state, UNUSED(int do_exec))
4101 Shfunc shf;
4102 char *oldscriptname, *oldscriptfilename;
4104 if (!(shf = loadautofn(state->prog->shf, 1, 0)))
4105 return 1;
4108 * Probably we didn't know the filename where this function was
4109 * defined yet.
4111 if (funcstack && !funcstack->filename)
4112 funcstack->filename = dupstring(shf->filename);
4114 oldscriptname = scriptname;
4115 oldscriptfilename = scriptfilename;
4116 scriptname = scriptfilename = dupstring(shf->node.nam);
4117 execode(shf->funcdef, 1, 0);
4118 scriptname = oldscriptname;
4119 scriptfilename = oldscriptfilename;
4121 return lastval;
4124 /**/
4125 Shfunc
4126 loadautofn(Shfunc shf, int fksh, int autol)
4128 int noalias = noaliases, ksh = 1;
4129 Eprog prog;
4130 char *fname;
4132 pushheap();
4134 noaliases = (shf->node.flags & PM_UNALIASED);
4135 prog = getfpfunc(shf->node.nam, &ksh, &fname);
4136 noaliases = noalias;
4138 if (ksh == 1) {
4139 ksh = fksh;
4140 if (ksh == 1)
4141 ksh = (shf->node.flags & PM_KSHSTORED) ? 2 :
4142 (shf->node.flags & PM_ZSHSTORED) ? 0 : 1;
4145 if (prog == &dummy_eprog) {
4146 /* We're not actually in the function; decrement locallevel */
4147 locallevel--;
4148 zwarn("%s: function definition file not found", shf->node.nam);
4149 locallevel++;
4150 popheap();
4151 return NULL;
4153 if (!prog) {
4154 zsfree(fname);
4155 return NULL;
4157 if (ksh == 2 || (ksh == 1 && isset(KSHAUTOLOAD))) {
4158 if (autol) {
4159 prog->flags |= EF_RUN;
4161 freeeprog(shf->funcdef);
4162 if (prog->flags & EF_MAP)
4163 shf->funcdef = prog;
4164 else
4165 shf->funcdef = dupeprog(prog, 0);
4166 shf->node.flags &= ~PM_UNDEFINED;
4167 shf->filename = fname;
4168 } else {
4169 VARARR(char, n, strlen(shf->node.nam) + 1);
4170 strcpy(n, shf->node.nam);
4171 execode(prog, 1, 0);
4172 shf = (Shfunc) shfunctab->getnode(shfunctab, n);
4173 if (!shf || (shf->node.flags & PM_UNDEFINED)) {
4174 /* We're not actually in the function; decrement locallevel */
4175 locallevel--;
4176 zwarn("%s: function not defined by file", n);
4177 locallevel++;
4178 popheap();
4179 zsfree(fname);
4180 return NULL;
4183 } else {
4184 freeeprog(shf->funcdef);
4185 if (prog->flags & EF_MAP)
4186 shf->funcdef = stripkshdef(prog, shf->node.nam);
4187 else
4188 shf->funcdef = dupeprog(stripkshdef(prog, shf->node.nam), 0);
4189 shf->node.flags &= ~PM_UNDEFINED;
4190 shf->filename = fname;
4192 popheap();
4194 return shf;
4198 * execute a shell function
4200 * name is the name of the function
4202 * prog is the code to execute
4204 * doshargs, if set, are parameters to pass to the function,
4205 * in which the first element is the function name (even if
4206 * FUNCTIONARGZERO is set as this is handled inside this function).
4208 * If noreturnval is nonzero, then reset the current return
4209 * value (lastval) to its value before the shell function
4210 * was executed. However, in any case return the status value
4211 * from the function (i.e. if noreturnval is not set, this
4212 * will be the same as lastval).
4215 /**/
4216 mod_export int
4217 doshfunc(Shfunc shfunc, LinkList doshargs, int noreturnval)
4219 char **tab, **x, *oargv0;
4220 int oldzoptind, oldlastval, oldoptcind, oldnumpipestats, ret;
4221 int *oldpipestats = NULL;
4222 char saveopts[OPT_SIZE], *oldscriptname = scriptname;
4223 char *name = shfunc->node.nam;
4224 int flags = shfunc->node.flags;
4225 char *fname = dupstring(name);
4226 int obreaks, saveemulation, savesticky_emulation, restore_sticky;
4227 Eprog prog;
4228 struct funcstack fstack;
4229 #ifdef MAX_FUNCTION_DEPTH
4230 static int funcdepth;
4231 #endif
4233 pushheap();
4235 oargv0 = NULL;
4236 obreaks = breaks;;
4237 if (trap_state == TRAP_STATE_PRIMED)
4238 trap_return--;
4239 oldlastval = lastval;
4240 oldnumpipestats = numpipestats;
4241 if (noreturnval) {
4243 * Easiest to use the heap here since we're bracketed
4244 * immediately by a pushheap/popheap pair.
4246 size_t bytes = sizeof(int)*numpipestats;
4247 oldpipestats = (int *)zhalloc(bytes);
4248 memcpy(oldpipestats, pipestats, bytes);
4251 starttrapscope();
4253 tab = pparams;
4254 if (!(flags & PM_UNDEFINED))
4255 scriptname = dupstring(name);
4256 oldzoptind = zoptind;
4257 zoptind = 1;
4258 oldoptcind = optcind;
4259 optcind = 0;
4261 /* We need to save the current options even if LOCALOPTIONS is *
4262 * not currently set. That's because if it gets set in the *
4263 * function we need to restore the original options on exit. */
4264 memcpy(saveopts, opts, sizeof(opts));
4265 saveemulation = emulation;
4266 savesticky_emulation = sticky_emulation;
4268 if (shfunc->emulation && sticky_emulation != shfunc->emulation) {
4270 * Function is marked for sticky emulation.
4271 * Enable it now.
4273 * We deliberately do not do this if the sticky emulation
4274 * in effect is the same as that requested. This enables
4275 * option setting naturally within emulation environments.
4276 * Note that a difference in EMULATE_FULLY (emulate with
4277 * or without -R) counts as a different environment.
4279 * This propagates the sticky emulation to subfunctions.
4281 emulation = sticky_emulation = shfunc->emulation;
4282 restore_sticky = 1;
4283 installemulation();
4284 } else
4285 restore_sticky = 0;
4287 if (flags & PM_TAGGED)
4288 opts[XTRACE] = 1;
4289 opts[PRINTEXITVALUE] = 0;
4290 if (doshargs) {
4291 LinkNode node;
4293 node = firstnode(doshargs);
4294 pparams = x = (char **) zshcalloc(((sizeof *x) *
4295 (1 + countlinknodes(doshargs))));
4296 if (isset(FUNCTIONARGZERO)) {
4297 oargv0 = argzero;
4298 argzero = ztrdup(getdata(node));
4300 /* first node contains name regardless of option */
4301 node = node->next;
4302 for (; node; node = node->next, x++)
4303 *x = ztrdup(getdata(node));
4304 } else {
4305 pparams = (char **) zshcalloc(sizeof *pparams);
4306 if (isset(FUNCTIONARGZERO)) {
4307 oargv0 = argzero;
4308 argzero = ztrdup(argzero);
4311 #ifdef MAX_FUNCTION_DEPTH
4312 if(++funcdepth > MAX_FUNCTION_DEPTH)
4314 zerr("maximum nested function level reached");
4315 goto undoshfunc;
4317 #endif
4318 fstack.name = dupstring(name);
4320 * The caller is whatever is immediately before on the stack,
4321 * unless we're at the top, in which case it's the script
4322 * or interactive shell name.
4324 fstack.caller = funcstack ? funcstack->name :
4325 dupstring(oargv0 ? oargv0 : argzero);
4326 fstack.lineno = lineno;
4327 fstack.prev = funcstack;
4328 fstack.tp = FS_FUNC;
4329 funcstack = &fstack;
4331 fstack.flineno = shfunc->lineno;
4332 fstack.filename = dupstring(shfunc->filename);
4334 prog = shfunc->funcdef;
4335 if (prog->flags & EF_RUN) {
4336 Shfunc shf;
4338 prog->flags &= ~EF_RUN;
4340 runshfunc(prog, NULL, fstack.name);
4342 if (!(shf = (Shfunc) shfunctab->getnode(shfunctab,
4343 (name = fname)))) {
4344 zwarn("%s: function not defined by file", name);
4345 if (noreturnval)
4346 errflag = 1;
4347 else
4348 lastval = 1;
4349 goto doneshfunc;
4351 prog = shf->funcdef;
4353 runshfunc(prog, wrappers, fstack.name);
4354 doneshfunc:
4355 funcstack = fstack.prev;
4356 #ifdef MAX_FUNCTION_DEPTH
4357 undoshfunc:
4358 --funcdepth;
4359 #endif
4360 if (retflag) {
4361 retflag = 0;
4362 breaks = obreaks;
4364 freearray(pparams);
4365 if (oargv0) {
4366 zsfree(argzero);
4367 argzero = oargv0;
4369 pparams = tab;
4370 optcind = oldoptcind;
4371 zoptind = oldzoptind;
4372 scriptname = oldscriptname;
4374 if (restore_sticky) {
4376 * If we switched to an emulation environment just for
4377 * this function, we interpret the option and emulation
4378 * switch as being a firewall between environments.
4380 memcpy(opts, saveopts, sizeof(opts));
4381 emulation = saveemulation;
4382 sticky_emulation = savesticky_emulation;
4383 } else if (isset(LOCALOPTIONS)) {
4384 /* restore all shell options except PRIVILEGED and RESTRICTED */
4385 saveopts[PRIVILEGED] = opts[PRIVILEGED];
4386 saveopts[RESTRICTED] = opts[RESTRICTED];
4387 memcpy(opts, saveopts, sizeof(opts));
4388 emulation = saveemulation;
4389 } else {
4390 /* just restore a couple. */
4391 opts[XTRACE] = saveopts[XTRACE];
4392 opts[PRINTEXITVALUE] = saveopts[PRINTEXITVALUE];
4393 opts[LOCALOPTIONS] = saveopts[LOCALOPTIONS];
4396 endtrapscope();
4398 if (trap_state == TRAP_STATE_PRIMED)
4399 trap_return++;
4400 ret = lastval;
4401 if (noreturnval) {
4402 lastval = oldlastval;
4403 numpipestats = oldnumpipestats;
4404 memcpy(pipestats, oldpipestats, sizeof(int)*numpipestats);
4406 popheap();
4408 if (exit_pending) {
4409 if (locallevel > forklevel) {
4410 /* Still functions to return: force them to do so. */
4411 retflag = 1;
4412 breaks = loops;
4413 } else {
4415 * All functions finished: time to exit the shell.
4416 * We already did the `stopmsg' test when the
4417 * exit command was handled.
4419 stopmsg = 1;
4420 zexit(exit_pending >> 1, 0);
4424 return ret;
4427 /* This finally executes a shell function and any function wrappers *
4428 * defined by modules. This works by calling the wrapper function which *
4429 * in turn has to call back this function with the arguments it gets. */
4431 /**/
4432 mod_export void
4433 runshfunc(Eprog prog, FuncWrap wrap, char *name)
4435 int cont, ouu;
4436 char *ou;
4438 ou = zalloc(ouu = underscoreused);
4439 if (ou)
4440 memcpy(ou, underscore, underscoreused);
4442 while (wrap) {
4443 wrap->module->wrapper++;
4444 cont = wrap->handler(prog, wrap->next, name);
4445 wrap->module->wrapper--;
4447 if (!wrap->module->wrapper &&
4448 (wrap->module->node.flags & MOD_UNLOAD))
4449 unload_module(wrap->module);
4451 if (!cont) {
4452 if (ou)
4453 zfree(ou, ouu);
4454 return;
4456 wrap = wrap->next;
4458 startparamscope();
4459 execode(prog, 1, 0);
4460 if (ou) {
4461 setunderscore(ou);
4462 zfree(ou, ouu);
4464 endparamscope();
4467 /* Search fpath for an undefined function. Finds the file, and returns the *
4468 * list of its contents. */
4470 /**/
4471 Eprog
4472 getfpfunc(char *s, int *ksh, char **fname)
4474 char **pp, buf[PATH_MAX];
4475 off_t len;
4476 off_t rlen;
4477 char *d;
4478 Eprog r;
4479 int fd;
4481 pp = fpath;
4482 for (; *pp; pp++) {
4483 if (strlen(*pp) + strlen(s) + 1 >= PATH_MAX)
4484 continue;
4485 if (**pp)
4486 sprintf(buf, "%s/%s", *pp, s);
4487 else
4488 strcpy(buf, s);
4489 if ((r = try_dump_file(*pp, s, buf, ksh))) {
4490 if (fname)
4491 *fname = ztrdup(buf);
4492 return r;
4494 unmetafy(buf, NULL);
4495 if (!access(buf, R_OK) && (fd = open(buf, O_RDONLY | O_NOCTTY)) != -1) {
4496 if ((len = lseek(fd, 0, 2)) != -1) {
4497 d = (char *) zalloc(len + 1);
4498 lseek(fd, 0, 0);
4499 if ((rlen = read(fd, d, len)) >= 0) {
4500 char *oldscriptname = scriptname;
4502 close(fd);
4503 d[rlen] = '\0';
4504 d = metafy(d, rlen, META_REALLOC);
4506 scriptname = dupstring(s);
4507 r = parse_string(d, 1);
4508 scriptname = oldscriptname;
4510 if (fname)
4511 *fname = ztrdup(buf);
4513 zfree(d, len + 1);
4515 return r;
4516 } else
4517 close(fd);
4519 zfree(d, len + 1);
4520 } else
4521 close(fd);
4524 return &dummy_eprog;
4527 /* Handle the most common type of ksh-style autoloading, when doing a *
4528 * zsh-style autoload. Given the list read from an autoload file, and the *
4529 * name of the function being defined, check to see if the file consists *
4530 * entirely of a single definition for that function. If so, use the *
4531 * contents of that definition. Otherwise, use the entire file. */
4533 /**/
4534 Eprog
4535 stripkshdef(Eprog prog, char *name)
4537 Wordcode pc;
4538 wordcode code;
4540 if (!prog)
4541 return NULL;
4542 pc = prog->prog;
4543 code = *pc++;
4544 if (wc_code(code) != WC_LIST ||
4545 (WC_LIST_TYPE(code) & (Z_SYNC|Z_END|Z_SIMPLE)) != (Z_SYNC|Z_END|Z_SIMPLE))
4546 return prog;
4547 pc++;
4548 code = *pc++;
4549 if (wc_code(code) != WC_FUNCDEF ||
4550 *pc != 1 || strcmp(name, ecrawstr(prog, pc + 1, NULL)))
4551 return prog;
4554 Eprog ret;
4555 Wordcode end = pc + WC_FUNCDEF_SKIP(code);
4556 int sbeg = pc[2], nstrs = pc[3], nprg, npats = pc[4], plen, len, i;
4557 Patprog *pp;
4559 pc += 5;
4561 nprg = end - pc;
4562 plen = nprg * sizeof(wordcode);
4563 len = plen + (npats * sizeof(Patprog)) + nstrs;
4565 if (prog->flags & EF_MAP) {
4566 ret = prog;
4567 free(prog->pats);
4568 ret->pats = pp = (Patprog *) zalloc(npats * sizeof(Patprog));
4569 ret->prog = pc;
4570 ret->strs = prog->strs + sbeg;
4571 } else {
4572 ret = (Eprog) zhalloc(sizeof(*ret));
4573 ret->flags = EF_HEAP;
4574 ret->pats = pp = (Patprog *) zhalloc(len);
4575 ret->prog = (Wordcode) (ret->pats + npats);
4576 ret->strs = (char *) (ret->prog + nprg);
4577 memcpy(ret->prog, pc, plen);
4578 memcpy(ret->strs, prog->strs + sbeg, nstrs);
4579 ret->dump = NULL;
4581 ret->len = len;
4582 ret->npats = npats;
4583 for (i = npats; i--; pp++)
4584 *pp = dummy_patprog1;
4585 ret->shf = NULL;
4587 return ret;
4591 /* check to see if AUTOCD applies here */
4593 /**/
4594 static char *
4595 cancd(char *s)
4597 int nocdpath = s[0] == '.' &&
4598 (s[1] == '/' || !s[1] || (s[1] == '.' && (s[2] == '/' || !s[1])));
4599 char *t;
4601 if (*s != '/') {
4602 char sbuf[PATH_MAX], **cp;
4604 if (cancd2(s))
4605 return s;
4606 if (access(unmeta(s), X_OK) == 0)
4607 return NULL;
4608 if (!nocdpath)
4609 for (cp = cdpath; *cp; cp++) {
4610 if (strlen(*cp) + strlen(s) + 1 >= PATH_MAX)
4611 continue;
4612 if (**cp)
4613 sprintf(sbuf, "%s/%s", *cp, s);
4614 else
4615 strcpy(sbuf, s);
4616 if (cancd2(sbuf)) {
4617 doprintdir = -1;
4618 return dupstring(sbuf);
4621 if ((t = cd_able_vars(s))) {
4622 if (cancd2(t)) {
4623 doprintdir = -1;
4624 return t;
4627 return NULL;
4629 return cancd2(s) ? s : NULL;
4632 /**/
4633 static int
4634 cancd2(char *s)
4636 struct stat buf;
4637 char *us, *us2 = NULL;
4638 int ret;
4641 * If CHASEDOTS and CHASELINKS are not set, we want to rationalize the
4642 * path by removing foo/.. combinations in the logical rather than
4643 * the physical path. If either is set, we test the physical path.
4645 if (!isset(CHASEDOTS) && !isset(CHASELINKS)) {
4646 if (*s != '/')
4647 us = tricat(pwd[1] ? pwd : "", "/", s);
4648 else
4649 us = ztrdup(s);
4650 fixdir(us2 = us);
4651 } else
4652 us = unmeta(s);
4653 ret = !(access(us, X_OK) || stat(us, &buf) || !S_ISDIR(buf.st_mode));
4654 if (us2)
4655 free(us2);
4656 return ret;
4659 /**/
4660 void
4661 execsave(void)
4663 struct execstack *es;
4665 es = (struct execstack *) malloc(sizeof(struct execstack));
4666 es->list_pipe_pid = list_pipe_pid;
4667 es->nowait = nowait;
4668 es->pline_level = pline_level;
4669 es->list_pipe_child = list_pipe_child;
4670 es->list_pipe_job = list_pipe_job;
4671 strcpy(es->list_pipe_text, list_pipe_text);
4672 es->lastval = lastval;
4673 es->noeval = noeval;
4674 es->badcshglob = badcshglob;
4675 es->cmdoutpid = cmdoutpid;
4676 es->cmdoutval = cmdoutval;
4677 es->trap_return = trap_return;
4678 es->trap_state = trap_state;
4679 es->trapisfunc = trapisfunc;
4680 es->traplocallevel = traplocallevel;
4681 es->noerrs = noerrs;
4682 es->subsh_close = subsh_close;
4683 es->underscore = ztrdup(underscore);
4684 es->next = exstack;
4685 exstack = es;
4686 noerrs = cmdoutpid = 0;
4689 /**/
4690 void
4691 execrestore(void)
4693 struct execstack *en;
4695 DPUTS(!exstack, "BUG: execrestore() without execsave()");
4696 list_pipe_pid = exstack->list_pipe_pid;
4697 nowait = exstack->nowait;
4698 pline_level = exstack->pline_level;
4699 list_pipe_child = exstack->list_pipe_child;
4700 list_pipe_job = exstack->list_pipe_job;
4701 strcpy(list_pipe_text, exstack->list_pipe_text);
4702 lastval = exstack->lastval;
4703 noeval = exstack->noeval;
4704 badcshglob = exstack->badcshglob;
4705 cmdoutpid = exstack->cmdoutpid;
4706 cmdoutval = exstack->cmdoutval;
4707 trap_return = exstack->trap_return;
4708 trap_state = exstack->trap_state;
4709 trapisfunc = exstack->trapisfunc;
4710 traplocallevel = exstack->traplocallevel;
4711 noerrs = exstack->noerrs;
4712 subsh_close = exstack->subsh_close;
4713 setunderscore(exstack->underscore);
4714 zsfree(exstack->underscore);
4715 en = exstack->next;
4716 free(exstack);
4717 exstack = en;