00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024
00025
00026
00027
00028
00029
00030
00031
00032
00033
00034
00035
00036
00037 #ifndef lint
00038 char copyright[] =
00039 "@(#) Copyright (c) 1991 The Regents of the University of California.\n\
00040 All rights reserved.\n";
00041 #endif
00042
00043 #ifndef lint
00044 static char sccsid[] = "@(#)main.c 5.2 (Berkeley) 3/13/91";
00045 #endif
00046
00047 #include <sys/types.h>
00048 #include <signal.h>
00049 #include <fcntl.h>
00050 #include "shell.h"
00051 #include "main.h"
00052 #include "mail.h"
00053 #include "options.h"
00054 #include "output.h"
00055 #include "parser.h"
00056 #include "nodes.h"
00057 #include "eval.h"
00058 #include "jobs.h"
00059 #include "input.h"
00060 #include "trap.h"
00061 #if ATTY
00062 #include "var.h"
00063 #endif
00064 #include "memalloc.h"
00065 #include "error.h"
00066 #include "init.h"
00067 #include "mystring.h"
00068
00069 #define PROFILE 0
00070
00071 int rootpid;
00072 int rootshell;
00073 STATIC union node *curcmd;
00074 STATIC union node *prevcmd;
00075 extern int errno;
00076 #if PROFILE
00077 short profile_buf[16384];
00078 extern int etext();
00079 #endif
00080
00081 #ifdef __STDC__
00082 STATIC void read_profile(char *);
00083 char *getenv(char *);
00084 #else
00085 STATIC void read_profile();
00086 char *getenv();
00087 #endif
00088
00089
00090
00091
00092
00093
00094
00095
00096
00097
00098 main(argc, argv) char **argv; {
00099 struct jmploc jmploc;
00100 struct stackmark smark;
00101 volatile int state;
00102 char *shinit, *home;
00103 char *profile = NULL, *ashrc = NULL;
00104
00105 #if PROFILE
00106 monitor(4, etext, profile_buf, sizeof profile_buf, 50);
00107 #endif
00108 state = 0;
00109 if (setjmp(jmploc.loc)) {
00110
00111
00112
00113
00114
00115 if (exception == EXSHELLPROC) {
00116 rootpid = getpid();
00117 rootshell = 1;
00118 minusc = NULL;
00119 state = 3;
00120 } else if (state == 0 || iflag == 0 || ! rootshell)
00121 exitshell(2);
00122 reset();
00123 #if ATTY
00124 if (exception == EXINT
00125 && (! attyset() || equal(termval(), "emacs"))) {
00126 #else
00127 if (exception == EXINT) {
00128 #endif
00129 out2c('\n');
00130 flushout(&errout);
00131 }
00132 popstackmark(&smark);
00133 FORCEINTON;
00134 if (state == 1)
00135 goto state1;
00136 else if (state == 2)
00137 goto state2;
00138 else if (state == 3)
00139 goto state3;
00140 else
00141 goto state4;
00142 }
00143 handler = &jmploc;
00144 #if DEBUG
00145 opentrace();
00146 trputs("Shell args: "); trargs(argv);
00147 #endif
00148 rootpid = getpid();
00149 rootshell = 1;
00150 init();
00151 setstackmark(&smark);
00152 procargs(argc, argv);
00153 if (eflag) eflag = 2;
00154 if (xflag) xflag = 2;
00155 if (argv[0] && argv[0][0] == '-') {
00156 state = 1;
00157 read_profile("/etc/profile");
00158 state1:
00159 state = 2;
00160 if ((home = getenv("HOME")) != NULL
00161 && (profile = (char *) malloc(strlen(home) + 10)) != NULL)
00162 {
00163 strcpy(profile, home);
00164 strcat(profile, "/.profile");
00165 read_profile(profile);
00166 } else {
00167 read_profile(".profile");
00168 }
00169 } else if ((sflag || minusc) && (shinit = getenv("SHINIT")) != NULL) {
00170 state = 2;
00171 evalstring(shinit);
00172 }
00173 state2:
00174 if (profile != NULL) free(profile);
00175
00176 state = 3;
00177 if (!argv[0] || argv[0][0] != '-') {
00178 if ((home = getenv("HOME")) != NULL
00179 && (ashrc = (char *) malloc(strlen(home) + 8)) != NULL)
00180 {
00181 strcpy(ashrc, home);
00182 strcat(ashrc, "/.ashrc");
00183 read_profile(ashrc);
00184 }
00185 }
00186 state3:
00187 if (ashrc != NULL) free(ashrc);
00188 if (eflag) eflag = 1;
00189 if (xflag) xflag = 1;
00190 exitstatus = 0;
00191
00192 state = 4;
00193 if (minusc) {
00194 evalstring(minusc);
00195 }
00196 if (sflag || minusc == NULL) {
00197 state4:
00198 cmdloop(1);
00199 }
00200 #if PROFILE
00201 monitor(0);
00202 #endif
00203 exitshell(exitstatus);
00204 }
00205
00206
00207
00208
00209
00210
00211
00212 void
00213 cmdloop(top) {
00214 union node *n;
00215 struct stackmark smark;
00216 int inter;
00217 int numeof;
00218
00219 TRACE(("cmdloop(%d) called\n", top));
00220 setstackmark(&smark);
00221 numeof = 0;
00222 for (;;) {
00223 if (pendingsigs)
00224 dotrap();
00225 inter = 0;
00226 if (iflag && top) {
00227 inter++;
00228 showjobs(1);
00229 chkmail(0);
00230 flushout(&output);
00231 }
00232 n = parsecmd(inter);
00233 #if DEBUG
00234
00235 #endif
00236 if (n == NEOF) {
00237 if (Iflag == 0 || numeof >= 50)
00238 break;
00239 out2str("\nUse \"exit\" to leave shell.\n");
00240 numeof++;
00241 } else if (n != NULL && nflag == 0) {
00242 if (inter) {
00243 INTOFF;
00244 if (prevcmd)
00245 freefunc(prevcmd);
00246 prevcmd = curcmd;
00247 curcmd = copyfunc(n);
00248 INTON;
00249 }
00250 evaltree(n, 0);
00251 #ifdef notdef
00252 if (exitstatus)
00253 outfmt(&errout, "Exit status 0x%X\n", exitstatus);
00254 #endif
00255 }
00256 popstackmark(&smark);
00257 }
00258 popstackmark(&smark);
00259 }
00260
00261
00262
00263
00264
00265
00266
00267 STATIC void
00268 read_profile(name)
00269 char *name;
00270 {
00271 int fd;
00272
00273 INTOFF;
00274 if ((fd = open(name, O_RDONLY)) >= 0)
00275 setinputfd(fd, 1);
00276 INTON;
00277 if (fd < 0)
00278 return;
00279 cmdloop(0);
00280 popfile();
00281 }
00282
00283
00284
00285
00286
00287
00288
00289 void
00290 readcmdfile(name)
00291 char *name;
00292 {
00293 int fd;
00294
00295 INTOFF;
00296 if ((fd = open(name, O_RDONLY)) >= 0)
00297 setinputfd(fd, 1);
00298 else
00299 error("Can't open %s", name);
00300 INTON;
00301 cmdloop(0);
00302 popfile();
00303 }
00304
00305
00306
00307
00308
00309
00310
00311 dotcmd(argc, argv) char **argv; {
00312 exitstatus = 0;
00313 if (argc >= 2) {
00314 setinputfile(argv[1], 1);
00315 commandname = argv[1];
00316 cmdloop(0);
00317 popfile();
00318 }
00319 return exitstatus;
00320 }
00321
00322
00323 exitcmd(argc, argv) char **argv; {
00324 extern int oexitstatus;
00325 if (argc > 1)
00326 exitstatus = number(argv[1]);
00327 else
00328 exitstatus = oexitstatus;
00329 exitshell(exitstatus);
00330 }
00331
00332
00333 lccmd(argc, argv) char **argv; {
00334 if (argc > 1) {
00335 defun(argv[1], prevcmd);
00336 return 0;
00337 } else {
00338 INTOFF;
00339 freefunc(curcmd);
00340 curcmd = prevcmd;
00341 prevcmd = NULL;
00342 INTON;
00343 evaltree(curcmd, 0);
00344 return exitstatus;
00345 }
00346 }
00347
00348
00349
00350 #ifdef notdef
00351
00352
00353
00354
00355 void
00356 exit(exitstatus) {
00357 _exit(exitstatus);
00358 }
00359 #endif