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
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.
42 /* buffer for $_ and its length */
48 int underscorelen
, underscoreused
;
50 /* what level of sourcing we are at */
55 /* the shell tty fd */
60 /* the FILE attached to the shell tty */
63 mod_export
FILE *shout
;
68 mod_export
char *tcstr
[TC_COUNT
];
70 /* lengths of each termcap string */
73 mod_export
int tclen
[TC_COUNT
];
75 /* Values of the li, co and am entries */
78 int tclines
, tccolumns
;
80 mod_export
int hasam
, hasxn
;
82 /* Value of the Co (max_colors) entry: may not be set */
85 mod_export
int tccolours
;
90 mod_export sigset_t sigchld_mask
;
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 */
103 loop(int toplevel
, int justonce
)
112 if (stophist
== 3) /* re-entry via preprompt() */
114 hbegin(1); /* init history mech */
115 if (isset(SHINSTDIN
)) {
117 if (interact
&& toplevel
) {
118 int hstop
= stophist
;
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 */
133 if ((tok
== ENDINPUT
&& !errflag
) ||
134 (tok
== LEXERR
&& (!isset(SHINSTDIN
) || !toplevel
)) ||
139 * Something down there (a ZLE function?) decided
140 * to exit when there was stuff to clear up.
144 zexit(exit_pending
>> 1, 0);
146 if (tok
== LEXERR
&& !lastval
)
154 (getshfunc("preexec") ||
155 paramtab
->getnode(paramtab
, "preexec" HOOK_SUFFIX
))) {
160 * As we're about to freeheap() or popheap()
161 * anyway, there's no gain in using permanent
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
);
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() */
181 if (stopmsg
) /* unset 'you have stopped jobs' flag */
188 if (ferror(stderr
)) {
192 if (subsh
) /* how'd we get this far in a subshell? */
194 if (((!interact
|| sourcelevel
) && errflag
) || retflag
)
196 if (isset(SINGLECOMMAND
) && toplevel
) {
197 if (sigtrapped
[SIGEXIT
])
210 static int restricted
;
214 parseargs(char **argv
)
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 *
231 opts
[INTERACTIVE
] = isatty(0) ? 2 : 0;
233 opts
[SINGLECOMMAND
] = 0;
235 /* loop through command line options (begins with "-" or "+") */
236 while (!optionbreak
&& *argv
&& (**argv
== '-' || **argv
== '+')) {
238 action
= (**argv
== '-');
244 /* The pseudo-option `--' signifies the end of options. */
248 if(*argv
!= args
+1 || **argv
!= '-')
249 goto badoptionstring
;
250 /* GNU-style long options */
252 if (!strcmp(*argv
, "version")) {
253 printf("zsh %s (%s-%s-%s)\n",
254 ZSH_VERSION
, MACHTYPE
, VENDOR
, OSTYPE
);
257 if (!strcmp(*argv
, "help")) {
261 /* `-' characters are allowed in long options */
262 for(args
= *argv
; *args
; args
++)
268 if (unset(SHOPTIONLETTERS
) && **argv
== 'b') {
269 /* -b ends options at the end of this argument */
271 } else if (**argv
== 'c') {
274 opts
[INTERACTIVE
] &= 1;
275 scriptname
= scriptfilename
= ztrdup("zsh");
276 } else if (**argv
== 'o') {
280 zerr("string expected after -o");
284 if (!(optno
= optlookup(*argv
))) {
285 zerr("no such option: %s", *argv
);
287 } else if (optno
== RESTRICTED
)
290 dosetopt(optno
, action
, 1);
292 } else if (isspace(STOUC(**argv
))) {
293 /* zsh's typtab not yet set, have to use ctype */
295 if (!isspace(STOUC(**argv
))) {
297 zerr("bad option string: `%s'", args
);
302 if (!(optno
= optlookupc(**argv
))) {
303 zerr("bad option: -%c", **argv
);
305 } else if (optno
== RESTRICTED
)
308 dosetopt(optno
, action
, 1);
314 paramlist
= znewlinklist();
317 zerr("string expected after -%s", cmd
);
323 if (unset(SHINSTDIN
)) {
325 SHIN
= movefd(open(unmeta(*argv
), O_RDONLY
| O_NOCTTY
));
327 zerr("can't open input file: %s", *argv
);
330 opts
[INTERACTIVE
] &= 1;
332 scriptfilename
= argzero
;
336 zaddlinknode(paramlist
, ztrdup(*argv
++));
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
)));
346 argzero
= ztrdup(argzero
);
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");
373 static char outbuf
[BUFSIZ
], errbuf
[BUFSIZ
];
375 #ifdef RSH_BUG_WORKAROUND
379 /* stdout, stderr fully buffered */
381 setvbuf(stdout
, outbuf
, _IOFBF
, BUFSIZ
);
382 setvbuf(stderr
, errbuf
, _IOFBF
, BUFSIZ
);
384 setbuffer(stdout
, outbuf
, BUFSIZ
);
385 setbuffer(stderr
, errbuf
, BUFSIZ
);
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
392 for (i
= 3; i
< 10; i
++)
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
412 /* Send xtrace output to stderr -- see execcmd() */
415 /* Make sure the tty is opened read/write. */
418 if ((ttystrname
= ztrdup(ttyname(0)))) {
419 SHTTY
= movefd(open(ttystrname
, O_RDWR
| O_NOCTTY
));
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);
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)
448 #define rdwrtty(fd) 1
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) {
457 ttystrname
= ztrdup(ttyname(1));
460 (SHTTY
= movefd(open("/dev/tty", O_RDWR
| O_NOCTTY
))) != -1) {
462 ttystrname
= ztrdup(ttyname(SHTTY
));
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 */
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] */
499 static char shoutbuf
[BUFSIZ
];
500 #if defined(JOB_CONTROL) && defined(TIOCSETD) && defined(NTTYDISC)
506 /* Since we're interative, it's nice to have somewhere to write. */
511 #if defined(JOB_CONTROL) && defined(TIOCSETD) && defined(NTTYDISC)
513 ioctl(SHTTY
, TIOCSETD
, (char *)&ldisc
);
516 /* Associate terminal file descriptor with a FILE pointer */
517 shout
= fdopen(SHTTY
, "w");
519 setvbuf(shout
, shoutbuf
, _IOFBF
, BUFSIZ
);
522 gettyinfo(&shttyinfo
); /* get tty state */
524 if (shttyinfo
.tio
.c_cc
[VSWTCH
] <= 0) /* hack for irises */
525 shttyinfo
.tio
.c_cc
[VSWTCH
] = CSWTCH
;
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 */
544 #ifndef TGETENT_ACCEPTS_NULL
545 static char termbuf
[2048]; /* the termcap buffer */
549 termflags
|= TERM_UNKNOWN
;
553 /* unset zle if using zsh under emacs */
554 if (!strcmp(term
, "emacs"))
557 #ifdef TGETENT_ACCEPTS_NULL
558 /* If possible, we let tgetent allocate its own termcap buffer */
559 if (tgetent(NULL
, term
) != TGETENT_SUCCESS
)
561 if (tgetent(termbuf
, term
) != TGETENT_SUCCESS
)
564 if (isset(INTERACTIVE
))
565 zerr("can't find terminal definition for %s", term
);
567 termflags
|= TERM_BAD
;
570 char tbuf
[1024], *pp
;
573 termflags
&= ~TERM_BAD
;
574 termflags
&= ~TERM_UNKNOWN
;
575 for (t0
= 0; t0
!= TC_COUNT
; t0
++) {
578 /* AIX tgetstr() ignores second argument */
579 if (!(pp
= tgetstr(tccapnams
[t0
], &pp
)))
580 tcstr
[t0
] = NULL
, tclen
[t0
] = 0;
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 *
600 termflags
&= ~TERM_NOUP
;
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') {
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;
644 /* Initialize lots of global variables and hash tables */
653 struct timezone dummy_tz
;
656 #if defined(SITEFPATH_DIR) || defined(FPATH_DIR)
658 # if defined(FPATH_DIR) && defined(FPATH_SUBDIRS)
659 char *fpath_subdirs
[] = FPATH_SUBDIRS
;
661 # ifdef SITEFPATH_DIR
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 */
686 /* j is current fd */
689 else if (i
< tmppipe
[1])
709 (void)addhookdefs(NULL
, zshhooks
, sizeof(zshhooks
)/sizeof(*zshhooks
));
713 zero_mnumber
.type
= MN_INTEGER
;
714 zero_mnumber
.u
.l
= 0;
719 histsiz
= DEFAULT_HISTSIZE
;
722 cmdstack
= (unsigned char *) zalloc(CMDSTACKSZ
);
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");
741 cdpath
= mkarray(NULL
);
742 manpath
= mkarray(NULL
);
743 fignore
= mkarray(NULL
);
745 #if defined(SITEFPATH_DIR) || defined(FPATH_DIR)
747 # ifdef FPATH_SUBDIRS
748 fpathlen
+= sizeof(fpath_subdirs
)/sizeof(char *);
753 fpath
= fpathptr
= (char **)zalloc((fpathlen
+1)*sizeof(char *));
754 # ifdef SITEFPATH_DIR
755 *fpathptr
++ = ztrdup(SITEFPATH_DIR
);
759 # ifdef FPATH_SUBDIRS
760 for (j
= 0; j
< fpathlen
; j
++)
761 *fpathptr
++ = tricat(FPATH_DIR
, "/", fpath_subdirs
[j
]);
763 *fpathptr
++ = ztrdup(FPATH_DIR
);
768 fpath
= mkarray(NULL
);
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
)) {
781 prompt2
= ztrdup("");
782 } else if (EMULATION(EMULATE_KSH
|EMULATE_SH
)) {
783 prompt
= ztrdup(privasserted() ? "# " : "$ ");
784 prompt2
= ztrdup("> ");
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);
801 zoptarg
= ztrdup("");
804 ppid
= (zlong
) getppid();
805 mypid
= (zlong
) getpid();
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' */
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
);
823 #endif /* USE_GETPWUID */
825 if (EMULATION(EMULATE_ZSH
))
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
))
838 ptr
= zgetenv("HOME");
839 if (ptr
&& ispwd(ptr
))
841 else if ((ptr
= zgetenv("PWD")) && (strlen(ptr
) < PATH_MAX
) &&
842 (ptr
= metafy(ptr
, -1, META_STATIC
), ispwd(ptr
)))
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 */
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
);
873 #ifdef HAVE_GETRLIMIT
874 for (i
= 0; i
!= RLIM_NLIMITS
; i
++) {
875 getrlimit(i
, current_limits
+ i
);
876 limits
[i
] = current_limits
[i
];
881 lastmailcheck
= time(NULL
);
882 locallevel
= sourcelevel
= 0;
883 sfcontext
= SFC_NONE
;
885 trap_state
= TRAP_STATE_INACTIVE
;
888 dirstack
= znewlinklist();
889 bufstack
= znewlinklist();
890 hsubl
= hsubr
= NULL
;
892 bshin
= SHIN
? fdopen(SHIN
, "r") : stdin
;
893 if (isset(SHINSTDIN
) && !SHIN
&& unset(INTERACTIVE
)) {
895 setvbuf(stdin
, NULL
, _IONBF
, 0);
903 /* Close the file descriptors we opened to block off 0 to 9 */
904 for (i
= 0; i
< 10; i
++)
908 /* Colour sequences for outputting colours in prompts and zle */
909 set_default_colour_sequences();
912 /* Initialize signal handling */
920 signal_setmask(signal_mask(0));
921 for (i
=0; i
<NSIG
; ++i
)
924 sigchld_mask
= signal_mask(SIGCHLD
);
929 signal_ignore(SIGQUIT
);
932 if (signal_ignore(SIGHUP
) == SIG_IGN
)
935 install_handler(SIGHUP
);
936 install_handler(SIGCHLD
);
938 install_handler(SIGWINCH
);
941 install_handler(SIGALRM
);
942 signal_ignore(SIGTERM
);
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 */
957 run_init_scripts(void)
961 if (EMULATION(EMULATE_KSH
|EMULATE_SH
)) {
963 source("/etc/profile");
964 if (unset(PRIVILEGED
)) {
965 char *s
= getsparam("ENV");
967 sourcehome(".profile");
969 if (s
&& !parsestr(s
)) {
976 source("/etc/suid_profile");
979 source(GLOBAL_ZSHENV
);
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");
998 #ifdef GLOBAL_ZPROFILE
999 if (isset(RCS
) && isset(GLOBALRCS
))
1000 source(GLOBAL_ZPROFILE
);
1002 if (isset(RCS
) && unset(PRIVILEGED
))
1003 sourcehome(".zprofile");
1007 if (isset(RCS
) && isset(GLOBALRCS
))
1008 source(GLOBAL_ZSHRC
);
1010 if (isset(RCS
) && unset(PRIVILEGED
))
1011 sourcehome(".zshrc");
1014 #ifdef GLOBAL_ZLOGIN
1015 if (isset(RCS
) && isset(GLOBALRCS
))
1016 source(GLOBAL_ZLOGIN
);
1018 if (isset(RCS
) && unset(PRIVILEGED
))
1019 sourcehome(".zlogin");
1026 /* Miscellaneous initializations that happen after init scripts are run */
1032 #ifndef RESTRICTED_R
1035 if (*zsh_name
== 'r' || restricted
)
1037 dosetopt(RESTRICTED
, 1, 0);
1041 SHIN
= movefd(open("/dev/null", O_RDONLY
| O_NOCTTY
));
1042 bshin
= fdopen(SHIN
, "r");
1043 execstring(cmd
, 0, 1);
1048 if (interact
&& isset(RCS
))
1049 readhistfile(NULL
, 0, HFILE_USE_OPTIONS
);
1059 int tempfd
= -1, fd
, cj
;
1061 int oldshst
, osubsh
, oloops
;
1063 char *old_scriptname
= scriptname
, *us
;
1064 char *old_scriptfilename
= scriptfilename
;
1067 int otrap_return
= trap_return
, otrap_state
= trap_state
;
1068 struct funcstack fstack
;
1071 (!(prog
= try_source_file((us
= unmeta(s
)))) &&
1072 (tempfd
= movefd(open(us
, O_RDONLY
| O_NOCTTY
))) == -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 */
1086 cmdstack
= (unsigned char *) zalloc(CMDSTACKSZ
);
1091 bshin
= fdopen(SHIN
, "r");
1096 dosetopt(SHINSTDIN
, 0, 1);
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
;
1109 fstack
.name
= scriptfilename
;
1110 fstack
.caller
= funcstack
? funcstack
->name
:
1111 dupstring(old_scriptfilename
? old_scriptfilename
: "zsh");
1113 fstack
.lineno
= oldlineno
;
1114 fstack
.filename
= scriptfilename
;
1115 fstack
.prev
= funcstack
;
1116 fstack
.tp
= FS_SOURCE
;
1117 funcstack
= &fstack
;
1122 execode(prog
, 1, 0);
1125 loop(0, 0); /* loop through the file to be sourced */
1126 funcstack
= funcstack
->prev
;
1129 trap_state
= otrap_state
;
1130 trap_return
= otrap_return
;
1132 /* restore the current shell state */
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 */
1149 scriptname
= old_scriptname
;
1150 scriptfilename
= old_scriptfilename
;
1158 /* Try to source a file in the home directory */
1167 if (EMULATION(EMULATE_SH
|EMULATE_KSH
) || !(h
= getsparam("ZDOTDIR"))) {
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
);
1184 init_bltinmods(void)
1187 #include "bltinmods.list"
1189 (void)load_module("zsh/main", NULL
, 0);
1201 noop_function_int(UNUSED(int nothing
))
1207 * ZLE entry point pointer.
1208 * No other source file needs to know which modules are linked in.
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.
1220 mod_export
int zle_load_state
;
1224 zleentry(VA_ALIST1(int cmd
))
1229 VA_DEF_ARG(int cmd
);
1232 VA_GET_ARG(ap
, cmd
, int);
1234 #if defined(LINKED_XMOD_zshQszle) || defined(UNLINKED_XMOD_zshQszle)
1236 switch (zle_load_state
) {
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 */
1252 /* Execute fallback code below */
1258 ret
= zle_entry_ptr(cmd
, ap
);
1259 /* Don't execute fallback code */
1264 /* Execute fallback code */
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.
1282 lp
= va_arg(ap
, char **);
1284 pptbuf
= unmetafy(promptexpand(lp
? *lp
: NULL
, 0, NULL
, NULL
,
1287 write(2, (WRITE_ARG_2_T
)pptbuf
, pptlen
);
1290 ret
= shingetline();
1294 case ZLE_CMD_GET_LINE
:
1298 ll
= va_arg(ap
, int *);
1299 cs
= va_arg(ap
, int *);
1310 /* compctl entry point pointers. Similar to the ZLE ones. */
1313 mod_export CompctlReadFn compctlreadptr
= fallback_compctlread
;
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");
1324 * Used by zle to indicate it has already printed a "use 'exit' to exit"
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
1337 zsh_main(UNUSED(int argc
), char **argv
)
1342 setlocale(LC_ALL
, "");
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
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
++);
1362 char *arg0
= zsh_name
;
1363 if (!(zsh_name
= strrchr(arg0
, '/')))
1367 if (*zsh_name
== '-')
1369 if (strcmp(zsh_name
, "su") == 0) {
1370 char *sh
= zgetenv("SHELL");
1371 if (sh
&& *sh
&& arg0
!= sh
)
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 */
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();
1407 /* Reset return from top level which gets us back here */
1410 } while (tok
!= ENDINPUT
&& (tok
!= LEXERR
|| isset(SHINSTDIN
)));
1411 if (tok
== LEXERR
) {
1412 /* Make sure a parse error exits with non-zero status */
1418 if (!(isset(IGNOREEOF
) && interact
)) {
1421 fputs(islogin
? "logout\n" : "exit\n", shout
);
1427 if (noexitct
>= 10) {
1432 * Don't print the message if it was already handled by
1433 * zle, since that makes special arrangements to keep
1436 if (!use_exit_printed
)
1437 zerrnam("zsh", (!islogin
) ? "use 'exit' to exit."
1438 : "use 'logout' to logout.");