26763: fix problem on failed cd -s to relative path
[zsh.git] / Src / init.c
bloba3aac3e1ca5a0abeca070f8c53043245b7c13f35
1 /*
2 * init.c - main loop and initialization routines
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"
32 #include "zshpaths.h"
33 #include "zshxmods.h"
35 #include "init.pro"
37 #include "version.h"
39 /**/
40 int noexitct = 0;
42 /* buffer for $_ and its length */
44 /**/
45 char *underscore;
47 /**/
48 int underscorelen, underscoreused;
50 /* what level of sourcing we are at */
52 /**/
53 int sourcelevel;
55 /* the shell tty fd */
57 /**/
58 mod_export int SHTTY;
60 /* the FILE attached to the shell tty */
62 /**/
63 mod_export FILE *shout;
65 /* termcap strings */
67 /**/
68 mod_export char *tcstr[TC_COUNT];
70 /* lengths of each termcap string */
72 /**/
73 mod_export int tclen[TC_COUNT];
75 /* Values of the li, co and am entries */
77 /**/
78 int tclines, tccolumns;
79 /**/
80 mod_export int hasam, hasxn;
82 /* Value of the Co (max_colors) entry: may not be set */
84 /**/
85 mod_export int tccolours;
87 /* SIGCHLD mask */
89 /**/
90 mod_export sigset_t sigchld_mask;
92 /**/
93 mod_export struct hookdef zshhooks[] = {
94 HOOKDEF("exit", NULL, HOOKF_ALL),
95 HOOKDEF("before_trap", NULL, HOOKF_ALL),
96 HOOKDEF("after_trap", NULL, HOOKF_ALL),
99 /* keep executing lists until EOF found */
101 /**/
102 void
103 loop(int toplevel, int justonce)
105 Eprog prog;
107 pushheap();
108 if (!toplevel)
109 lexsave();
110 for (;;) {
111 freeheap();
112 if (stophist == 3) /* re-entry via preprompt() */
113 hend(NULL);
114 hbegin(1); /* init history mech */
115 if (isset(SHINSTDIN)) {
116 setblock_stdin();
117 if (interact && toplevel) {
118 int hstop = stophist;
119 stophist = 3;
120 preprompt();
121 if (stophist != 3)
122 hbegin(1);
123 else
124 stophist = hstop;
125 errflag = 0;
128 use_exit_printed = 0;
129 intr(); /* interrupts on */
130 lexinit(); /* initialize lexical state */
131 if (!(prog = parse_event())) { /* if we couldn't parse a list */
132 hend(NULL);
133 if ((tok == ENDINPUT && !errflag) ||
134 (tok == LEXERR && (!isset(SHINSTDIN) || !toplevel)) ||
135 justonce)
136 break;
137 if (exit_pending) {
139 * Something down there (a ZLE function?) decided
140 * to exit when there was stuff to clear up.
141 * Handle that now.
143 stopmsg = 1;
144 zexit(exit_pending >> 1, 0);
146 if (tok == LEXERR && !lastval)
147 lastval = 1;
148 continue;
150 if (hend(prog)) {
151 int toksav = tok;
153 if (toplevel &&
154 (getshfunc("preexec") ||
155 paramtab->getnode(paramtab, "preexec" HOOK_SUFFIX))) {
156 LinkList args;
157 char *cmdstr;
160 * As we're about to freeheap() or popheap()
161 * anyway, there's no gain in using permanent
162 * storage here.
164 args = newlinklist();
165 addlinknode(args, "preexec");
166 /* If curline got dumped from the history, we don't know
167 * what the user typed. */
168 if (hist_ring && curline.histnum == curhist)
169 addlinknode(args, hist_ring->node.nam);
170 else
171 addlinknode(args, "");
172 addlinknode(args, dupstring(getjobtext(prog, NULL)));
173 addlinknode(args, cmdstr = getpermtext(prog, NULL, 0));
175 callhookfunc("preexec", args, 1, NULL);
177 /* The only permanent storage is from getpermtext() */
178 zsfree(cmdstr);
179 errflag = 0;
181 if (stopmsg) /* unset 'you have stopped jobs' flag */
182 stopmsg--;
183 execode(prog, 0, 0);
184 tok = toksav;
185 if (toplevel)
186 noexitct = 0;
188 if (ferror(stderr)) {
189 zerr("write error");
190 clearerr(stderr);
192 if (subsh) /* how'd we get this far in a subshell? */
193 exit(lastval);
194 if (((!interact || sourcelevel) && errflag) || retflag)
195 break;
196 if (isset(SINGLECOMMAND) && toplevel) {
197 if (sigtrapped[SIGEXIT])
198 dotrap(SIGEXIT);
199 exit(lastval);
201 if (justonce)
202 break;
204 if (!toplevel)
205 lexrestore();
206 popheap();
209 static char *cmd;
210 static int restricted;
212 /**/
213 void
214 parseargs(char **argv)
216 int optionbreak = 0;
217 char **x;
218 int action, optno;
219 LinkList paramlist;
221 argzero = *argv++;
222 SHIN = 0;
224 /* There's a bit of trickery with opts[INTERACTIVE] here. It starts *
225 * at a value of 2 (instead of 1) or 0. If it is explicitly set on *
226 * the command line, it goes to 1 or 0. If input is coming from *
227 * somewhere that normally makes the shell non-interactive, we do *
228 * "opts[INTERACTIVE] &= 1", so that only a *default* on state will *
229 * be changed. At the end of the function, a value of 2 gets *
230 * changed to 1. */
231 opts[INTERACTIVE] = isatty(0) ? 2 : 0;
232 opts[SHINSTDIN] = 0;
233 opts[SINGLECOMMAND] = 0;
235 /* loop through command line options (begins with "-" or "+") */
236 while (!optionbreak && *argv && (**argv == '-' || **argv == '+')) {
237 char *args = *argv;
238 action = (**argv == '-');
239 if (!argv[0][1])
240 *argv = "--";
241 while (*++*argv) {
242 if (**argv == '-') {
243 if(!argv[0][1]) {
244 /* The pseudo-option `--' signifies the end of options. */
245 argv++;
246 goto doneoptions;
248 if(*argv != args+1 || **argv != '-')
249 goto badoptionstring;
250 /* GNU-style long options */
251 ++*argv;
252 if (!strcmp(*argv, "version")) {
253 printf("zsh %s (%s-%s-%s)\n",
254 ZSH_VERSION, MACHTYPE, VENDOR, OSTYPE);
255 exit(0);
257 if (!strcmp(*argv, "help")) {
258 printhelp();
259 exit(0);
261 /* `-' characters are allowed in long options */
262 for(args = *argv; *args; args++)
263 if(*args == '-')
264 *args = '_';
265 goto longoptions;
268 if (unset(SHOPTIONLETTERS) && **argv == 'b') {
269 /* -b ends options at the end of this argument */
270 optionbreak = 1;
271 } else if (**argv == 'c') {
272 /* -c command */
273 cmd = *argv;
274 opts[INTERACTIVE] &= 1;
275 scriptname = scriptfilename = ztrdup("zsh");
276 } else if (**argv == 'o') {
277 if (!*++*argv)
278 argv++;
279 if (!*argv) {
280 zerr("string expected after -o");
281 exit(1);
283 longoptions:
284 if (!(optno = optlookup(*argv))) {
285 zerr("no such option: %s", *argv);
286 exit(1);
287 } else if (optno == RESTRICTED)
288 restricted = action;
289 else
290 dosetopt(optno, action, 1);
291 break;
292 } else if (isspace(STOUC(**argv))) {
293 /* zsh's typtab not yet set, have to use ctype */
294 while (*++*argv)
295 if (!isspace(STOUC(**argv))) {
296 badoptionstring:
297 zerr("bad option string: `%s'", args);
298 exit(1);
300 break;
301 } else {
302 if (!(optno = optlookupc(**argv))) {
303 zerr("bad option: -%c", **argv);
304 exit(1);
305 } else if (optno == RESTRICTED)
306 restricted = action;
307 else
308 dosetopt(optno, action, 1);
311 argv++;
313 doneoptions:
314 paramlist = znewlinklist();
315 if (cmd) {
316 if (!*argv) {
317 zerr("string expected after -%s", cmd);
318 exit(1);
320 cmd = *argv++;
322 if (*argv) {
323 if (unset(SHINSTDIN)) {
324 if (!cmd)
325 SHIN = movefd(open(unmeta(*argv), O_RDONLY | O_NOCTTY));
326 if (SHIN == -1) {
327 zerr("can't open input file: %s", *argv);
328 exit(127);
330 opts[INTERACTIVE] &= 1;
331 argzero = *argv;
332 scriptfilename = argzero;
333 argv++;
335 while (*argv)
336 zaddlinknode(paramlist, ztrdup(*argv++));
337 } else if (!cmd)
338 opts[SHINSTDIN] = 1;
339 if(isset(SINGLECOMMAND))
340 opts[INTERACTIVE] &= 1;
341 opts[INTERACTIVE] = !!opts[INTERACTIVE];
342 pparams = x = (char **) zshcalloc((countlinknodes(paramlist) + 1) * sizeof(char *));
344 while ((*x++ = (char *)getlinknode(paramlist)));
345 free(paramlist);
346 argzero = ztrdup(argzero);
349 /**/
350 static void
351 printhelp(void)
353 printf("Usage: %s [<options>] [<argument> ...]\n", argzero);
354 printf("\nSpecial options:\n");
355 printf(" --help show this message, then exit\n");
356 printf(" --version show zsh version number, then exit\n");
357 if(unset(SHOPTIONLETTERS))
358 printf(" -b end option processing, like --\n");
359 printf(" -c take first argument as a command to execute\n");
360 printf(" -o OPTION set an option by name (see below)\n");
361 printf("\nNormal options are named. An option may be turned on by\n");
362 printf("`-o OPTION', `--OPTION', `+o no_OPTION' or `+-no-OPTION'. An\n");
363 printf("option may be turned off by `-o no_OPTION', `--no-OPTION',\n");
364 printf("`+o OPTION' or `+-OPTION'. Options are listed below only in\n");
365 printf("`--OPTION' or `--no-OPTION' form.\n");
366 printoptionlist();
369 /**/
370 mod_export void
371 init_io(void)
373 static char outbuf[BUFSIZ], errbuf[BUFSIZ];
375 #ifdef RSH_BUG_WORKAROUND
376 int i;
377 #endif
379 /* stdout, stderr fully buffered */
380 #ifdef _IOFBF
381 setvbuf(stdout, outbuf, _IOFBF, BUFSIZ);
382 setvbuf(stderr, errbuf, _IOFBF, BUFSIZ);
383 #else
384 setbuffer(stdout, outbuf, BUFSIZ);
385 setbuffer(stderr, errbuf, BUFSIZ);
386 #endif
388 /* This works around a bug in some versions of in.rshd. *
389 * Currently this is not defined by default. */
390 #ifdef RSH_BUG_WORKAROUND
391 if (cmd) {
392 for (i = 3; i < 10; i++)
393 close(i);
395 #endif
397 if (shout) {
399 * Check if shout was set to stderr, if so don't close it.
400 * We do this if we are interactive but don't have a
401 * terminal.
403 if (shout != stderr)
404 fclose(shout);
405 shout = 0;
407 if (SHTTY != -1) {
408 zclose(SHTTY);
409 SHTTY = -1;
412 /* Send xtrace output to stderr -- see execcmd() */
413 xtrerr = stderr;
415 /* Make sure the tty is opened read/write. */
416 if (isatty(0)) {
417 zsfree(ttystrname);
418 if ((ttystrname = ztrdup(ttyname(0)))) {
419 SHTTY = movefd(open(ttystrname, O_RDWR | O_NOCTTY));
420 #ifdef TIOCNXCL
422 * See if the terminal claims to be busy. If so, and fd 0
423 * is a terminal, try and set non-exclusive use for that.
424 * This is something to do with Solaris over-cleverness.
426 if (SHTTY == -1 && errno == EBUSY)
427 ioctl(0, TIOCNXCL, 0);
428 #endif
431 * xterm, rxvt and probably all terminal emulators except
432 * dtterm on Solaris 2.6 & 7 have a bug. Applications are
433 * unable to open /dev/tty or /dev/pts/<terminal number here>
434 * because something in Sun's STREAMS modules doesn't like
435 * it. The open() call fails with EBUSY which is not even
436 * listed as a possibility in the open(2) man page. So we'll
437 * try to outsmart The Company. -- <dave@srce.hr>
439 * Presumably there's no harm trying this on any OS, given that
440 * isatty(0) worked but opening the tty didn't. Possibly we won't
441 * get the tty read/write, but it's the best we can do -- pws
443 * Try both stdin and stdout before trying /dev/tty. -- Bart
445 #if defined(HAVE_FCNTL_H) && defined(F_GETFL)
446 #define rdwrtty(fd) ((fcntl(fd, F_GETFL, 0) & O_RDWR) == O_RDWR)
447 #else
448 #define rdwrtty(fd) 1
449 #endif
450 if (SHTTY == -1 && rdwrtty(0)) {
451 SHTTY = movefd(dup(0));
454 if (SHTTY == -1 && isatty(1) && rdwrtty(1) &&
455 (SHTTY = movefd(dup(1))) != -1) {
456 zsfree(ttystrname);
457 ttystrname = ztrdup(ttyname(1));
459 if (SHTTY == -1 &&
460 (SHTTY = movefd(open("/dev/tty", O_RDWR | O_NOCTTY))) != -1) {
461 zsfree(ttystrname);
462 ttystrname = ztrdup(ttyname(SHTTY));
464 if (SHTTY == -1) {
465 zsfree(ttystrname);
466 ttystrname = ztrdup("");
467 } else if (!ttystrname) {
468 ttystrname = ztrdup("/dev/tty");
471 /* We will only use zle if shell is interactive, *
472 * SHTTY != -1, and shout != 0 */
473 if (interact) {
474 init_shout();
475 if(!SHTTY || !shout)
476 opts[USEZLE] = 0;
477 } else
478 opts[USEZLE] = 0;
480 #ifdef JOB_CONTROL
481 /* If interactive, make sure the shell is in the foreground and is the
482 * process group leader.
484 mypid = (zlong)getpid();
485 if (opts[MONITOR] && interact && (SHTTY != -1)) {
486 origpgrp = GETPGRP();
487 acquire_pgrp(); /* might also clear opts[MONITOR] */
488 } else
489 opts[MONITOR] = 0;
490 #else
491 opts[MONITOR] = 0;
492 #endif
495 /**/
496 mod_export void
497 init_shout(void)
499 static char shoutbuf[BUFSIZ];
500 #if defined(JOB_CONTROL) && defined(TIOCSETD) && defined(NTTYDISC)
501 int ldisc;
502 #endif
504 if (SHTTY == -1)
506 /* Since we're interative, it's nice to have somewhere to write. */
507 shout = stderr;
508 return;
511 #if defined(JOB_CONTROL) && defined(TIOCSETD) && defined(NTTYDISC)
512 ldisc = NTTYDISC;
513 ioctl(SHTTY, TIOCSETD, (char *)&ldisc);
514 #endif
516 /* Associate terminal file descriptor with a FILE pointer */
517 shout = fdopen(SHTTY, "w");
518 #ifdef _IOFBF
519 setvbuf(shout, shoutbuf, _IOFBF, BUFSIZ);
520 #endif
522 gettyinfo(&shttyinfo); /* get tty state */
523 #if defined(__sgi)
524 if (shttyinfo.tio.c_cc[VSWTCH] <= 0) /* hack for irises */
525 shttyinfo.tio.c_cc[VSWTCH] = CSWTCH;
526 #endif
529 /* names of the termcap strings we want */
531 static char *tccapnams[TC_COUNT] = {
532 "cl", "le", "LE", "nd", "RI", "up", "UP", "do",
533 "DO", "dc", "DC", "ic", "IC", "cd", "ce", "al", "dl", "ta",
534 "md", "so", "us", "me", "se", "ue", "ch",
535 "ku", "kd", "kl", "kr", "sc", "rc", "bc", "AF", "AB"
538 /* Initialise termcap */
540 /**/
541 mod_export int
542 init_term(void)
544 #ifndef TGETENT_ACCEPTS_NULL
545 static char termbuf[2048]; /* the termcap buffer */
546 #endif
548 if (!*term) {
549 termflags |= TERM_UNKNOWN;
550 return 0;
553 /* unset zle if using zsh under emacs */
554 if (!strcmp(term, "emacs"))
555 opts[USEZLE] = 0;
557 #ifdef TGETENT_ACCEPTS_NULL
558 /* If possible, we let tgetent allocate its own termcap buffer */
559 if (tgetent(NULL, term) != TGETENT_SUCCESS)
560 #else
561 if (tgetent(termbuf, term) != TGETENT_SUCCESS)
562 #endif
564 if (isset(INTERACTIVE))
565 zerr("can't find terminal definition for %s", term);
566 errflag = 0;
567 termflags |= TERM_BAD;
568 return 0;
569 } else {
570 char tbuf[1024], *pp;
571 int t0;
573 termflags &= ~TERM_BAD;
574 termflags &= ~TERM_UNKNOWN;
575 for (t0 = 0; t0 != TC_COUNT; t0++) {
576 pp = tbuf;
577 zsfree(tcstr[t0]);
578 /* AIX tgetstr() ignores second argument */
579 if (!(pp = tgetstr(tccapnams[t0], &pp)))
580 tcstr[t0] = NULL, tclen[t0] = 0;
581 else {
582 tclen[t0] = strlen(pp);
583 tcstr[t0] = (char *) zalloc(tclen[t0] + 1);
584 memcpy(tcstr[t0], pp, tclen[t0] + 1);
588 /* check whether terminal has automargin (wraparound) capability */
589 hasam = tgetflag("am");
590 hasxn = tgetflag("xn"); /* also check for newline wraparound glitch */
592 tclines = tgetnum("li");
593 tccolumns = tgetnum("co");
594 tccolours = tgetnum("Co");
596 /* if there's no termcap entry for cursor up, use single line mode: *
597 * this is flagged by termflags which is examined in zle_refresh.c *
599 if (tccan(TCUP))
600 termflags &= ~TERM_NOUP;
601 else {
602 zsfree(tcstr[TCUP]);
603 tcstr[TCUP] = NULL;
604 termflags |= TERM_NOUP;
607 /* most termcaps don't define "bc" because they use \b. */
608 if (!tccan(TCBACKSPACE)) {
609 zsfree(tcstr[TCBACKSPACE]);
610 tcstr[TCBACKSPACE] = ztrdup("\b");
611 tclen[TCBACKSPACE] = 1;
614 /* if there's no termcap entry for cursor left, use backspace. */
615 if (!tccan(TCLEFT)) {
616 zsfree(tcstr[TCLEFT]);
617 tcstr[TCLEFT] = ztrdup(tcstr[TCBACKSPACE]);
618 tclen[TCLEFT] = tclen[TCBACKSPACE];
621 if (tccan(TCSAVECURSOR) && !tccan(TCRESTRCURSOR)) {
622 tclen[TCSAVECURSOR] = 0;
623 zsfree(tcstr[TCSAVECURSOR]);
624 tcstr[TCSAVECURSOR] = NULL;
627 /* if the termcap entry for down is \n, don't use it. */
628 if (tccan(TCDOWN) && tcstr[TCDOWN][0] == '\n') {
629 tclen[TCDOWN] = 0;
630 zsfree(tcstr[TCDOWN]);
631 tcstr[TCDOWN] = NULL;
634 /* if there's no termcap entry for clear, use ^L. */
635 if (!tccan(TCCLEARSCREEN)) {
636 zsfree(tcstr[TCCLEARSCREEN]);
637 tcstr[TCCLEARSCREEN] = ztrdup("\14");
638 tclen[TCCLEARSCREEN] = 1;
641 return 1;
644 /* Initialize lots of global variables and hash tables */
646 /**/
647 void
648 setupvals(void)
650 #ifdef USE_GETPWUID
651 struct passwd *pswd;
652 #endif
653 struct timezone dummy_tz;
654 char *ptr;
655 int i, j;
656 #if defined(SITEFPATH_DIR) || defined(FPATH_DIR)
657 char **fpathptr;
658 # if defined(FPATH_DIR) && defined(FPATH_SUBDIRS)
659 char *fpath_subdirs[] = FPATH_SUBDIRS;
660 # endif
661 # ifdef SITEFPATH_DIR
662 int fpathlen = 1;
663 # else
664 int fpathlen = 0;
665 # endif
666 #endif
667 int close_fds[10], tmppipe[2];
670 * Workaround a problem with NIS (in one guise or another) which
671 * grabs file descriptors and keeps them for future reference.
672 * We don't want these to be in the range where the user can
673 * open fd's, i.e. 0 to 9 inclusive. So we make sure all
674 * fd's in that range are in use.
676 memset(close_fds, 0, 10*sizeof(int));
677 if (pipe(tmppipe) == 0) {
679 * Strategy: Make sure we have at least fd 0 open (hence
680 * the pipe). From then on, keep dup'ing until we are
681 * up to 9. If we go over the top, close immediately, else
682 * mark for later closure.
684 i = -1; /* max fd we have checked */
685 while (i < 9) {
686 /* j is current fd */
687 if (i < tmppipe[0])
688 j = tmppipe[0];
689 else if (i < tmppipe[1])
690 j = tmppipe[1];
691 else {
692 j = dup(0);
693 if (j == -1)
694 break;
696 if (j < 10)
697 close_fds[j] = 1;
698 else
699 close(j);
700 if (i < j)
701 i = j;
703 if (i < tmppipe[0])
704 close(tmppipe[0]);
705 if (i < tmppipe[1])
706 close(tmppipe[1]);
709 (void)addhookdefs(NULL, zshhooks, sizeof(zshhooks)/sizeof(*zshhooks));
711 init_eprog();
713 zero_mnumber.type = MN_INTEGER;
714 zero_mnumber.u.l = 0;
716 lineno = 1;
717 noeval = 0;
718 curhist = 0;
719 histsiz = DEFAULT_HISTSIZE;
720 inithist();
722 cmdstack = (unsigned char *) zalloc(CMDSTACKSZ);
723 cmdsp = 0;
725 bangchar = '!';
726 hashchar = '#';
727 hatchar = '^';
728 termflags = TERM_UNKNOWN;
729 curjob = prevjob = coprocin = coprocout = -1;
730 gettimeofday(&shtimer, &dummy_tz); /* init $SECONDS */
731 srand((unsigned int)(shtimer.tv_sec + shtimer.tv_usec)); /* seed $RANDOM */
733 /* Set default path */
734 path = (char **) zalloc(sizeof(*path) * 5);
735 path[0] = ztrdup("/bin");
736 path[1] = ztrdup("/usr/bin");
737 path[2] = ztrdup("/usr/ucb");
738 path[3] = ztrdup("/usr/local/bin");
739 path[4] = NULL;
741 cdpath = mkarray(NULL);
742 manpath = mkarray(NULL);
743 fignore = mkarray(NULL);
745 #if defined(SITEFPATH_DIR) || defined(FPATH_DIR)
746 # ifdef FPATH_DIR
747 # ifdef FPATH_SUBDIRS
748 fpathlen += sizeof(fpath_subdirs)/sizeof(char *);
749 # else
750 fpathlen++;
751 # endif
752 # endif
753 fpath = fpathptr = (char **)zalloc((fpathlen+1)*sizeof(char *));
754 # ifdef SITEFPATH_DIR
755 *fpathptr++ = ztrdup(SITEFPATH_DIR);
756 fpathlen--;
757 # endif
758 # ifdef FPATH_DIR
759 # ifdef FPATH_SUBDIRS
760 for (j = 0; j < fpathlen; j++)
761 *fpathptr++ = tricat(FPATH_DIR, "/", fpath_subdirs[j]);
762 # else
763 *fpathptr++ = ztrdup(FPATH_DIR);
764 # endif
765 # endif
766 *fpathptr = NULL;
767 #else
768 fpath = mkarray(NULL);
769 #endif
771 mailpath = mkarray(NULL);
772 watch = mkarray(NULL);
773 psvar = mkarray(NULL);
774 module_path = mkarray(ztrdup(MODULE_DIR));
775 modulestab = newmoduletable(17, "modules");
776 linkedmodules = znewlinklist();
778 /* Set default prompts */
779 if(unset(INTERACTIVE)) {
780 prompt = ztrdup("");
781 prompt2 = ztrdup("");
782 } else if (EMULATION(EMULATE_KSH|EMULATE_SH)) {
783 prompt = ztrdup(privasserted() ? "# " : "$ ");
784 prompt2 = ztrdup("> ");
785 } else {
786 prompt = ztrdup("%m%# ");
787 prompt2 = ztrdup("%_> ");
789 prompt3 = ztrdup("?# ");
790 prompt4 = EMULATION(EMULATE_KSH|EMULATE_SH)
791 ? ztrdup("+ ") : ztrdup("+%N:%i> ");
792 sprompt = ztrdup("zsh: correct '%R' to '%r' [nyae]? ");
794 ifs = ztrdup(DEFAULT_IFS);
795 wordchars = ztrdup(DEFAULT_WORDCHARS);
796 postedit = ztrdup("");
797 underscore = (char *) zalloc(underscorelen = 32);
798 underscoreused = 1;
799 *underscore = '\0';
801 zoptarg = ztrdup("");
802 zoptind = 1;
804 ppid = (zlong) getppid();
805 mypid = (zlong) getpid();
806 term = ztrdup("");
808 nullcmd = ztrdup("cat");
809 readnullcmd = ztrdup(DEFAULT_READNULLCMD);
811 /* We cache the uid so we know when to *
812 * recheck the info for `USERNAME' */
813 cached_uid = getuid();
815 /* Get password entry and set info for `USERNAME' */
816 #ifdef USE_GETPWUID
817 if ((pswd = getpwuid(cached_uid))) {
818 if (EMULATION(EMULATE_ZSH))
819 home = metafy(pswd->pw_dir, -1, META_DUP);
820 cached_username = ztrdup(pswd->pw_name);
822 else
823 #endif /* USE_GETPWUID */
825 if (EMULATION(EMULATE_ZSH))
826 home = ztrdup("/");
827 cached_username = ztrdup("");
831 * Try a cheap test to see if we can initialize `PWD' from `HOME'.
832 * In non-native emulations HOME must come from the environment;
833 * we're not allowed to set it locally.
835 if (EMULATION(EMULATE_ZSH))
836 ptr = home;
837 else
838 ptr = zgetenv("HOME");
839 if (ptr && ispwd(ptr))
840 pwd = ztrdup(ptr);
841 else if ((ptr = zgetenv("PWD")) && (strlen(ptr) < PATH_MAX) &&
842 (ptr = metafy(ptr, -1, META_STATIC), ispwd(ptr)))
843 pwd = ztrdup(ptr);
844 else
845 pwd = metafy(zgetcwd(), -1, META_DUP);
847 oldpwd = ztrdup(pwd); /* initialize `OLDPWD' = `PWD' */
849 inittyptab(); /* initialize the ztypes table */
850 initlextabs(); /* initialize lexing tables */
852 createreswdtable(); /* create hash table for reserved words */
853 createaliastables(); /* create hash tables for aliases */
854 createcmdnamtable(); /* create hash table for external commands */
855 createshfunctable(); /* create hash table for shell functions */
856 createbuiltintable(); /* create hash table for builtin commands */
857 createnameddirtable(); /* create hash table for named directories */
858 createparamtable(); /* create parameter hash table */
860 condtab = NULL;
861 wrappers = NULL;
863 #ifdef TIOCGWINSZ
864 adjustwinsize(0);
865 #else
866 /* columns and lines are normally zero, unless something different *
867 * was inhereted from the environment. If either of them are zero *
868 * the setiparam calls below set them to the defaults from termcap */
869 setiparam("COLUMNS", columns);
870 setiparam("LINES", lines);
871 #endif
873 #ifdef HAVE_GETRLIMIT
874 for (i = 0; i != RLIM_NLIMITS; i++) {
875 getrlimit(i, current_limits + i);
876 limits[i] = current_limits[i];
878 #endif
880 breaks = loops = 0;
881 lastmailcheck = time(NULL);
882 locallevel = sourcelevel = 0;
883 sfcontext = SFC_NONE;
884 trap_return = 0;
885 trap_state = TRAP_STATE_INACTIVE;
886 noerrexit = -1;
887 nohistsave = 1;
888 dirstack = znewlinklist();
889 bufstack = znewlinklist();
890 hsubl = hsubr = NULL;
891 lastpid = 0;
892 bshin = SHIN ? fdopen(SHIN, "r") : stdin;
893 if (isset(SHINSTDIN) && !SHIN && unset(INTERACTIVE)) {
894 #ifdef _IONBF
895 setvbuf(stdin, NULL, _IONBF, 0);
896 #else
897 setlinebuf(stdin);
898 #endif
901 get_usage();
903 /* Close the file descriptors we opened to block off 0 to 9 */
904 for (i = 0; i < 10; i++)
905 if (close_fds[i])
906 close(i);
908 /* Colour sequences for outputting colours in prompts and zle */
909 set_default_colour_sequences();
912 /* Initialize signal handling */
914 /**/
915 void
916 init_signals(void)
918 if (interact) {
919 int i;
920 signal_setmask(signal_mask(0));
921 for (i=0; i<NSIG; ++i)
922 signal_default(i);
924 sigchld_mask = signal_mask(SIGCHLD);
926 intr();
928 #ifndef QDEBUG
929 signal_ignore(SIGQUIT);
930 #endif
932 if (signal_ignore(SIGHUP) == SIG_IGN)
933 opts[HUP] = 0;
934 else
935 install_handler(SIGHUP);
936 install_handler(SIGCHLD);
937 #ifdef SIGWINCH
938 install_handler(SIGWINCH);
939 #endif
940 if (interact) {
941 install_handler(SIGALRM);
942 signal_ignore(SIGTERM);
944 if (jobbing) {
945 signal_ignore(SIGTTOU);
946 signal_ignore(SIGTSTP);
947 signal_ignore(SIGTTIN);
951 /* Source the init scripts. If called as "ksh" or "sh" *
952 * then we source the standard sh/ksh scripts instead of *
953 * the standard zsh scripts */
955 /**/
956 void
957 run_init_scripts(void)
959 noerrexit = -1;
961 if (EMULATION(EMULATE_KSH|EMULATE_SH)) {
962 if (islogin)
963 source("/etc/profile");
964 if (unset(PRIVILEGED)) {
965 char *s = getsparam("ENV");
966 if (islogin)
967 sourcehome(".profile");
968 noerrs = 2;
969 if (s && !parsestr(s)) {
970 singsub(&s);
971 noerrs = 0;
972 source(s);
974 noerrs = 0;
975 } else
976 source("/etc/suid_profile");
977 } else {
978 #ifdef GLOBAL_ZSHENV
979 source(GLOBAL_ZSHENV);
980 #endif
982 if (isset(RCS) && unset(PRIVILEGED))
984 if (isset(INTERACTIVE)) {
986 * Always attempt to load the newuser module to perform
987 * checks for new zsh users. Don't care if we can't load it.
989 if (!load_module("zsh/newuser", NULL, 1)) {
990 /* Unload it immediately. */
991 unload_named_module("zsh/newuser", "zsh", 1);
995 sourcehome(".zshenv");
997 if (islogin) {
998 #ifdef GLOBAL_ZPROFILE
999 if (isset(RCS) && isset(GLOBALRCS))
1000 source(GLOBAL_ZPROFILE);
1001 #endif
1002 if (isset(RCS) && unset(PRIVILEGED))
1003 sourcehome(".zprofile");
1005 if (interact) {
1006 #ifdef GLOBAL_ZSHRC
1007 if (isset(RCS) && isset(GLOBALRCS))
1008 source(GLOBAL_ZSHRC);
1009 #endif
1010 if (isset(RCS) && unset(PRIVILEGED))
1011 sourcehome(".zshrc");
1013 if (islogin) {
1014 #ifdef GLOBAL_ZLOGIN
1015 if (isset(RCS) && isset(GLOBALRCS))
1016 source(GLOBAL_ZLOGIN);
1017 #endif
1018 if (isset(RCS) && unset(PRIVILEGED))
1019 sourcehome(".zlogin");
1022 noerrexit = 0;
1023 nohistsave = 0;
1026 /* Miscellaneous initializations that happen after init scripts are run */
1028 /**/
1029 void
1030 init_misc(void)
1032 #ifndef RESTRICTED_R
1033 if ( restricted )
1034 #else
1035 if (*zsh_name == 'r' || restricted)
1036 #endif
1037 dosetopt(RESTRICTED, 1, 0);
1038 if (cmd) {
1039 if (SHIN >= 10)
1040 fclose(bshin);
1041 SHIN = movefd(open("/dev/null", O_RDONLY | O_NOCTTY));
1042 bshin = fdopen(SHIN, "r");
1043 execstring(cmd, 0, 1);
1044 stopmsg = 1;
1045 zexit(lastval, 0);
1048 if (interact && isset(RCS))
1049 readhistfile(NULL, 0, HFILE_USE_OPTIONS);
1052 /* source a file */
1054 /**/
1055 mod_export int
1056 source(char *s)
1058 Eprog prog;
1059 int tempfd = -1, fd, cj;
1060 zlong oldlineno;
1061 int oldshst, osubsh, oloops;
1062 FILE *obshin;
1063 char *old_scriptname = scriptname, *us;
1064 char *old_scriptfilename = scriptfilename;
1065 unsigned char *ocs;
1066 int ocsp;
1067 int otrap_return = trap_return, otrap_state = trap_state;
1068 struct funcstack fstack;
1070 if (!s ||
1071 (!(prog = try_source_file((us = unmeta(s)))) &&
1072 (tempfd = movefd(open(us, O_RDONLY | O_NOCTTY))) == -1)) {
1073 return 1;
1076 /* save the current shell state */
1077 fd = SHIN; /* store the shell input fd */
1078 obshin = bshin; /* store file handle for buffered shell input */
1079 osubsh = subsh; /* store whether we are in a subshell */
1080 cj = thisjob; /* store our current job number */
1081 oldlineno = lineno; /* store our current lineno */
1082 oloops = loops; /* stored the # of nested loops we are in */
1083 oldshst = opts[SHINSTDIN]; /* store current value of this option */
1084 ocs = cmdstack;
1085 ocsp = cmdsp;
1086 cmdstack = (unsigned char *) zalloc(CMDSTACKSZ);
1087 cmdsp = 0;
1089 if (!prog) {
1090 SHIN = tempfd;
1091 bshin = fdopen(SHIN, "r");
1093 subsh = 0;
1094 lineno = 1;
1095 loops = 0;
1096 dosetopt(SHINSTDIN, 0, 1);
1097 scriptname = s;
1098 scriptfilename = s;
1101 * The special return behaviour of traps shouldn't
1102 * trigger in files sourced from traps; the return
1103 * is just a return from the file.
1105 trap_state = TRAP_STATE_INACTIVE;
1107 sourcelevel++;
1109 fstack.name = scriptfilename;
1110 fstack.caller = funcstack ? funcstack->name :
1111 dupstring(old_scriptfilename ? old_scriptfilename : "zsh");
1112 fstack.flineno = 0;
1113 fstack.lineno = oldlineno;
1114 fstack.filename = scriptfilename;
1115 fstack.prev = funcstack;
1116 fstack.tp = FS_SOURCE;
1117 funcstack = &fstack;
1119 if (prog) {
1120 pushheap();
1121 errflag = 0;
1122 execode(prog, 1, 0);
1123 popheap();
1124 } else
1125 loop(0, 0); /* loop through the file to be sourced */
1126 funcstack = funcstack->prev;
1127 sourcelevel--;
1129 trap_state = otrap_state;
1130 trap_return = otrap_return;
1132 /* restore the current shell state */
1133 if (prog)
1134 freeeprog(prog);
1135 else {
1136 fclose(bshin);
1137 fdtable[SHIN] = FDT_UNUSED;
1138 SHIN = fd; /* the shell input fd */
1139 bshin = obshin; /* file handle for buffered shell input */
1141 subsh = osubsh; /* whether we are in a subshell */
1142 thisjob = cj; /* current job number */
1143 lineno = oldlineno; /* our current lineno */
1144 loops = oloops; /* the # of nested loops we are in */
1145 dosetopt(SHINSTDIN, oldshst, 1); /* SHINSTDIN option */
1146 errflag = 0;
1147 if (!exit_pending)
1148 retflag = 0;
1149 scriptname = old_scriptname;
1150 scriptfilename = old_scriptfilename;
1151 free(cmdstack);
1152 cmdstack = ocs;
1153 cmdsp = ocsp;
1155 return 0;
1158 /* Try to source a file in the home directory */
1160 /**/
1161 void
1162 sourcehome(char *s)
1164 char *h;
1166 queue_signals();
1167 if (EMULATION(EMULATE_SH|EMULATE_KSH) || !(h = getsparam("ZDOTDIR"))) {
1168 h = home;
1169 if (!h)
1170 return;
1174 /* Let source() complain if path is too long */
1175 VARARR(char, buf, strlen(h) + strlen(s) + 2);
1176 sprintf(buf, "%s/%s", h, s);
1177 unqueue_signals();
1178 source(buf);
1182 /**/
1183 void
1184 init_bltinmods(void)
1187 #include "bltinmods.list"
1189 (void)load_module("zsh/main", NULL, 0);
1192 /**/
1193 mod_export void
1194 noop_function(void)
1196 /* do nothing */
1199 /**/
1200 mod_export void
1201 noop_function_int(UNUSED(int nothing))
1203 /* do nothing */
1207 * ZLE entry point pointer.
1208 * No other source file needs to know which modules are linked in.
1210 /**/
1211 mod_export ZleEntryPoint zle_entry_ptr;
1214 * State of loading of zle.
1215 * 0 = Not loaded, not attempted.
1216 * 1 = Loaded successfully
1217 * 2 = Failed to load.
1219 /**/
1220 mod_export int zle_load_state;
1222 /**/
1223 mod_export char *
1224 zleentry(VA_ALIST1(int cmd))
1225 VA_DCL
1227 char *ret = NULL;
1228 va_list ap;
1229 VA_DEF_ARG(int cmd);
1231 VA_START(ap, cmd);
1232 VA_GET_ARG(ap, cmd, int);
1234 #if defined(LINKED_XMOD_zshQszle) || defined(UNLINKED_XMOD_zshQszle)
1235 /* autoload */
1236 switch (zle_load_state) {
1237 case 0:
1239 * Some commands don't require us to load ZLE.
1240 * These also have no fallback.
1242 if (cmd != ZLE_CMD_TRASH && cmd != ZLE_CMD_RESET_PROMPT &&
1243 cmd != ZLE_CMD_REFRESH)
1245 if (load_module("zsh/zle", NULL, 0) != 1) {
1246 (void)load_module("zsh/compctl", NULL, 0);
1247 ret = zle_entry_ptr(cmd, ap);
1248 /* Don't execute fallback code */
1249 cmd = -1;
1250 } else {
1251 zle_load_state = 2;
1252 /* Execute fallback code below */
1255 break;
1257 case 1:
1258 ret = zle_entry_ptr(cmd, ap);
1259 /* Don't execute fallback code */
1260 cmd = -1;
1261 break;
1263 case 2:
1264 /* Execute fallback code */
1265 break;
1267 #endif
1269 switch (cmd) {
1271 * Only the read command really needs a fallback if zle
1272 * is not available. ZLE_CMD_GET_LINE has traditionally
1273 * had local code in bufferwords() to do this, but that'
1274 * probably only because bufferwords() is part of completion
1275 * and so everything to do with it is horribly complicated.
1277 case ZLE_CMD_READ:
1279 char *pptbuf, **lp;
1280 int pptlen;
1282 lp = va_arg(ap, char **);
1284 pptbuf = unmetafy(promptexpand(lp ? *lp : NULL, 0, NULL, NULL,
1285 NULL),
1286 &pptlen);
1287 write(2, (WRITE_ARG_2_T)pptbuf, pptlen);
1288 free(pptbuf);
1290 ret = shingetline();
1291 break;
1294 case ZLE_CMD_GET_LINE:
1296 int *ll, *cs;
1298 ll = va_arg(ap, int *);
1299 cs = va_arg(ap, int *);
1300 *ll = *cs = 0;
1301 ret = ztrdup("");
1302 break;
1306 va_end(ap);
1307 return ret;
1310 /* compctl entry point pointers. Similar to the ZLE ones. */
1312 /**/
1313 mod_export CompctlReadFn compctlreadptr = fallback_compctlread;
1315 /**/
1316 mod_export int
1317 fallback_compctlread(char *name, UNUSED(char **args), UNUSED(Options ops), UNUSED(char *reply))
1319 zwarnnam(name, "option valid only in functions called from completion");
1320 return 1;
1324 * Used by zle to indicate it has already printed a "use 'exit' to exit"
1325 * message.
1327 /**/
1328 mod_export int use_exit_printed;
1331 * This is real main entry point. This has to be mod_export'ed
1332 * so zsh.exe can found it on Cygwin
1335 /**/
1336 mod_export int
1337 zsh_main(UNUSED(int argc), char **argv)
1339 char **t;
1340 int t0;
1341 #ifdef USE_LOCALE
1342 setlocale(LC_ALL, "");
1343 #endif
1345 init_jobs(argv, environ);
1348 * Provisionally set up the type table to allow metafication.
1349 * This will be done properly when we have decided if we are
1350 * interactive
1352 typtab['\0'] |= IMETA;
1353 typtab[STOUC(Meta) ] |= IMETA;
1354 typtab[STOUC(Marker)] |= IMETA;
1355 for (t0 = (int)STOUC(Pound); t0 <= (int)STOUC(Nularg); t0++)
1356 typtab[t0] |= ITOK | IMETA;
1358 for (t = argv; *t; *t = metafy(*t, -1, META_ALLOC), t++);
1360 zsh_name = argv[0];
1361 do {
1362 char *arg0 = zsh_name;
1363 if (!(zsh_name = strrchr(arg0, '/')))
1364 zsh_name = arg0;
1365 else
1366 zsh_name++;
1367 if (*zsh_name == '-')
1368 zsh_name++;
1369 if (strcmp(zsh_name, "su") == 0) {
1370 char *sh = zgetenv("SHELL");
1371 if (sh && *sh && arg0 != sh)
1372 zsh_name = sh;
1373 else
1374 break;
1375 } else
1376 break;
1377 } while (zsh_name);
1379 fdtable_size = zopenmax();
1380 fdtable = zshcalloc(fdtable_size*sizeof(*fdtable));
1382 createoptiontable();
1383 emulate(zsh_name, 1); /* initialises most options */
1384 opts[LOGINSHELL] = (**argv == '-');
1385 opts[MONITOR] = 1; /* may be unset in init_io() */
1386 opts[PRIVILEGED] = (getuid() != geteuid() || getgid() != getegid());
1387 opts[USEZLE] = 1; /* may be unset in init_io() */
1388 parseargs(argv); /* sets INTERACTIVE, SHINSTDIN and SINGLECOMMAND */
1390 SHTTY = -1;
1391 init_io();
1392 setupvals();
1393 init_signals();
1394 init_bltinmods();
1395 run_init_scripts();
1396 init_misc();
1398 for (;;) {
1400 * See if we can free up some of jobtab.
1401 * We only do this at top level, because if we are
1402 * executing stuff we may refer to them by job pointer.
1404 maybeshrinkjobtab();
1406 do {
1407 /* Reset return from top level which gets us back here */
1408 retflag = 0;
1409 loop(1,0);
1410 } while (tok != ENDINPUT && (tok != LEXERR || isset(SHINSTDIN)));
1411 if (tok == LEXERR) {
1412 /* Make sure a parse error exits with non-zero status */
1413 if (!lastval)
1414 lastval = 1;
1415 stopmsg = 1;
1416 zexit(lastval, 0);
1418 if (!(isset(IGNOREEOF) && interact)) {
1419 #if 0
1420 if (interact)
1421 fputs(islogin ? "logout\n" : "exit\n", shout);
1422 #endif
1423 zexit(lastval, 0);
1424 continue;
1426 noexitct++;
1427 if (noexitct >= 10) {
1428 stopmsg = 1;
1429 zexit(lastval, 0);
1432 * Don't print the message if it was already handled by
1433 * zle, since that makes special arrangements to keep
1434 * the display tidy.
1436 if (!use_exit_printed)
1437 zerrnam("zsh", (!islogin) ? "use 'exit' to exit."
1438 : "use 'logout' to logout.");