xref: /plan9-contrib/sys/src/ape/lib/ap/plan9/_envsetup.c (revision 781103c4074deb8af160e8a0da2742ba6b29dc2b)
13e12c5d1SDavid du Colombier #include "lib.h"
23e12c5d1SDavid du Colombier #include <stdlib.h>
33e12c5d1SDavid du Colombier #include <sys/stat.h>
43e12c5d1SDavid du Colombier #include <fcntl.h>
53e12c5d1SDavid du Colombier #include <dirent.h>
63e12c5d1SDavid du Colombier #include <unistd.h>
73e12c5d1SDavid du Colombier #include <string.h>
8219b2ee8SDavid du Colombier #include <signal.h>
93e12c5d1SDavid du Colombier #include "sys9.h"
103e12c5d1SDavid du Colombier #include "dir.h"
113e12c5d1SDavid du Colombier 
123e12c5d1SDavid du Colombier /*
133e12c5d1SDavid du Colombier  * Called before main to initialize environ.
143e12c5d1SDavid du Colombier  * Some plan9 environment variables
153e12c5d1SDavid du Colombier  * have 0 bytes in them (notably $path);
163e12c5d1SDavid du Colombier  * we change them to 1's (and execve changes back)
173e12c5d1SDavid du Colombier  *
183e12c5d1SDavid du Colombier  * Also, register the note handler.
193e12c5d1SDavid du Colombier  */
203e12c5d1SDavid du Colombier 
213e12c5d1SDavid du Colombier char **environ;
223e12c5d1SDavid du Colombier int errno;
233e12c5d1SDavid du Colombier unsigned long _clock;
24e877b607SDavid du Colombier 
253e12c5d1SDavid du Colombier static void fdsetup(char *, char *);
26219b2ee8SDavid du Colombier static void sigsetup(char *, char *);
273e12c5d1SDavid du Colombier 
283e12c5d1SDavid du Colombier enum {
293e12c5d1SDavid du Colombier 	Envhunk=7000,
303e12c5d1SDavid du Colombier };
313e12c5d1SDavid du Colombier 
323e12c5d1SDavid du Colombier void
_envsetup(void)333e12c5d1SDavid du Colombier _envsetup(void)
343e12c5d1SDavid du Colombier {
35e877b607SDavid du Colombier 	int dfd, fdinited, n, nd, m, i, j, f, nohandle, psize, cnt;
363e12c5d1SDavid du Colombier 	char *ps, *p;
373e12c5d1SDavid du Colombier 	char **pp;
38e877b607SDavid du Colombier 	char name[NAME_MAX+5];
39fb7f0c93SDavid du Colombier 	Dir *d9, *d9a;
40e877b607SDavid du Colombier 	static char **emptyenvp = 0;
413e12c5d1SDavid du Colombier 
42e877b607SDavid du Colombier 	environ = emptyenvp;		/* pessimism */
433e12c5d1SDavid du Colombier 	nohandle = 0;
44219b2ee8SDavid du Colombier 	fdinited = 0;
453e12c5d1SDavid du Colombier 	cnt = 0;
46e877b607SDavid du Colombier 	strcpy(name, "#e");
47fb7f0c93SDavid du Colombier 	dfd = _OPEN(name, 0);
48e877b607SDavid du Colombier 	if(dfd < 0)
493e12c5d1SDavid du Colombier 		return;
503e12c5d1SDavid du Colombier 	name[2] = '/';
513e12c5d1SDavid du Colombier 	ps = p = malloc(Envhunk);
52e877b607SDavid du Colombier 	if(p == 0)
53e877b607SDavid du Colombier 		return;
543e12c5d1SDavid du Colombier 	psize = Envhunk;
55fb7f0c93SDavid du Colombier 	nd = _dirreadall(dfd, &d9a);
56fb7f0c93SDavid du Colombier 	_CLOSE(dfd);
57fb7f0c93SDavid du Colombier 	for(j=0; j<nd; j++){
58fb7f0c93SDavid du Colombier 		d9 = &d9a[j];
59fb7f0c93SDavid du Colombier 		n = strlen(d9->name);
60e877b607SDavid du Colombier 		if(n >= sizeof name - 4)
61e877b607SDavid du Colombier 			continue;	/* shouldn't be possible */
629a747e4fSDavid du Colombier 		m = d9->length;
633e12c5d1SDavid du Colombier 		i = p - ps;
643e12c5d1SDavid du Colombier 		if(i+n+1+m+1 > psize) {
653e12c5d1SDavid du Colombier 			psize += (n+m+2 < Envhunk)? Envhunk : n+m+2;
663e12c5d1SDavid du Colombier 			ps = realloc(ps, psize);
67e877b607SDavid du Colombier 			if (ps == 0) {
68e877b607SDavid du Colombier 				free(d9a);
69e877b607SDavid du Colombier 				return;
70e877b607SDavid du Colombier 			}
713e12c5d1SDavid du Colombier 			p = ps + i;
723e12c5d1SDavid du Colombier 		}
73fb7f0c93SDavid du Colombier 		memcpy(p, d9->name, n);
743e12c5d1SDavid du Colombier 		p[n] = '=';
75fb7f0c93SDavid du Colombier 		strcpy(name+3, d9->name);
76bd389b36SDavid du Colombier 		f = _OPEN(name, O_RDONLY);
77bd389b36SDavid du Colombier 		if(f < 0 || _READ(f, p+n+1, m) != m)
783e12c5d1SDavid du Colombier 			m = 0;
79bd389b36SDavid du Colombier 		_CLOSE(f);
803e12c5d1SDavid du Colombier 		if(p[n+m] == 0)
813e12c5d1SDavid du Colombier 			m--;
823e12c5d1SDavid du Colombier 		for(i=0; i<m; i++)
833e12c5d1SDavid du Colombier 			if(p[n+1+i] == 0)
843e12c5d1SDavid du Colombier 				p[n+1+i] = 1;
853e12c5d1SDavid du Colombier 		p[n+1+m] = 0;
86fb7f0c93SDavid du Colombier 		if(strcmp(d9->name, "_fdinfo") == 0) {
87219b2ee8SDavid du Colombier 			_fdinit(p+n+1, p+n+1+m);
88219b2ee8SDavid du Colombier 			fdinited = 1;
89fb7f0c93SDavid du Colombier 		} else if(strcmp(d9->name, "_sighdlr") == 0)
90219b2ee8SDavid du Colombier 			sigsetup(p+n+1, p+n+1+m);
91fb7f0c93SDavid du Colombier 		else if(strcmp(d9->name, "nohandle") == 0)
923e12c5d1SDavid du Colombier 			nohandle = 1;
933e12c5d1SDavid du Colombier 		p += n+m+2;
943e12c5d1SDavid du Colombier 		cnt++;
953e12c5d1SDavid du Colombier 	}
96fb7f0c93SDavid du Colombier 	free(d9a);
97219b2ee8SDavid du Colombier 	if(!fdinited)
98219b2ee8SDavid du Colombier 		_fdinit(0, 0);
99e877b607SDavid du Colombier 	pp = malloc((1+cnt)*sizeof(char *));
100e877b607SDavid du Colombier 	if (pp == 0)
101e877b607SDavid du Colombier 		return;
102e877b607SDavid du Colombier 	environ = pp;
1033e12c5d1SDavid du Colombier 	p = ps;
1043e12c5d1SDavid du Colombier 	for(i = 0; i < cnt; i++) {
1053e12c5d1SDavid du Colombier 		*pp++ = p;
1063e12c5d1SDavid du Colombier 		p = memchr(p, 0, ps+psize-p);
1073e12c5d1SDavid du Colombier 		if (!p)
1083e12c5d1SDavid du Colombier 			break;
1093e12c5d1SDavid du Colombier 		p++;
1103e12c5d1SDavid du Colombier 	}
1113e12c5d1SDavid du Colombier 	*pp = 0;
1123e12c5d1SDavid du Colombier 	if(!nohandle)
1133e12c5d1SDavid du Colombier 		_NOTIFY(_notehandler);
1143e12c5d1SDavid du Colombier }
1153e12c5d1SDavid du Colombier 
1163e12c5d1SDavid du Colombier static void
sigsetup(char * s,char * se)117219b2ee8SDavid du Colombier sigsetup(char *s, char *se)
1183e12c5d1SDavid du Colombier {
119*781103c4SDavid du Colombier 	int sig;
1203e12c5d1SDavid du Colombier 	char *e;
1213e12c5d1SDavid du Colombier 
1223e12c5d1SDavid du Colombier 	while(s < se){
123219b2ee8SDavid du Colombier 		sig = strtoul(s, &e, 10);
1243e12c5d1SDavid du Colombier 		if(s == e)
1253e12c5d1SDavid du Colombier 			break;
1263e12c5d1SDavid du Colombier 		s = e;
127219b2ee8SDavid du Colombier 		if(sig <= MAXSIG)
128219b2ee8SDavid du Colombier 			_sighdlr[sig] = SIG_IGN;
1293e12c5d1SDavid du Colombier 	}
1303e12c5d1SDavid du Colombier }
131