xref: /plan9-contrib/sys/src/ape/lib/ap/plan9/_fdinfo.c (revision 781103c4074deb8af160e8a0da2742ba6b29dc2b)
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