1 /* this file is intentionally ugly */
2 #ifndef __sio_h
3 #define __sio_h
4
5 #include "config.h"
6
7 /* synchronized I/O */
8 #ifdef HAVE_POLL
9 #include <sys/types.h>
10 #include <sys/poll.h>
11 #else
12 #include <sys/time.h>
13 #include <sys/types.h>
14 #include <unistd.h>
15 #endif
16
17 #include "bin.h"
18
19 #define sio_read 1
20 #define sio_write 2
21 #define sio_infinite -1
22 #define sio_infinity sio_infinite
23
sio_test(bin_t b,int fd)24 int inline sio_test(bin_t b, int fd)
25 {
26 register int op;
27 #ifdef HAVE_POLL
28 struct pollfd *pf;
29 register int i;
30 int pfnum;
31
32 pf = (struct pollfd *)caddr(b);
33 if (!pf)
34 return 0;
35
36 pfnum = (bin_len(b)) / sizeof(struct pollfd);
37 for (i = 0; i < pfnum; i++) {
38 if (pf[i].fd == fd) {
39 op = 0;
40 if (pf[i].revents & (POLLIN|POLLPRI|POLLHUP))
41 op |= sio_read;
42 if (pf[i].revents & POLLOUT)
43 op |= sio_write;
44 return op;
45 }
46 }
47 return 0;
48 #else
49 fd_set *r, *w;
50
51 if (caddr(b) == 0)
52 return 0;
53
54 bin_need(b, sizeof(fd_set) * 2);
55 r = (fd_set *)(caddr(b));
56 w = (fd_set *)(((char *)caddr(b)) + sizeof(fd_set));
57
58 op = 0;
59 if (FD_ISSET(fd, r))
60 op |= sio_read;
61 if (FD_ISSET(fd, w))
62 op |= sio_write;
63
64 return op;
65 #endif
66 }
67
sio_block(bin_t b,int timeout)68 int inline sio_block(bin_t b, int timeout)
69 {
70 #ifdef HAVE_POLL
71 struct pollfd *pf;
72 int pfnum;
73
74 pf = (struct pollfd *)caddr(b);
75 if (!pf)
76 return 0;
77
78 pfnum = (bin_len(b)) / sizeof(struct pollfd);
79
80 return poll(pf, pfnum, timeout);
81 #else
82 fd_set *r, *w;
83 struct timeval tv;
84 int high;
85
86 if (caddr(b) == 0)
87 return 0;
88
89 bin_need(b, sizeof(fd_set) * 2);
90 r = (fd_set *)(caddr(b));
91 w = (fd_set *)(((char *)caddr(b)) + sizeof(fd_set));
92 high = *(int *)(((char *)caddr(b)) + (sizeof(fd_set)+sizeof(fd_set)));
93
94 if (timeout < 0) {
95 return select(high+1, r, w, 0, 0);
96 } else {
97 tv.tv_sec = 0;
98 tv.tv_usec = timeout;
99 return select(high+1, r, w, 0, &tv);
100 }
101 #endif
102 }
sio_remove(bin_t b,int fd)103 void inline sio_remove(bin_t b, int fd)
104 {
105 #ifdef HAVE_POLL
106 struct pollfd *pf;
107 register int i;
108 int pfnum;
109
110 pf = (struct pollfd *)caddr(b);
111 if (pf) {
112 pfnum = (bin_len(b)) / sizeof(struct pollfd);
113
114 for (i = 0; i < pfnum; i++) {
115 if (fd == -1 || pf[i].fd == fd) {
116 pf[i].fd = -1;
117 pf[i].events = 0;
118 pf[i].revents = 0;
119 if (fd != -1)
120 break;
121 }
122 }
123 }
124 #else
125 fd_set *r, *w;
126 register int i;
127 int *high;
128
129 i = (caddr(b) == 0) ? 1 : 0;
130 bin_need(b, (sizeof(fd_set) * 2) + sizeof(int));
131 r = (fd_set *)(caddr(b));
132 w = (fd_set *)(((char *)caddr(b)) + sizeof(fd_set));
133 high = (int *)(((char *)caddr(b)) + (sizeof(fd_set)+sizeof(fd_set)));
134
135 if (i || fd == -1) {
136 FD_ZERO(r); FD_ZERO(w);
137 *high = 0;
138 } else {
139 FD_CLR(fd, r);
140 FD_CLR(fd, w);
141 }
142 #endif
143 }
sio_flush(bin_t b)144 void inline sio_flush(bin_t b)
145 {
146 sio_remove(b, -1);
147 }
sio_add(bin_t b,int fd,int ops)148 void inline sio_add(bin_t b, int fd, int ops)
149 {
150 #ifdef HAVE_POLL
151 struct pollfd *pf;
152 register int i;
153 int pfnum;
154
155 if (fd == -1)
156 return;
157
158 /* search for a -1 */
159 pf = (struct pollfd *)caddr(b);
160 if (!pf) {
161 i = pfnum = 0;
162 } else {
163 pfnum = (bin_len(b)) / sizeof(struct pollfd);
164
165 for (i = 0; i < pfnum; i++) {
166 if (pf[i].fd == -1)
167 break;
168 }
169 }
170 if (i == pfnum) {
171 bin_needplus(b, sizeof(struct pollfd));
172 clen(b) = bin_len(b); /* update length */
173 pf = (struct pollfd *)caddr(b);
174 }
175 pf[i].fd = fd;
176 pf[i].events = 0;
177 pf[i].revents = 0;
178 if (ops & sio_read)
179 pf[i].events |= (POLLIN|POLLPRI);
180 if (ops & sio_write)
181 pf[i].events |= POLLOUT;
182 #else
183 fd_set *r, *w;
184 register int i;
185 int *high;
186
187 if (fd == -1)
188 return;
189
190 i = (caddr(b) == 0) ? 1 : 0;
191 bin_need(b, (sizeof(fd_set) * 2) + sizeof(int));
192 r = (fd_set *)(caddr(b));
193 w = (fd_set *)(((char *)caddr(b)) + sizeof(fd_set));
194 high = (int *)(((char *)caddr(b)) + (sizeof(fd_set)+sizeof(fd_set)));
195
196 if (i) {
197 FD_ZERO(r); FD_ZERO(w);
198 *high = fd;
199 } else if (fd > *high)
200 *high = fd;
201
202 if (ops & sio_read)
203 FD_SET(fd, r);
204 if (ops & sio_write)
205 FD_SET(fd, w);
206 #endif
207 }
208
209 #endif
210