ViewVC Help
View File | Revision Log | Show Annotations | Download File
/cvs/EV/schmorp.h
(Generate patch)

Comparing EV/schmorp.h (file contents):
Revision 1.2 by root, Tue Jul 14 02:33:55 2009 UTC vs.
Revision 1.3 by root, Tue Jul 14 20:31:21 2009 UTC

187 S_GENSUB_ARG = arg; 187 S_GENSUB_ARG = arg;
188 188
189 return newRV_noinc ((SV *)cv); 189 return newRV_noinc ((SV *)cv);
190} 190}
191 191
192#endif 192/** portable pipe/socketpair */
193 193
194#ifdef USE_SOCKETS_AS_HANDLES
195# define S_TO_SOCKET(x) (win32_get_osfhandle (x))
196#else
197# define S_TO_SOCKET(x) (x)
198#endif
199
200#ifdef _WIN32
201/* taken almost verbatim from libev's ev_win32.c */
202/* oh, the humanity! */
203static int
204s_pipe (int filedes [2])
205{
206 struct sockaddr_in addr = { 0 };
207 int addr_size = sizeof (addr);
208 struct sockaddr_in adr2;
209 int adr2_size = sizeof (adr2);
210 SOCKET listener;
211 SOCKET sock [2] = { -1, -1 };
212
213 if ((listener = socket (AF_INET, SOCK_STREAM, 0)) == INVALID_SOCKET)
214 return -1;
215
216 addr.sin_family = AF_INET;
217 addr.sin_addr.s_addr = htonl (INADDR_LOOPBACK);
218 addr.sin_port = 0;
219
220 if (bind (listener, (struct sockaddr *)&addr, addr_size))
221 goto fail;
222
223 if (getsockname (listener, (struct sockaddr *)&addr, &addr_size))
224 goto fail;
225
226 if (listen (listener, 1))
227 goto fail;
228
229 if ((sock [0] = socket (AF_INET, SOCK_STREAM, 0)) == INVALID_SOCKET)
230 goto fail;
231
232 if (connect (sock [0], (struct sockaddr *)&addr, addr_size))
233 goto fail;
234
235 if ((sock [1] = accept (listener, 0, 0)) < 0)
236 goto fail;
237
238 /* windows vista returns fantasy port numbers for getpeername.
239 * example for two interconnected tcp sockets:
240 *
241 * (Socket::unpack_sockaddr_in getsockname $sock0)[0] == 53364
242 * (Socket::unpack_sockaddr_in getpeername $sock0)[0] == 53363
243 * (Socket::unpack_sockaddr_in getsockname $sock1)[0] == 53363
244 * (Socket::unpack_sockaddr_in getpeername $sock1)[0] == 53365
245 *
246 * wow! tridirectional sockets!
247 *
248 * this way of checking ports seems to work:
249 */
250 if (getpeername (sock [0], (struct sockaddr *)&addr, &addr_size))
251 goto fail;
252
253 if (getsockname (sock [1], (struct sockaddr *)&adr2, &adr2_size))
254 goto fail;
255
256 errno = WSAEINVAL;
257 if (addr_size != adr2_size
258 || addr.sin_addr.s_addr != adr2.sin_addr.s_addr /* just to be sure, I mean, it's windows */
259 || addr.sin_port != adr2.sin_port)
260 goto fail;
261
262 closesocket (listener);
263
264#ifdef USE_SOCKETS_AS_HANDLES
265 /* when select isn't winsocket, we also expect socket, connect, accept etc.
266 * to work on fds */
267 filedes [0] = sock [0];
268 filedes [1] = sock [1];
269#else
270 filedes [0] = _open_osfhandle (sock [0], 0);
271 filedes [1] = _open_osfhandle (sock [1], 0);
272#endif
273
274 return 0;
275
276fail:
277 closesocket (listener);
278
279 if (sock [0] != INVALID_SOCKET) closesocket (sock [0]);
280 if (sock [1] != INVALID_SOCKET) closesocket (sock [1]);
281
282 return -1;
283}
284
285#define s_socketpair(domain,type,protocol,filedes) s_pipe (filedes)
286
287#else
288
289#define s_socketpair(domain,type,protocol,filedes) socketpair (domain, type, protocol, filedes)
290#define s_pipe(filedes) pipe (filedes)
291
292#endif
293
294#endif
295

Diff Legend

Removed lines
+ Added lines
< Changed lines
> Changed lines