386BSD 0.1 development
[unix-history] / usr / othersrc / public / zsh-2.2 / src / init.c
CommitLineData
dbf02a84
WJ
1/*
2 *
3 * init.c - main loop and initialization routines
4 *
5 * This file is part of zsh, the Z shell.
6 *
7 * This software is Copyright 1992 by Paul Falstad
8 *
9 * Permission is hereby granted to copy, reproduce, redistribute or otherwise
10 * use this software as long as: there is no monetary profit gained
11 * specifically from the use or reproduction of this software, it is not
12 * sold, rented, traded or otherwise marketed, and this copyright notice is
13 * included prominently in any copy made.
14 *
15 * The author make no claims as to the fitness or correctness of this software
16 * for any use whatsoever, and it is provided as is. Any use of this software
17 * is at the user's own risk.
18 *
19 */
20
21#define GLOBALS
22#include "zsh.h"
23#include <pwd.h>
24
25void main(argc,argv,envp) /**/
26int argc; char **argv; char **envp;
27{
28int notect = 0;
29
30#ifdef LC_ALL
31 setlocale(LC_ALL, "");
32#endif
33 environ = envp;
34 meminit();
35 setflags();
36 parseargs(argv);
37 setmoreflags();
38 setupvals();
39 initialize();
40 heapalloc();
41 runscripts();
42 for(;;)
43 {
44 do
45 loop();
46 while (tok != ENDINPUT);
47 if (!(isset(IGNOREEOF) && interact))
48 {
49#if 0
50 if (interact)
51 fputs(islogin ? "logout\n" : "exit\n",stderr);
52#endif
53 zexit(NULL);
54 continue;
55 }
56 zerrnam("zsh",(!islogin) ? "use 'exit' to exit."
57 : "use 'logout' to logout.",NULL,0);
58 notect++;
59 if (notect == 10)
60 zexit(NULL);
61 }
62}
63
64/* keep executing lists until EOF found */
65
66void loop() /**/
67{
68List list;
69Heap h = (Heap) peekfirst(heaplist);
70
71 pushheap();
72 for(;;)
73 {
74 freeheap();
75 if (interact && isset(SHINSTDIN))
76 preprompt();
77 hbegin(); /* init history mech */
78 intr(); /* interrupts on */
79 ainit(); /* init alias mech */
80 lexinit();
81 errflag = 0;
82 if (!(list = parse_event()))
83 { /* if we couldn't parse a list */
84 hend();
85 if (tok == ENDINPUT && !errflag)
86 break;
87 continue;
88 }
89 if (hend())
90 {
91 if (stopmsg) /* unset 'you have stopped jobs' flag */
92 stopmsg--;
93 execlist(list);
94 }
95 if (ferror(stderr))
96 {
97 zerr("write error",NULL,0);
98 clearerr(stderr);
99 }
100 if (subsh) /* how'd we get this far in a subshell? */
101 exit(lastval);
102 if ((!interact && errflag) || retflag)
103 break;
104 if ((opts['t'] == OPT_SET) || (lastval && opts[ERREXIT] == OPT_SET))
105 {
106 if (sigtrapped[SIGEXIT])
107 dotrap(SIGEXIT);
108 exit(lastval);
109 }
110 }
111 while ((Heap) peekfirst(heaplist) != h)
112 popheap();
113}
114
115void setflags() /**/
116{
117int c;
118
119 for (c = 0; c != 32; c++) opts[c] = OPT_UNSET;
120 for (c = 32; c != 128; c++) opts[c] = OPT_INVALID;
121 for (c = 'a'; c <= 'z'; c++) opts[c] = opts[c-'a'+'A'] = OPT_UNSET;
122 for (c = '0'; c <= '9'; c++) opts[c] = OPT_UNSET;
123 opts['A'] = OPT_INVALID;
124 opts['i'] = (isatty(0)) ? OPT_SET : OPT_UNSET;
125 opts[BGNICE] = opts[NOTIFY] = OPT_SET;
126 opts[USEZLE] = (interact && SHTTY != -1) ? OPT_SET : OPT_UNSET;
127 opts[HASHCMDS] = opts[HASHLISTALL] = opts[HASHDIRS] = OPT_SET;
128}
129
130static char *cmd;
131
132void parseargs(argv) /**/
133char **argv;
134{
135char **x;
136int bk = 0,action;
137Lklist paramlist;
138
139 hackzero = argzero = *argv;
140 opts[LOGINSHELL] = (**(argv++) == '-') ? OPT_SET : OPT_UNSET;
141 SHIN = 0;
142 while (!bk && *argv && (**argv == '-' || **argv == '+'))
143 {
144 action = (**argv == '-') ? OPT_SET : OPT_UNSET;
145 while (*++*argv) {
146 if (opts[**argv] == OPT_INVALID) {
147 zerr("bad option: -%c",NULL,**argv);
148 exit(1);
149 }
150 if (bk = **argv == 'b') break;
151 if (**argv == 'c') { /* -c command */
152 argv++;
153 if (!*argv) {
154 zerr("string expected after -c",NULL,0);
155 exit(1);
156 }
157 cmd = *argv;
158 opts[INTERACTIVE] = OPT_UNSET;
159 opts['c'] = OPT_SET;
160 break;
161 } else if (**argv == 'o') {
162 int c;
163
164 if (!*++*argv)
165 argv++;
166 if (!*argv) {
167 zerr("string expected after -o",NULL,0);
168 exit(1);
169 }
170 c = optlookup(*argv);
171 if (c == -1)
172 zerr("no such option: %s",*argv,0);
173 else
174 opts[c] = action;
175 break;
176 } else opts[**argv] = action;
177 }
178 argv++;
179 }
180 paramlist = newlist();
181 if (*argv)
182 {
183 if (opts[SHINSTDIN] == OPT_UNSET)
184 {
185 SHIN = movefd(open(argzero = *argv,O_RDONLY));
186 if (SHIN == -1)
187 {
188 zerr("can't open input file: %s",*argv,0);
189 exit(1);
190 }
191 opts[INTERACTIVE] = OPT_UNSET;
192 argv++;
193 }
194 while (*argv)
195 addnode(paramlist,ztrdup(*argv++));
196 }
197 else
198 opts[SHINSTDIN] = OPT_SET;
199 pparams = x = zcalloc((countnodes(paramlist)+1)*sizeof(char *));
200 while (*x++ = getnode(paramlist));
201 free(paramlist);
202 argzero = ztrdup(argzero);
203}
204
205void setmoreflags() /**/
206{
207int t0;
208long ttpgrp;
209
210 /* stdout,stderr fully buffered */
211#ifdef _IOFBF
212 setvbuf(stdout,malloc(BUFSIZ),_IOFBF,BUFSIZ);
213 setvbuf(stderr,malloc(BUFSIZ),_IOFBF,BUFSIZ);
214#else
215 setbuffer(stdout,malloc(BUFSIZ),BUFSIZ);
216 setbuffer(stderr,malloc(BUFSIZ),BUFSIZ);
217#endif
218 subsh = 0;
219#ifndef NOCLOSEFUNNYFDS
220 /* this works around a bug in some versions of in.rshd */
221 for (t0 = 3; t0 != 10; t0++)
222 close(t0);
223#endif
224#ifdef JOB_CONTROL
225 opts[MONITOR] = (interact) ? OPT_SET : OPT_UNSET;
226 if (jobbing) {
227 SHTTY = movefd((isatty(0)) ? dup(0) : open("/dev/tty",O_RDWR));
228 if (SHTTY == -1)
229 opts[MONITOR] = OPT_UNSET;
230 else {
231#ifdef TIOCSETD
232#ifdef NTTYDISC
233 int ldisc = NTTYDISC;
234 ioctl(SHTTY, TIOCSETD, &ldisc);
235#endif
236#endif
237 gettyinfo(&shttyinfo); /* get tty state */
238#ifdef sgi
239 if (shttyinfo.tio.c_cc[VSWTCH] <= 0) /* hack for irises */
240 shttyinfo.tio.c_cc[VSWTCH] = CSWTCH;
241#endif
242 savedttyinfo = shttyinfo;
243 }
244#ifdef sgi
245 setpgrp(0,getpgrp(0));
246#endif
247 if ((mypgrp = getpgrp(0)) <= 0)
248 opts[MONITOR] = OPT_UNSET;
249 else while ((ttpgrp = gettygrp()) != -1 && ttpgrp != mypgrp) {
250 sleep(1);
251 mypgrp = getpgrp(0);
252 if (mypgrp == gettygrp()) break;
253 killpg(mypgrp,SIGTTIN);
254 mypgrp = getpgrp(0);
255 }
256 } else
257 SHTTY = -1;
258#else
259 opts[MONITOR] = OPT_UNSET;
260 SHTTY = movefd((isatty(0)) ? dup(0) : open("/dev/tty",O_RDWR));
261 if (SHTTY != -1) {
262 gettyinfo(&shttyinfo);
263 savedttyinfo = shttyinfo;
264 }
265#endif
266}
267
268void setupvals() /**/
269{
270struct passwd *pswd;
271char *ptr,*s;
272static long bauds[] = {
273 0,50,75,110,134,150,200,300,600,1200,1800,2400,4800,9600,19200,38400
274 };
275
276 curhist = 0;
277 histsiz = DEFAULT_HISTSIZE;
278 lithistsiz = 5;
279 inithist();
280 mailcheck = logcheck = 60;
281 dirstacksize = -1;
282 listmax = 100;
283 reporttime = -1;
284 bangchar = '!';
285 hashchar = '#';
286 hatchar = '^';
287 termok = 0;
288 curjob = prevjob = coprocin = coprocout = -1;
289 shtimer = time(NULL); /* init $SECONDS */
290 srand((unsigned int) shtimer);
291 /* build various hash tables; argument to newhtable is table size */
292 aliastab = newhtable(37);
293 addreswords();
294 paramtab = newhtable(151);
295 cmdnamtab = newhtable(37);
296 compctltab = newhtable(13);
297 initxbindtab();
298 nullcmd = ztrdup("cat");
299 readnullcmd = ztrdup("more");
300 prompt = ztrdup("%m%# ");
301 prompt2 = ztrdup("> ");
302 prompt3 = ztrdup("?# ");
303 prompt4 = ztrdup("+ ");
304 sprompt = ztrdup("zsh: correct `%R' to `%r' [nyae]? ");
305 term = ztrdup("");
306 ppid = getppid();
307#ifdef TIO
308#ifdef HAS_TCCRAP
309 baud = cfgetospeed(&shttyinfo.tio);
310 if (baud < 100) baud = bauds[baud]; /* aren't "standards" great?? */
311#else
312 baud = bauds[shttyinfo.tio.c_cflag & CBAUD];
313#endif
314#else
315 baud = bauds[shttyinfo.sgttyb.sg_ospeed];
316#endif
317#ifdef TIOCGWINSZ
318 if (!(columns = shttyinfo.winsize.ws_col))
319 columns = 80;
320 if (!(lines = shttyinfo.winsize.ws_row))
321 lines = 24;
322#else
323 columns = 80;
324 lines = 24;
325#endif
326 ifs = ztrdup(" \t\n");
327 if (pswd = getpwuid(getuid())) {
328 username = ztrdup(pswd->pw_name);
329 home = ztrdup(pswd->pw_dir);
330 } else {
331 username = ztrdup("");
332 home = ztrdup("/");
333 }
334 if (ptr = zgetenv("LOGNAME"))
335 logname = ztrdup(ptr);
336 else
337 logname = ztrdup(username);
338 timefmt = ztrdup(DEFTIMEFMT);
339 watchfmt = ztrdup(DEFWATCHFMT);
340 if (!(ttystrname = ztrdup(ttyname(SHTTY))))
341 ttystrname = ztrdup("");
342 wordchars = ztrdup(DEFWORDCHARS);
343 fceditparam = ztrdup(DEFFCEDIT);
344 tmpprefix = ztrdup(DEFTMPPREFIX);
345 postedit = ztrdup("");
346 if (ispwd(home)) pwd = ztrdup(home);
347 else if ((ptr = zgetenv("PWD")) && ispwd(ptr)) pwd = ztrdup(ptr);
348 else pwd = zgetwd();
349 oldpwd = ztrdup(pwd);
350 hostnam = zalloc(256);
351 underscore = ztrdup("");
352 gethostname(hostnam,256);
353 mypid = getpid();
354 cdpath = mkarray(NULL);
355 manpath = mkarray(NULL);
356 fignore = mkarray(NULL);
357 fpath = mkarray(NULL);
358 mailpath = mkarray(NULL);
359 watch = mkarray(NULL);
360 hosts = mkarray(NULL);
361 compctlsetup();
362 userdirs = (char **) zcalloc(sizeof(char *)*2);
363 usernames = (char **) zcalloc(sizeof(char *)*2);
364 userdirsz = 2;
365 userdirct = 0;
366 optarg = ztrdup("");
367 zoptind = 1;
368 schedcmds = NULL;
369 path = (char **) zalloc(4*sizeof *path);
370 path[0] = ztrdup("/bin"); path[1] = ztrdup("/usr/bin");
371 path[2] = ztrdup("/usr/ucb"); path[3] = NULL;
372 inittyptab();
373 initlextabs();
374 setupparams();
375 setparams();
376 inittyptab();
377 if ((s = zgetenv("EMACS")) && !strcmp(s,"t") && !strcmp(term,"emacs"))
378 opts[USEZLE] = OPT_UNSET;
379#ifndef HAS_RUSAGE
380 times(&shtms);
381#endif
382}
383
384void compctlsetup() /**/
385{
386static char
387 *hs[] = {"telnet","rlogin","ftp","rup","rusers","rsh",NULL},
388 *os[] = {"setopt","unsetopt",NULL},
389 *vs[] = {"export","typeset","vared","unset",NULL},
390 *cs[] = {"which","builtin",NULL},
391 *bs[] = {"bindkey",NULL};
392
393 compctl_process(hs,CC_HOSTS|CC_FILES,NULL);
394 compctl_process(os,CC_OPTIONS,NULL);
395 compctl_process(vs,CC_VARS,NULL);
396 compctl_process(bs,CC_BINDINGS,NULL);
397 compctl_process(cs,CC_COMMPATH,NULL);
398 cc_compos.mask = CC_COMMPATH;
399 cc_default.mask = CC_FILES;
400}
401
402void initialize() /**/
403{
404int t0;
405
406 breaks = loops = 0;
407 lastmailcheck = time(NULL);
408 locallist = NULL;
409 dirstack = newlist();
410 bufstack = newlist();
411 newcmdnamtab();
412 inbuf = zalloc(inbufsz = 256);
413 inbufptr = inbuf+inbufsz;
414 inbufct = 0;
415#ifndef QDEBUG
416 signal(SIGQUIT,SIG_IGN);
417#endif
418#ifdef RLIM_INFINITY
419 for (t0 = 0; t0 != RLIM_NLIMITS; t0++)
420 getrlimit(t0,limits+t0);
421#endif
422 hsubl = hsubr = NULL;
423 lastpid = 0;
424 bshin = fdopen(SHIN,"r");
425 signal(SIGCHLD,handler);
426 if (jobbing)
427 {
428 int ttypgrp;
429 for (;;)
430 {
431#ifdef TIOCGPGRP
432 ioctl(SHTTY, TIOCGPGRP, &ttypgrp);
433#else
434 ttypgrp = tcgetpgrp(SHTTY);
435#endif
436 if (ttypgrp == mypgrp)
437 break;
438 kill(0,SIGTTIN);
439 }
440 signal(SIGTTOU,SIG_IGN);
441 signal(SIGTSTP,SIG_IGN);
442 signal(SIGTTIN,SIG_IGN);
443 signal(SIGPIPE,SIG_IGN);
444 attachtty(mypgrp);
445 }
446 if (interact)
447 {
448 signal(SIGTERM,SIG_IGN);
449#ifdef SIGWINCH
450 signal(SIGWINCH,handler);
451#endif
452 signal(SIGALRM,handler);
453 intr();
454 }
455}
456
457void addreswords() /**/
458{
459static char *reswds[] = {
460 "do", "done", "esac", "then", "elif", "else", "fi", "for", "case",
461 "if", "while", "function", "repeat", "time", "until", "exec", "command",
462 "select", "coproc", "noglob", "-", "nocorrect", "foreach", "end", NULL
463 };
464int t0;
465
466 for (t0 = 0; reswds[t0]; t0++)
467 addhperm(reswds[t0],mkanode(NULL,-1-t0),aliastab,NULL);
468}
469
470void runscripts() /**/
471{
472#ifdef GLOBALZSHENV
473 source(GLOBALZSHENV);
474#endif
475 if (opts[NORCS] == OPT_SET) {
476#ifdef GLOBALZPROFILE
477 if (islogin) source(GLOBALZPROFILE);
478#endif
479#ifdef GLOBALZSHRC
480 source(GLOBALZSHRC);
481#endif
482#ifdef GLOBALZLOGIN
483 if (islogin) source(GLOBALZLOGIN);
484#endif
485 } else {
486 sourcehome(".zshenv");
487 if (opts[NORCS] == OPT_SET)
488 return;
489 if (interact) {
490 if (islogin) {
491 sourcehome(".zprofile");
492#ifdef GLOBALZPROFILE
493 source(GLOBALZPROFILE);
494#endif
495 }
496#ifdef GLOBALZSHRC
497 source(GLOBALZSHRC);
498#endif
499 sourcehome(".zshrc");
500 if (islogin) {
501#ifdef GLOBALZLOGIN
502 source(GLOBALZLOGIN);
503#endif
504 sourcehome(".zlogin");
505 }
506 }
507 }
508 if (interact)
509 readhistfile(getsparam("HISTFILE"),0);
510 if (opts['c'] == OPT_SET)
511 {
512 if (SHIN >= 10)
513 close(SHIN);
514 SHIN = movefd(open("/dev/null",O_RDONLY));
515 execstring(cmd);
516 stopmsg = 1;
517 zexit(NULL);
518 }
519#ifdef TIOCSWINSZ
520 if (!(columns = shttyinfo.winsize.ws_col))
521 columns = 80;
522 if (!(lines = shttyinfo.winsize.ws_row))
523 lines = 24;
524#endif
525}
526
527void ainit() /**/
528{
529 alstackind = 0; /* reset alias stack */
530 alstat = 0;
531 isfirstln = 1;
532}
533