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