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
25 static void fdsetup(char *, char *);
26 static void sigsetup(char *, char *);
27
28 enum {
29 Envhunk=7000,
30 };
31
32 void
_envsetup(void)33 _envsetup(void)
34 {
35 int dfd, fdinited, n, nd, m, i, j, f, nohandle, psize, cnt;
36 char *ps, *p;
37 char **pp;
38 char name[NAME_MAX+5];
39 Dir *d9, *d9a;
40 static char **emptyenvp = 0;
41
42 environ = emptyenvp; /* pessimism */
43 nohandle = 0;
44 fdinited = 0;
45 cnt = 0;
46 strcpy(name, "#e");
47 dfd = _OPEN(name, 0);
48 if(dfd < 0)
49 return;
50 name[2] = '/';
51 ps = p = malloc(Envhunk);
52 if(p == 0)
53 return;
54 psize = Envhunk;
55 nd = _dirreadall(dfd, &d9a);
56 _CLOSE(dfd);
57 for(j=0; j<nd; j++){
58 d9 = &d9a[j];
59 n = strlen(d9->name);
60 if(n >= sizeof name - 4)
61 continue; /* shouldn't be possible */
62 m = d9->length;
63 i = p - ps;
64 if(i+n+1+m+1 > psize) {
65 psize += (n+m+2 < Envhunk)? Envhunk : n+m+2;
66 ps = realloc(ps, psize);
67 if (ps == 0) {
68 free(d9a);
69 return;
70 }
71 p = ps + i;
72 }
73 memcpy(p, d9->name, n);
74 p[n] = '=';
75 strcpy(name+3, d9->name);
76 f = _OPEN(name, O_RDONLY);
77 if(f < 0 || _READ(f, p+n+1, m) != m)
78 m = 0;
79 _CLOSE(f);
80 if(p[n+m] == 0)
81 m--;
82 for(i=0; i<m; i++)
83 if(p[n+1+i] == 0)
84 p[n+1+i] = 1;
85 p[n+1+m] = 0;
86 if(strcmp(d9->name, "_fdinfo") == 0) {
87 _fdinit(p+n+1, p+n+1+m);
88 fdinited = 1;
89 } else if(strcmp(d9->name, "_sighdlr") == 0)
90 sigsetup(p+n+1, p+n+1+m);
91 else if(strcmp(d9->name, "nohandle") == 0)
92 nohandle = 1;
93 p += n+m+2;
94 cnt++;
95 }
96 free(d9a);
97 if(!fdinited)
98 _fdinit(0, 0);
99 pp = malloc((1+cnt)*sizeof(char *));
100 if (pp == 0)
101 return;
102 environ = pp;
103 p = ps;
104 for(i = 0; i < cnt; i++) {
105 *pp++ = p;
106 p = memchr(p, 0, ps+psize-p);
107 if (!p)
108 break;
109 p++;
110 }
111 *pp = 0;
112 if(!nohandle)
113 _NOTIFY(_notehandler);
114 }
115
116 static void
sigsetup(char * s,char * se)117 sigsetup(char *s, char *se)
118 {
119 int sig;
120 char *e;
121
122 while(s < se){
123 sig = strtoul(s, &e, 10);
124 if(s == e)
125 break;
126 s = e;
127 if(sig <= MAXSIG)
128 _sighdlr[sig] = SIG_IGN;
129 }
130 }
131