1219b2ee8SDavid du Colombier #define _BSDTIME_EXTENSION
2219b2ee8SDavid du Colombier #include "lib.h"
3219b2ee8SDavid du Colombier #include <sys/stat.h>
4219b2ee8SDavid du Colombier #include <stdlib.h>
5*d9306527SDavid du Colombier #include "sys9.h"
6*d9306527SDavid du Colombier #include <string.h>
7219b2ee8SDavid du Colombier
8*d9306527SDavid du Colombier extern int errno;
9219b2ee8SDavid du Colombier Fdinfo _fdinfo[OPEN_MAX];
10219b2ee8SDavid du Colombier
11219b2ee8SDavid du Colombier /*
12219b2ee8SDavid du Colombier called from _envsetup, either with the value of the environment
13219b2ee8SDavid du Colombier variable _fdinfo (from s to se-1), or with s==0 if there was no _fdinfo
14219b2ee8SDavid du Colombier */
15*d9306527SDavid du Colombier static void
defaultfdinit(void)16*d9306527SDavid du Colombier defaultfdinit(void)
17*d9306527SDavid du Colombier {
18*d9306527SDavid du Colombier int i;
19*d9306527SDavid du Colombier Fdinfo *fi;
20*d9306527SDavid du Colombier
21*d9306527SDavid du Colombier for(i = 0; i <= 2; i++) {
22*d9306527SDavid du Colombier fi = &_fdinfo[i];
23*d9306527SDavid du Colombier fi->flags = FD_ISOPEN;
24*d9306527SDavid du Colombier fi->oflags = (i == 0)? O_RDONLY : O_WRONLY;
25*d9306527SDavid du Colombier if(_isatty(i))
26*d9306527SDavid du Colombier fi->flags |= FD_ISTTY;
27*d9306527SDavid du Colombier }
28*d9306527SDavid du Colombier }
29*d9306527SDavid du Colombier
30*d9306527SDavid du Colombier static int
readprocfdinit(void)31*d9306527SDavid du Colombier readprocfdinit(void)
32*d9306527SDavid du Colombier {
33*d9306527SDavid du Colombier /* construct info from /proc/$pid/fd */
34*d9306527SDavid du Colombier char buf[8192];
35*d9306527SDavid du Colombier Fdinfo *fi;
36*d9306527SDavid du Colombier int fd, pfd, pid, n, tot, m;
37*d9306527SDavid du Colombier char *s, *nexts;
38*d9306527SDavid du Colombier
39*d9306527SDavid du Colombier memset(buf, 0, sizeof buf);
40*d9306527SDavid du Colombier pfd = _OPEN("#c/pid", 0);
41*d9306527SDavid du Colombier if(pfd < 0)
42*d9306527SDavid du Colombier return -1;
43*d9306527SDavid du Colombier if(_PREAD(pfd, buf, 100, 0) < 0){
44*d9306527SDavid du Colombier _CLOSE(pfd);
45*d9306527SDavid du Colombier return -1;
46*d9306527SDavid du Colombier }
47*d9306527SDavid du Colombier _CLOSE(pfd);
48*d9306527SDavid du Colombier pid = strtoul(buf, 0, 10);
49*d9306527SDavid du Colombier strcpy(buf, "#p/");
50*d9306527SDavid du Colombier _ultoa(buf+3, pid);
51*d9306527SDavid du Colombier strcat(buf, "/fd");
52*d9306527SDavid du Colombier pfd = _OPEN(buf, 0);
53*d9306527SDavid du Colombier if(pfd < 0)
54*d9306527SDavid du Colombier return -1;
55*d9306527SDavid du Colombier memset(buf, 0, sizeof buf);
56*d9306527SDavid du Colombier tot = 0;
57*d9306527SDavid du Colombier for(;;){
58*d9306527SDavid du Colombier n = _PREAD(pfd, buf+tot, sizeof buf-tot, tot);
59*d9306527SDavid du Colombier if(n <= 0)
60*d9306527SDavid du Colombier break;
61*d9306527SDavid du Colombier tot += n;
62*d9306527SDavid du Colombier }
63*d9306527SDavid du Colombier _CLOSE(pfd);
64*d9306527SDavid du Colombier if(n < 0)
65*d9306527SDavid du Colombier return -1;
66*d9306527SDavid du Colombier buf[sizeof buf-1] = '\0';
67*d9306527SDavid du Colombier s = strchr(buf, '\n'); /* skip current directory */
68*d9306527SDavid du Colombier if(s == 0)
69*d9306527SDavid du Colombier return -1;
70*d9306527SDavid du Colombier s++;
71*d9306527SDavid du Colombier m = 0;
72*d9306527SDavid du Colombier for(; s && *s; s=nexts){
73*d9306527SDavid du Colombier nexts = strchr(s, '\n');
74*d9306527SDavid du Colombier if(nexts)
75*d9306527SDavid du Colombier *nexts++ = '\0';
76*d9306527SDavid du Colombier errno = 0;
77*d9306527SDavid du Colombier fd = strtoul(s, &s, 10);
78*d9306527SDavid du Colombier if(errno != 0)
79*d9306527SDavid du Colombier return -1;
80*d9306527SDavid du Colombier if(fd >= OPEN_MAX)
81*d9306527SDavid du Colombier continue;
82*d9306527SDavid du Colombier if(fd == pfd)
83*d9306527SDavid du Colombier continue;
84*d9306527SDavid du Colombier fi = &_fdinfo[fd];
85*d9306527SDavid du Colombier fi->flags = FD_ISOPEN;
86*d9306527SDavid du Colombier while(*s == ' ' || *s == '\t')
87*d9306527SDavid du Colombier s++;
88*d9306527SDavid du Colombier if(*s == 'r'){
89*d9306527SDavid du Colombier m |= 1;
90*d9306527SDavid du Colombier s++;
91*d9306527SDavid du Colombier }
92*d9306527SDavid du Colombier if(*s == 'w'){
93*d9306527SDavid du Colombier m |= 2;
94*d9306527SDavid du Colombier }
95*d9306527SDavid du Colombier if(m==1)
96*d9306527SDavid du Colombier fi->oflags = O_RDONLY;
97*d9306527SDavid du Colombier else if(m==2)
98*d9306527SDavid du Colombier fi->oflags = O_WRONLY;
99*d9306527SDavid du Colombier else
100*d9306527SDavid du Colombier fi->oflags = O_RDWR;
101*d9306527SDavid du Colombier if(strlen(s) >= 9 && strcmp(s+strlen(s)-9, "/dev/cons") == 0)
102*d9306527SDavid du Colombier fi->flags |= FD_ISTTY;
103*d9306527SDavid du Colombier }
104*d9306527SDavid du Colombier return 0;
105*d9306527SDavid du Colombier }
106*d9306527SDavid du Colombier
107*d9306527SDavid du Colombier static void
sfdinit(int usedproc,char * s,char * se)108*d9306527SDavid du Colombier sfdinit(int usedproc, char *s, char *se)
109219b2ee8SDavid du Colombier {
110219b2ee8SDavid du Colombier Fdinfo *fi;
111219b2ee8SDavid du Colombier unsigned long fd, fl, ofl;
112219b2ee8SDavid du Colombier char *e;
113219b2ee8SDavid du Colombier
114219b2ee8SDavid du Colombier while(s < se){
115219b2ee8SDavid du Colombier fd = strtoul(s, &e, 10);
116219b2ee8SDavid du Colombier if(s == e)
117219b2ee8SDavid du Colombier break;
118219b2ee8SDavid du Colombier s = e;
119219b2ee8SDavid du Colombier fl = strtoul(s, &e, 10);
120219b2ee8SDavid du Colombier if(s == e)
121219b2ee8SDavid du Colombier break;
122219b2ee8SDavid du Colombier s = e;
123219b2ee8SDavid du Colombier ofl = strtoul(s, &e, 10);
124219b2ee8SDavid du Colombier if(s == e)
125219b2ee8SDavid du Colombier break;
126219b2ee8SDavid du Colombier s = e;
127219b2ee8SDavid du Colombier if(fd < OPEN_MAX){
128219b2ee8SDavid du Colombier fi = &_fdinfo[fd];
129*d9306527SDavid du Colombier if(usedproc && !(fi->flags&FD_ISOPEN))
130*d9306527SDavid du Colombier continue; /* should probably ignore all of $_fdinit */
131219b2ee8SDavid du Colombier fi->flags = fl;
132219b2ee8SDavid du Colombier fi->oflags = ofl;
133219b2ee8SDavid du Colombier if(_isatty(fd))
134219b2ee8SDavid du Colombier fi->flags |= FD_ISTTY;
135219b2ee8SDavid du Colombier }
136219b2ee8SDavid du Colombier }
137*d9306527SDavid du Colombier
138219b2ee8SDavid du Colombier }
139*d9306527SDavid du Colombier
140*d9306527SDavid du Colombier void
_fdinit(char * s,char * se)141*d9306527SDavid du Colombier _fdinit(char *s, char *se)
142*d9306527SDavid du Colombier {
143*d9306527SDavid du Colombier int i, usedproc;
144*d9306527SDavid du Colombier Fdinfo *fi;
145*d9306527SDavid du Colombier struct stat sbuf;
146*d9306527SDavid du Colombier
147*d9306527SDavid du Colombier usedproc = 0;
148*d9306527SDavid du Colombier if(readprocfdinit() == 0)
149*d9306527SDavid du Colombier usedproc = 1;
150*d9306527SDavid du Colombier else
151*d9306527SDavid du Colombier _WRITE(2, "FAILED\n", 7);
152*d9306527SDavid du Colombier if(s)
153*d9306527SDavid du Colombier sfdinit(usedproc, s, se);
154*d9306527SDavid du Colombier if(!s && !usedproc)
155*d9306527SDavid du Colombier defaultfdinit();
156*d9306527SDavid du Colombier
157219b2ee8SDavid du Colombier for(i = 0; i < OPEN_MAX; i++) {
158219b2ee8SDavid du Colombier fi = &_fdinfo[i];
159219b2ee8SDavid du Colombier if(fi->flags&FD_ISOPEN){
160219b2ee8SDavid du Colombier if(fstat(i, &sbuf) >= 0) {
161219b2ee8SDavid du Colombier fi->uid = sbuf.st_uid;
162219b2ee8SDavid du Colombier fi->gid = sbuf.st_gid;
163219b2ee8SDavid du Colombier }
164219b2ee8SDavid du Colombier }
165219b2ee8SDavid du Colombier }
166219b2ee8SDavid du Colombier }
167219b2ee8SDavid du Colombier
168