ref: d1cebf608b05e45b148108ac6c16ae94f6862097
dir: /sys/src/ape/lib/ap/plan9/_fdinfo.c/
#define _BSDTIME_EXTENSION #include "lib.h" #include <sys/stat.h> #include <unistd.h> #include <errno.h> #include <stdlib.h> #include "sys9.h" #include <string.h> Fdinfo _fdinfo[OPEN_MAX]; /* called from _envsetup, either with the value of the environment variable _fdinfo (from s to se-1), or with s==0 if there was no _fdinfo */ static void defaultfdinit(void) { int i; Fdinfo *fi; for(i = 0; i <= 2; i++) { fi = &_fdinfo[i]; fi->flags = FD_ISOPEN; fi->oflags = (i == 0)? O_RDONLY : O_WRONLY; if(_isatty(i)) fi->flags |= FD_ISTTY; } } static int readprocfdinit(void) { /* construct info from /proc/$pid/fd */ char buf[8192]; Fdinfo *fi; int fd, pfd, n, tot, m; char *s, *nexts; memset(buf, 0, sizeof buf); strcpy(buf, "/proc/"); _ultoa(buf+6, getpid()); strcat(buf, "/fd"); pfd = _OPEN(buf, OREAD); if(pfd < 0) return -1; memset(buf, 0, sizeof buf); tot = 0; for(;;){ n = _PREAD(pfd, buf+tot, sizeof buf-tot, tot); if(n <= 0) break; tot += n; } _CLOSE(pfd); if(n < 0) return -1; buf[sizeof buf-1] = '\0'; s = strchr(buf, '\n'); /* skip current directory */ if(s == 0) return -1; s++; m = 0; for(; s && *s; s=nexts){ nexts = strchr(s, '\n'); if(nexts) *nexts++ = '\0'; errno = 0; fd = strtoul(s, &s, 10); if(errno != 0) return -1; if(fd < 0 || fd == pfd || fd >= OPEN_MAX) continue; fi = &_fdinfo[fd]; fi->flags = FD_ISOPEN; while(*s == ' ' || *s == '\t') s++; if(*s == 'r'){ m |= 1; s++; } if(*s == 'w'){ m |= 2; } if(m==1) fi->oflags = O_RDONLY; else if(m==2) fi->oflags = O_WRONLY; else fi->oflags = O_RDWR; if(strlen(s) >= 9 && strcmp(s+strlen(s)-9, "/dev/cons") == 0) fi->flags |= FD_ISTTY; } return 0; } static void sfdinit(int usedproc, char *s, char *se) { Fdinfo *fi; unsigned long fd, fl, ofl; char *e; while(s < se){ fd = strtoul(s, &e, 10); if(s == e) break; s = e; fl = strtoul(s, &e, 10); if(s == e) break; s = e; ofl = strtoul(s, &e, 10); if(s == e) break; s = e; if(fd < OPEN_MAX){ fi = &_fdinfo[fd]; if(usedproc && !(fi->flags&FD_ISOPEN)) continue; /* should probably ignore all of $_fdinit */ fi->flags = fl; fi->oflags = ofl; if(_isatty(fd)) fi->flags |= FD_ISTTY; } } } void _fdinit(char *s, char *se) { int i, usedproc; Fdinfo *fi; struct stat sbuf; usedproc = 0; if(readprocfdinit() == 0) usedproc = 1; if(s) sfdinit(usedproc, s, se); if(!s && !usedproc) defaultfdinit(); for(i = 0; i < OPEN_MAX; i++) { fi = &_fdinfo[i]; if(fi->flags&FD_ISOPEN){ if(fstat(i, &sbuf) >= 0) { fi->uid = sbuf.st_uid; fi->gid = sbuf.st_gid; } } } }