xref: /plan9/sys/src/ape/lib/bsd/socket.c (revision 781103c4074deb8af160e8a0da2742ba6b29dc2b)
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*
_sock_findrock(int fd,struct stat * dp)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*
_sock_newrock(int fd)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
_sock_data(int cfd,char * net,int domain,int stype,int protocol,Rock ** rp)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
socket(int domain,int stype,int protocol)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
issocket(int fd)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  */
getsockopt(int,int,int,void *,int *)166 int getsockopt(int, int, int, void *, int *)
167 {
168 	return -1;
169 }
170 
setsockopt(int,int,int,void *,int)171 int setsockopt(int, int, int, void *, int)
172 {
173 	return 0;
174 }
175 
176