xref: /inferno-os/tools/libstyx/Posix.c (revision 7ef44d652ae9e5e1f5b3465d73684e4a54de73c0)
1 #define	__EXTENSIONS__
2 #define	_BSD_COMPAT
3 #include <lib9.h>
4 #include 	<sys/types.h>
5 #include	<sys/time.h>
6 #include	<sys/socket.h>
7 #include	<netinet/in.h>
8 
9 #include "styxserver.h"
10 #include "styxaux.h"
11 
12 typedef struct Fdset Fdset;
13 
14 struct Fdset
15 {
16 	fd_set infds, outfds, excfds, r_infds, r_outfds, r_excfds;
17 };
18 
19 int
20 styxinitsocket(void)
21 {
22 	return 0;
23 }
24 
25 void
26 styxendsocket(void)
27 {
28 }
29 
30 void
31 styxclosesocket(int fd)
32 {
33 	close(fd);
34 }
35 
36 int
37 styxannounce(Styxserver *server, char *port)
38 {
39 	struct sockaddr_in sin;
40 	int s, one;
41 
42 	USED(server);
43 	s = socket(AF_INET, SOCK_STREAM, 0);
44 	if(s < 0)
45 		return s;
46 	one = 1;
47 	if(setsockopt(s, SOL_SOCKET, SO_REUSEADDR, (char*)&one, sizeof(one)) < 0)
48 		fprint(2, "setsockopt failed\n");
49 	memset(&sin, 0, sizeof(sin));
50 	sin.sin_family = AF_INET;
51 	sin.sin_addr.s_addr = 0;
52 	sin.sin_port = htons(atoi(port));
53 	if(bind(s, (struct sockaddr *)&sin, sizeof(sin)) < 0){
54 		close(s);
55 		return -1;
56 	}
57 	if(listen(s, 20) < 0){
58 		close(s);
59 		return -1;
60 	}
61 	return s;
62 }
63 
64 int
65 styxaccept(Styxserver *server)
66 {
67 	struct sockaddr_in sin;
68 	int s;
69 	socklen_t len;
70 
71 	len = sizeof(sin);
72 	memset(&sin, 0, sizeof(sin));
73 	sin.sin_family = AF_INET;
74 	s = accept(server->connfd, (struct sockaddr *)&sin, &len);
75 	if(s < 0){
76 		if(errno != EINTR)
77 			fprint(2, "error in accept: %s\n", strerror(errno));
78 	}
79 	return s;
80 }
81 
82 void
83 styxinitwait(Styxserver *server)
84 {
85 	Fdset *fs;
86 
87 	server->priv = fs = malloc(sizeof(Fdset));
88 	FD_ZERO(&fs->infds);
89 	FD_ZERO(&fs->outfds);
90 	FD_ZERO(&fs->excfds);
91 	FD_SET(server->connfd, &fs->infds);
92 }
93 
94 int
95 styxnewcall(Styxserver *server)
96 {
97 	Fdset *fs;
98 
99 	fs = server->priv;
100 	return FD_ISSET(server->connfd, &fs->r_infds);
101 }
102 
103 void
104 styxnewclient(Styxserver *server, int s)
105 {
106 	Fdset *fs;
107 
108 	fs = server->priv;
109 	FD_SET(s, &fs->infds);
110 }
111 
112 void
113 styxfreeclient(Styxserver *server, int s)
114 {
115 	Fdset *fs;
116 
117 	fs = server->priv;
118 	FD_CLR(s, &fs->infds);
119 }
120 
121 int
122 styxnewmsg(Styxserver *server, int s)
123 {
124 	Fdset *fs;
125 
126 	fs = server->priv;
127 	return FD_ISSET(s, &fs->r_infds) || FD_ISSET(s, &fs->r_excfds);
128 }
129 
130 char*
131 styxwaitmsg(Styxserver *server)
132 {
133 	struct timeval seltime;
134 	int nfds;
135 	Fdset *fs;
136 
137 	fs = server->priv;
138 	fs->r_infds = fs->infds;
139 	fs->r_outfds = fs->outfds;
140 	fs->r_excfds = fs->excfds;
141 	seltime.tv_sec = 10;
142 	seltime.tv_usec = 0L;
143 	nfds = select(sizeof(fd_set)*8, &fs->r_infds, &fs->r_outfds, &fs->r_excfds, &seltime);
144 	if(nfds < 0 && errno != EINTR)
145 		return"error in select";
146 	return nil;
147 }
148 
149 int
150 styxrecv(Styxserver *server, int fd, char *buf, int n, int m)
151 {
152 	return recv(fd, buf, n, m);
153 }
154 
155 int
156 styxsend(Styxserver *server, int fd, char *buf, int n, int m)
157 {
158 	return send(fd, buf, n, m);
159 }
160 
161 void
162 styxexit(int n)
163 {
164 	exit(n);
165 }
166