xref: /plan9-contrib/sys/src/ape/lib/ap/plan9/_envsetup.c (revision 219b2ee8daee37f4aad58d63f21287faa8e4ffdc)
1 #include "lib.h"
2 #include <stdlib.h>
3 #include <sys/stat.h>
4 #include <fcntl.h>
5 #include <dirent.h>
6 #include <unistd.h>
7 #include <string.h>
8 #include <signal.h>
9 #include "sys9.h"
10 #include "dir.h"
11 
12 /*
13  * Called before main to initialize environ.
14  * Some plan9 environment variables
15  * have 0 bytes in them (notably $path);
16  * we change them to 1's (and execve changes back)
17  *
18  * Also, register the note handler.
19  */
20 
21 char **environ;
22 int errno;
23 unsigned long _clock;
24 static char name[NAME_MAX+5] = "#e";
25 static void fdsetup(char *, char *);
26 static void sigsetup(char *, char *);
27 
28 enum {
29 	Envhunk=7000,
30 };
31 
32 void
33 _envsetup(void)
34 {
35 	DIR *d;
36 	struct dirent *de;
37 	int n, m, i, f;
38 	int psize, cnt;
39 	int nohandle;
40 	int fdinited;
41 	char *ps, *p;
42 	char **pp;
43 	char cd[DIRLEN];
44 	Dir db;
45 
46 	nohandle = 0;
47 	fdinited = 0;
48 	cnt = 0;
49 	d = opendir(name);
50 	if(!d) {
51 		static char **emptyenvp = 0;
52 		environ = emptyenvp;
53 		return;
54 	}
55 	name[2] = '/';
56 	ps = p = malloc(Envhunk);
57 	psize = Envhunk;
58 	while((de = readdir(d)) != NULL){
59 		strcpy(name+3, de->d_name);
60 		if(_STAT(name, cd) < 0)
61 			continue;
62 		convM2D(cd, &db);
63 		n = strlen(de->d_name);
64 		m = db.length;
65 		i = p - ps;
66 		if(i+n+1+m+1 > psize) {
67 			psize += (n+m+2 < Envhunk)? Envhunk : n+m+2;
68 			ps = realloc(ps, psize);
69 			p = ps + i;
70 		}
71 		memcpy(p, de->d_name, n);
72 		p[n] = '=';
73 		f = _OPEN(name, O_RDONLY);
74 		if(f < 0 || _READ(f, p+n+1, m) != m)
75 			m = 0;
76 		_CLOSE(f);
77 		if(p[n+m] == 0)
78 			m--;
79 		for(i=0; i<m; i++)
80 			if(p[n+1+i] == 0)
81 				p[n+1+i] = 1;
82 		p[n+1+m] = 0;
83 		if(strcmp(de->d_name, "_fdinfo") == 0) {
84 			_fdinit(p+n+1, p+n+1+m);
85 			fdinited = 1;
86 		} else if(strcmp(de->d_name, "_sighdlr") == 0)
87 			sigsetup(p+n+1, p+n+1+m);
88 		else if(strcmp(de->d_name, "nohandle") == 0)
89 			nohandle = 1;
90 		p += n+m+2;
91 		cnt++;
92 	}
93 	closedir(d);
94 	if(!fdinited)
95 		_fdinit(0, 0);
96 	environ = pp = malloc((1+cnt)*sizeof(char *));
97 	p = ps;
98 	for(i = 0; i < cnt; i++) {
99 		*pp++ = p;
100 		p = memchr(p, 0, ps+psize-p);
101 		if (!p)
102 			break;
103 		p++;
104 	}
105 	*pp = 0;
106 	if(!nohandle)
107 		_NOTIFY(_notehandler);
108 }
109 
110 static void
111 sigsetup(char *s, char *se)
112 {
113 	int i, sig;
114 	char *e;
115 
116 	while(s < se){
117 		sig = strtoul(s, &e, 10);
118 		if(s == e)
119 			break;
120 		s = e;
121 		if(sig <= MAXSIG)
122 			_sighdlr[sig] = SIG_IGN;
123 	}
124 }
125