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