rc

[fork] interactive rc shell
git clone https://hhvn.uk/rc
git clone git://hhvn.uk/rc
Log | Files | Refs | README | LICENSE

main.c (3559B)


      1 /* main.c: handles initialization of rc and command line options */
      2 
      3 #include "rc.h"
      4 
      5 #include <errno.h>
      6 #include <locale.h>
      7 
      8 #include "input.h"
      9 
     10 extern char **environ;
     11 
     12 bool dashdee, dashee, dasheye, dashell, dashen;
     13 bool dashpee, dashoh, dashess, dashvee, dashex;
     14 bool interactive;
     15 static bool dashEYE;
     16 char *dashsee[2];
     17 pid_t rc_pid;
     18 
     19 
     20 static void assigndefault(char *,...);
     21 static void checkfd(int, enum redirtype);
     22 
     23 extern int main(int argc, char *argv[], char *envp[]) {
     24 	char *dollarzero, *null[1];
     25 	int c;
     26 	initprint();
     27 	dashsee[0] = dashsee[1] = NULL;
     28 	dollarzero = argv[0];
     29 	rc_pid = getpid();
     30 	dashell = (*argv[0] == '-'); /* Unix tradition */
     31 	while ((c = rc_getopt(argc, argv, "c:deiIlnopsvx")) != -1)
     32 		switch (c) {
     33 		case 'c':
     34 			dashsee[0] = rc_optarg;
     35 			goto quitopts;
     36 		case 'd':
     37 			dashdee = TRUE;
     38 			break;
     39 		case 'e':
     40 			dashee = TRUE;
     41 			break;
     42 		case 'I':
     43 			dashEYE = TRUE;
     44 			interactive = FALSE;
     45 			break;
     46 		case 'i':
     47 			dasheye = interactive = TRUE;
     48 			break;
     49 		case 'l':
     50 			dashell = TRUE;
     51 			break;
     52 		case 'n':
     53 			dashen = TRUE;
     54 			break;
     55 		case 'o':
     56 			dashoh = TRUE;
     57 			break;
     58 		case 'p':
     59 			dashpee = TRUE;
     60 			break;
     61 		case 's':
     62 			dashess = TRUE;
     63 			break;
     64 		case 'v':
     65 			dashvee = TRUE;
     66 			break;
     67 		case 'x':
     68 			dashex = TRUE;
     69 			break;
     70 		case '?':
     71 			exit(1);
     72 		}
     73 quitopts:
     74 	argv += rc_optind;
     75 	/* use isatty() iff neither -i nor -I is set, and iff the input is not
     76 	 * from a script or -c flags */
     77 	if (!dasheye && !dashEYE && dashsee[0] == NULL &&
     78 			(dashess || *argv == NULL))
     79 		interactive = isatty(0);
     80 	if (!dashoh) {
     81 		checkfd(0, rFrom);
     82 		checkfd(1, rCreate);
     83 		checkfd(2, rCreate);
     84 	}
     85 	initsignal();
     86 	inithash();
     87 	initparse();
     88 	assigndefault("ifs", " ", "\t", "\n", (void *)0);
     89 	assigndefault("nl", "\n", (void *)0);
     90 #ifdef DEFAULTPATH
     91 	assigndefault("path", DEFAULTPATH, (void *)0);
     92 #endif
     93 	assigndefault("pid", nprint("%d", rc_pid), (void *)0);
     94 	assigndefault("prompt", "; ", "", (void *)0);
     95 	assigndefault("tab", "\t", (void *)0);
     96 	assigndefault("version",
     97 		VERSION,
     98 		"$Release: @(#)" PACKAGE " " VERSION " " DESCRIPTION " $",
     99 		(void *)0 );
    100 	initenv(envp);
    101 	initinput();
    102 	null[0] = NULL;
    103 	starassign(dollarzero, null, FALSE); /* assign $0 to $* */
    104 	inithandler();
    105 
    106 	if (dashell) {
    107 		char *rcrc;
    108 		int fd;
    109 
    110 		rcrc = concat(varlookup("home"), word("/.rcrc", NULL))->w;
    111 		fd = rc_open(rcrc, rFrom);
    112 		if (fd == -1) {
    113 			if (errno != ENOENT)
    114 				uerror(rcrc);
    115 		} else {
    116 			bool push_interactive;
    117 
    118 			pushfd(fd);
    119 			push_interactive = interactive;
    120 			interactive = FALSE;
    121 			doit(TRUE);
    122 			interactive = push_interactive;
    123 			close(fd);
    124 		}
    125 	}
    126 	environ = makeenv();
    127 	setlocale(LC_CTYPE, "");
    128 
    129 	if (dashsee[0] != NULL || dashess) {	/* input from  -c or -s? */
    130 		if (*argv != NULL)
    131 			starassign(dollarzero, argv, FALSE);
    132 		if (dashess)
    133 			pushfd(0);
    134 		else
    135 			pushstring(dashsee, TRUE);
    136 	} else if (*argv != NULL) {	/* else from a file? */
    137 		b_dot(--argv);
    138 		rc_exit(getstatus());
    139 	} else {			/* else stdin */
    140 		pushfd(0);
    141 	}
    142 	dasheye = FALSE;
    143 	doit(TRUE);
    144 	rc_exit(getstatus());
    145 	return 0; /* Never really reached. */
    146 }
    147 
    148 static void assigndefault(char *name,...) {
    149 	va_list ap;
    150 	List *l;
    151 	char *v;
    152 	va_start(ap, name);
    153 	for (l = NULL; (v = va_arg(ap, char *)) != NULL;)
    154 		l = append(l, word(v, NULL));
    155 	varassign(name, l, FALSE);
    156 	set_exportable(name, FALSE);
    157 	if (streq(name, "path"))
    158 		alias(name, l, FALSE);
    159 	va_end(ap);
    160 }
    161 
    162 /* open an fd on /dev/null if it is inherited closed */
    163 
    164 static void checkfd(int fd, enum redirtype r) {
    165 	int new = rc_open("/dev/null", r);
    166 	if (new != fd && new != -1)
    167 		close(new);
    168 }