Subversion Repositories planix.SVN

Rev

Rev 2 | Details | Compare with Previous | Last modification | View Log | RSS feed

Rev Author Line No. Line
2 - 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