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