1 #define _BSDTIME_EXTENSION 2 #include "lib.h" 3 #include <sys/stat.h> 4 #include <stdlib.h> 5 #include "sys9.h" 6 #include <string.h> 7 8 extern int errno; 9 Fdinfo _fdinfo[OPEN_MAX]; 10 11 /* 12 called from _envsetup, either with the value of the environment 13 variable _fdinfo (from s to se-1), or with s==0 if there was no _fdinfo 14 */ 15 static void 16 defaultfdinit(void) 17 { 18 int i; 19 Fdinfo *fi; 20 21 for(i = 0; i <= 2; i++) { 22 fi = &_fdinfo[i]; 23 fi->flags = FD_ISOPEN; 24 fi->oflags = (i == 0)? O_RDONLY : O_WRONLY; 25 if(_isatty(i)) 26 fi->flags |= FD_ISTTY; 27 } 28 } 29 30 static int 31 readprocfdinit(void) 32 { 33 /* construct info from /proc/$pid/fd */ 34 char buf[8192]; 35 Fdinfo *fi; 36 int fd, pfd, pid, n, tot, m; 37 char *s, *nexts; 38 39 memset(buf, 0, sizeof buf); 40 pfd = _OPEN("#c/pid", 0); 41 if(pfd < 0) 42 return -1; 43 if(_PREAD(pfd, buf, 100, 0) < 0){ 44 _CLOSE(pfd); 45 return -1; 46 } 47 _CLOSE(pfd); 48 pid = strtoul(buf, 0, 10); 49 strcpy(buf, "#p/"); 50 _ultoa(buf+3, pid); 51 strcat(buf, "/fd"); 52 pfd = _OPEN(buf, 0); 53 if(pfd < 0) 54 return -1; 55 memset(buf, 0, sizeof buf); 56 tot = 0; 57 for(;;){ 58 n = _PREAD(pfd, buf+tot, sizeof buf-tot, tot); 59 if(n <= 0) 60 break; 61 tot += n; 62 } 63 _CLOSE(pfd); 64 if(n < 0) 65 return -1; 66 buf[sizeof buf-1] = '\0'; 67 s = strchr(buf, '\n'); /* skip current directory */ 68 if(s == 0) 69 return -1; 70 s++; 71 m = 0; 72 for(; s && *s; s=nexts){ 73 nexts = strchr(s, '\n'); 74 if(nexts) 75 *nexts++ = '\0'; 76 errno = 0; 77 fd = strtoul(s, &s, 10); 78 if(errno != 0) 79 return -1; 80 if(fd >= OPEN_MAX) 81 continue; 82 if(fd == pfd) 83 continue; 84 fi = &_fdinfo[fd]; 85 fi->flags = FD_ISOPEN; 86 while(*s == ' ' || *s == '\t') 87 s++; 88 if(*s == 'r'){ 89 m |= 1; 90 s++; 91 } 92 if(*s == 'w'){ 93 m |= 2; 94 } 95 if(m==1) 96 fi->oflags = O_RDONLY; 97 else if(m==2) 98 fi->oflags = O_WRONLY; 99 else 100 fi->oflags = O_RDWR; 101 if(strlen(s) >= 9 && strcmp(s+strlen(s)-9, "/dev/cons") == 0) 102 fi->flags |= FD_ISTTY; 103 } 104 return 0; 105 } 106 107 static void 108 sfdinit(int usedproc, char *s, char *se) 109 { 110 Fdinfo *fi; 111 unsigned long fd, fl, ofl; 112 char *e; 113 114 while(s < se){ 115 fd = strtoul(s, &e, 10); 116 if(s == e) 117 break; 118 s = e; 119 fl = strtoul(s, &e, 10); 120 if(s == e) 121 break; 122 s = e; 123 ofl = strtoul(s, &e, 10); 124 if(s == e) 125 break; 126 s = e; 127 if(fd < OPEN_MAX){ 128 fi = &_fdinfo[fd]; 129 if(usedproc && !(fi->flags&FD_ISOPEN)) 130 continue; /* should probably ignore all of $_fdinit */ 131 fi->flags = fl; 132 fi->oflags = ofl; 133 if(_isatty(fd)) 134 fi->flags |= FD_ISTTY; 135 } 136 } 137 138 } 139 140 void 141 _fdinit(char *s, char *se) 142 { 143 int i, usedproc; 144 Fdinfo *fi; 145 struct stat sbuf; 146 147 usedproc = 0; 148 if(readprocfdinit() == 0) 149 usedproc = 1; 150 else 151 _WRITE(2, "FAILED\n", 7); 152 if(s) 153 sfdinit(usedproc, s, se); 154 if(!s && !usedproc) 155 defaultfdinit(); 156 157 for(i = 0; i < OPEN_MAX; i++) { 158 fi = &_fdinfo[i]; 159 if(fi->flags&FD_ISOPEN){ 160 if(fstat(i, &sbuf) >= 0) { 161 fi->uid = sbuf.st_uid; 162 fi->gid = sbuf.st_gid; 163 } 164 } 165 } 166 } 167 168