Subversion Repositories planix.SVN

Rev

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

Rev Author Line No. Line
2 - 1
/* posix */
2
#include <sys/types.h>
3
#include <unistd.h>
4
#include <stdlib.h>
5
#include <stdio.h>
6
#include <errno.h>
7
#include <string.h>
8
#include <fcntl.h>
9
#include <sys/stat.h>
10
 
11
/* bsd extensions */
12
#include <sys/uio.h>
13
#include <sys/socket.h>
14
 
15
#include "priv.h"
16
 
17
Rock *_sock_rock;
18
 
19
Rock*
20
_sock_findrock(int fd, struct stat *dp)
21
{
22
	Rock *r;
23
	struct stat d;
24
 
25
	if(dp == 0)
26
		dp = &d;
27
	fstat(fd, dp);
28
	for(r = _sock_rock; r; r = r->next){
29
		if(r->inode == dp->st_ino
30
		&& r->dev == dp->st_dev)
31
			break;
32
	}
33
	return r;
34
}
35
 
36
Rock*
37
_sock_newrock(int fd)
38
{
39
	Rock *r;
40
	struct stat d;
41
 
42
	r = _sock_findrock(fd, &d);
43
	if(r == 0){
44
		r = malloc(sizeof(Rock));
45
		if(r == 0)
46
			return 0;
47
		r->dev = d.st_dev;
48
		r->inode = d.st_ino;
49
		r->other = -1;
50
		r->next = _sock_rock;
51
		_sock_rock = r;
52
	}
53
	memset(&r->raddr, 0, sizeof(r->raddr));
54
	memset(&r->addr, 0, sizeof(r->addr));
55
	r->reserved = 0;
56
	r->dev = d.st_dev;
57
	r->inode = d.st_ino;
58
	r->other = -1;
59
	return r;
60
}
61
 
62
int
63
_sock_data(int cfd, char *net, int domain, int stype, int protocol, Rock **rp)
64
{
65
	int n, fd;
66
	Rock *r;
67
	char name[Ctlsize];
68
 
69
	/* get the data file name */
70
	n = read(cfd, name, sizeof(name)-1);
71
	if(n < 0){
72
		close(cfd);
73
		errno = ENOBUFS;
74
		return -1;
75
	}
76
	name[n] = 0;
77
	n = strtoul(name, 0, 0);
78
	snprintf(name, sizeof name, "/net/%s/%d/data", net, n);
79
 
80
	/* open data file */
81
	fd = open(name, O_RDWR);
82
	close(cfd);
83
	if(fd < 0){
84
		close(cfd);
85
		errno = ENOBUFS;
86
		return -1;
87
	}
88
 
89
	/* hide stuff under the rock */
90
	snprintf(name, sizeof name, "/net/%s/%d/ctl", net, n);
91
	r = _sock_newrock(fd);
92
	if(r == 0){
93
		errno = ENOBUFS;
94
		close(fd);
95
		return -1;
96
	}
97
	if(rp)
98
		*rp = r;
99
	memset(&r->raddr, 0, sizeof(r->raddr));
100
	memset(&r->addr, 0, sizeof(r->addr));
101
	r->domain = domain;
102
	r->stype = stype;
103
	r->protocol = protocol;
104
	strcpy(r->ctl, name);
105
	return fd;
106
}
107
 
108
int
109
socket(int domain, int stype, int protocol)
110
{
111
	Rock *r;
112
	int cfd;
113
	int pfd[2];
114
	char *net;
115
 
116
	switch(domain){
117
	case PF_INET:
118
		/* get a free network directory */
119
		switch(stype){
120
		case SOCK_DGRAM:
121
			net = "udp";
122
			cfd = open("/net/udp/clone", O_RDWR);
123
			break;
124
		case SOCK_STREAM:
125
			net = "tcp";
126
			cfd = open("/net/tcp/clone", O_RDWR);
127
			break;
128
		default:
129
			errno = EPROTONOSUPPORT;
130
			return -1;
131
		}
132
		if(cfd < 0){
133
			_syserrno();
134
			return -1;
135
		}
136
		return _sock_data(cfd, net, domain, stype, protocol, 0);
137
	case PF_UNIX:
138
		if(pipe(pfd) < 0){
139
			_syserrno();
140
			return -1;
141
		}
142
		r = _sock_newrock(pfd[0]);
143
		r->domain = domain;
144
		r->stype = stype;
145
		r->protocol = protocol;
146
		r->other = pfd[1];
147
		return pfd[0];
148
	default:
149
		errno = EPROTONOSUPPORT;
150
		return -1;
151
	}
152
}
153
 
154
int
155
issocket(int fd)
156
{
157
	Rock *r;
158
 
159
	r = _sock_findrock(fd, 0);
160
	return (r != 0);
161
}
162
 
163
/*
164
 * probably should do better than this
165
 */
166
int getsockopt(int, int, int, void *, int *)
167
{
168
	return -1;
169
}
170
 
171
int setsockopt(int, int, int, void *, int)
172
{
173
	return 0;
174
}
175