Skip to content
Newer
Older
100644 269 lines (240 sloc) 5.64 KB
7ed5be2 @WinterMute build with mingw
WinterMute authored Apr 29, 2012
1 #ifdef __MINGW32__
2
3 #include "mingw.h"
4
6db2766 @WinterMute undefine macros for socket redirection, fix warnings
WinterMute authored Apr 29, 2012
5 #undef socket
6 #undef connect
7 #undef accept
8 #undef shutdown
9
7ed5be2 @WinterMute build with mingw
WinterMute authored Apr 29, 2012
10 #include <string.h>
11 #include <errno.h>
12 #include <assert.h>
13
14 int win32_poll(struct pollfd *fds, unsigned int nfds, int timo)
15 {
16 struct timeval timeout, *toptr;
17 fd_set ifds, ofds, efds, *ip, *op;
6db2766 @WinterMute undefine macros for socket redirection, fix warnings
WinterMute authored Apr 29, 2012
18 unsigned int i, rc;
7ed5be2 @WinterMute build with mingw
WinterMute authored Apr 29, 2012
19
20 /* Set up the file-descriptor sets in ifds, ofds and efds. */
21 FD_ZERO(&ifds);
22 FD_ZERO(&ofds);
23 FD_ZERO(&efds);
24 for (i = 0, op = ip = 0; i < nfds; ++i) {
25 fds[i].revents = 0;
26 if(fds[i].events & (POLLIN|POLLPRI)) {
27 ip = &ifds;
28 FD_SET(fds[i].fd, ip);
29 }
30 if(fds[i].events & POLLOUT) {
31 op = &ofds;
32 FD_SET(fds[i].fd, op);
33 }
34 FD_SET(fds[i].fd, &efds);
35 }
36
37 /* Set up the timeval structure for the timeout parameter */
38 if(timo < 0) {
39 toptr = 0;
40 } else {
41 toptr = &timeout;
42 timeout.tv_sec = timo / 1000;
43 timeout.tv_usec = (timo - timeout.tv_sec * 1000) * 1000;
44 }
45
46 #ifdef DEBUG_POLL
47 printf("Entering select() sec=%ld usec=%ld ip=%lx op=%lx\n",
48 (long)timeout.tv_sec, (long)timeout.tv_usec, (long)ip, (long)op);
49 #endif
50 rc = select(0, ip, op, &efds, toptr);
51 #ifdef DEBUG_POLL
52 printf("Exiting select rc=%d\n", rc);
53 #endif
54
55 if(rc <= 0)
56 return rc;
57
58 if(rc > 0) {
6db2766 @WinterMute undefine macros for socket redirection, fix warnings
WinterMute authored Apr 29, 2012
59 for ( i = 0; i < nfds; ++i) {
7ed5be2 @WinterMute build with mingw
WinterMute authored Apr 29, 2012
60 int fd = fds[i].fd;
61 if(fds[i].events & (POLLIN|POLLPRI) && FD_ISSET(fd, &ifds))
62 fds[i].revents |= POLLIN;
63 if(fds[i].events & POLLOUT && FD_ISSET(fd, &ofds))
64 fds[i].revents |= POLLOUT;
65 if(FD_ISSET(fd, &efds))
66 /* Some error was detected ... should be some way to know. */
67 fds[i].revents |= POLLHUP;
68 #ifdef DEBUG_POLL
69 printf("%d %d %d revent = %x\n",
70 FD_ISSET(fd, &ifds), FD_ISSET(fd, &ofds), FD_ISSET(fd, &efds),
71 fds[i].revents
72 );
73 #endif
74 }
75 }
76 return rc;
77 }
78 static void
79 set_connect_errno(int winsock_err)
80 {
81 switch(winsock_err) {
82 case WSAEINVAL:
83 case WSAEALREADY:
84 case WSAEWOULDBLOCK:
85 errno = EINPROGRESS;
86 break;
87 default:
88 errno = winsock_err;
89 break;
90 }
91 }
92
93 static void
94 set_socket_errno(int winsock_err)
95 {
96 switch(winsock_err) {
97 case WSAEWOULDBLOCK:
98 errno = EAGAIN;
99 break;
100 default:
101 errno = winsock_err;
102 break;
103 }
104 }
105 /*
106 * A wrapper around the socket() function. The purpose of this wrapper
107 * is to ensure that the global errno symbol is set if an error occurs,
108 * even if we are using winsock.
109 */
110 SOCKET
111 win32_socket(int domain, int type, int protocol)
112 {
113 SOCKET fd = socket(domain, type, protocol);
114 if(fd == INVALID_SOCKET) {
115 set_socket_errno(WSAGetLastError());
116 }
117 return fd;
118 }
119 /*
120 * A wrapper around the connect() function. The purpose of this wrapper
121 * is to ensure that the global errno symbol is set if an error occurs,
122 * even if we are using winsock.
123 */
124 int
125 win32_connect(SOCKET fd, struct sockaddr *addr, socklen_t addr_len)
126 {
127 int rc = connect(fd, addr, addr_len);
128 assert(rc == 0 || rc == SOCKET_ERROR);
129 if(rc == SOCKET_ERROR) {
130 set_connect_errno(WSAGetLastError());
131 }
132 return rc;
133 }
134
135 /*
136 * A wrapper around the accept() function. The purpose of this wrapper
137 * is to ensure that the global errno symbol is set if an error occurs,
138 * even if we are using winsock.
139 */
140 SOCKET
141 win32_accept(SOCKET fd, struct sockaddr *addr, socklen_t *addr_len)
142 {
143 SOCKET newfd = accept(fd, addr, addr_len);
144 if(newfd == INVALID_SOCKET) {
145 set_socket_errno(WSAGetLastError());
146 newfd = -1;
147 }
148 return newfd;
149 }
150
151 /*
152 * A wrapper around the shutdown() function. The purpose of this wrapper
153 * is to ensure that the global errno symbol is set if an error occurs,
154 * even if we are using winsock.
155 */
156 int
157 win32_shutdown(SOCKET fd, int mode)
158 {
159 int rc = shutdown(fd, mode);
160 assert(rc == 0 || rc == SOCKET_ERROR);
161 if(rc == SOCKET_ERROR) {
162 set_socket_errno(WSAGetLastError());
163 }
164 return rc;
165 }
166 int win32_close_socket(SOCKET fd) {
167 int rc;
168
169 rc = closesocket(fd);
6db2766 @WinterMute undefine macros for socket redirection, fix warnings
WinterMute authored Apr 29, 2012
170 return rc;
7ed5be2 @WinterMute build with mingw
WinterMute authored Apr 29, 2012
171 }
172
173
49bafd8 @WinterMute wrap read/write socket functions on mingw
WinterMute authored Apr 29, 2012
174 ssize_t win32_write_socket(SOCKET fd, void *buf, int n)
7ed5be2 @WinterMute build with mingw
WinterMute authored Apr 29, 2012
175 {
176 int rc = send(fd, buf, n, 0);
177 if(rc == SOCKET_ERROR) {
178 set_socket_errno(WSAGetLastError());
179 }
180 return rc;
181 }
182
49bafd8 @WinterMute wrap read/write socket functions on mingw
WinterMute authored Apr 29, 2012
183 ssize_t win32_read_socket(SOCKET fd, void *buf, int n)
7ed5be2 @WinterMute build with mingw
WinterMute authored Apr 29, 2012
184 {
185 int rc = recv(fd, buf, n, 0);
186 if(rc == SOCKET_ERROR) {
187 set_socket_errno(WSAGetLastError());
188 }
189 return rc;
190 }
191
192
193 char * win32_strtok_r(char *s, const char *delim, char **lasts)
194 {
195 register char *spanp;
196 register int c, sc;
197 char *tok;
198
199
200 if (s == NULL && (s = *lasts) == NULL)
201 return (NULL);
202
203 /*
204 * Skip (span) leading delimiters (s += strspn(s, delim), sort of).
205 */
206 cont:
207 c = *s++;
208 for (spanp = (char *)delim; (sc = *spanp++) != 0;) {
209 if (c == sc)
210 goto cont;
211 }
212
213 if (c == 0) { /* no non-delimiter characters */
214 *lasts = NULL;
215 return (NULL);
216 }
217 tok = s - 1;
218
219 /*
220 * Scan token (scan for delimiters: s += strcspn(s, delim), sort of).
221 * Note that delim must have one NUL; we stop if we see that, too.
222 */
223 for (;;) {
224 c = *s++;
225 spanp = (char *)delim;
226 do {
227 if ((sc = *spanp++) == c) {
228 if (c == 0)
229 s = NULL;
230 else
231 s[-1] = 0;
232 *lasts = s;
233 return (tok);
234 }
235 } while (sc != 0);
236 }
237 /* NOTREACHED */
238 }
239
240 char *win32_strsep (char **stringp, const char *delim)
241 {
242 register char *s;
243 register const char *spanp;
244 register int c, sc;
245 char *tok;
246
247 if ((s = *stringp) == NULL)
248 return (NULL);
249 for (tok = s;;) {
250 c = *s++;
251 spanp = delim;
252 do {
253 if ((sc = *spanp++) == c) {
254 if (c == 0)
255 s = NULL;
256 else
257 s[-1] = 0;
258 *stringp = s;
259 return (tok);
260 }
261 } while (sc != 0);
262 }
263 /* NOTREACHED */
264 }
265
266 #endif
267
268
Something went wrong with that request. Please try again.