| 326 } |
326 } |
| 327 |
327 |
| 328 return result; |
328 return result; |
| 329 } |
329 } |
| 330 |
330 |
| |
331 int wpurple_input_pipe(int pipefd[2]) |
| |
332 { |
| |
333 SOCKET sock_server, sock_client, sock_server_established; |
| |
334 struct sockaddr_in saddr_in; |
| |
335 struct sockaddr * const saddr_p = (struct sockaddr *)&saddr_in; |
| |
336 int saddr_len = sizeof(struct sockaddr_in); |
| |
337 u_long arg; |
| |
338 fd_set select_set; |
| |
339 char succ = 1; |
| |
340 |
| |
341 sock_server = sock_client = sock_server_established = INVALID_SOCKET; |
| |
342 |
| |
343 purple_debug_misc("wpurple", "wpurple_input_pipe(0x%x[%d,%d])\n", |
| |
344 (unsigned int)pipefd, pipefd[0], pipefd[1]); |
| |
345 |
| |
346 /* create client and passive server sockets */ |
| |
347 sock_server = socket(AF_INET, SOCK_STREAM, 0); |
| |
348 sock_client = socket(AF_INET, SOCK_STREAM, 0); |
| |
349 succ = (sock_server != INVALID_SOCKET || sock_client != INVALID_SOCKET); |
| |
350 |
| |
351 /* set created sockets into nonblocking mode */ |
| |
352 arg = 1; |
| |
353 succ = (succ && |
| |
354 ioctlsocket(sock_server, FIONBIO, &arg) != SOCKET_ERROR); |
| |
355 arg = 1; |
| |
356 succ = (succ && |
| |
357 ioctlsocket(sock_client, FIONBIO, &arg) != SOCKET_ERROR); |
| |
358 |
| |
359 /* listen on server socket */ |
| |
360 memset(&saddr_in, 0, saddr_len); |
| |
361 saddr_in.sin_family = AF_INET; |
| |
362 saddr_in.sin_port = 0; |
| |
363 saddr_in.sin_addr.s_addr = htonl(INADDR_LOOPBACK); |
| |
364 succ = (succ && |
| |
365 bind(sock_server, saddr_p, saddr_len) != SOCKET_ERROR && |
| |
366 listen(sock_server, 1) != SOCKET_ERROR && |
| |
367 getsockname(sock_server, saddr_p, &saddr_len) != SOCKET_ERROR); |
| |
368 |
| |
369 /* request a connection from client to server socket */ |
| |
370 succ = (succ && |
| |
371 connect(sock_client, saddr_p, saddr_len) == SOCKET_ERROR && |
| |
372 WSAGetLastError() == WSAEWOULDBLOCK); |
| |
373 |
| |
374 /* ensure, that server socket is readable */ |
| |
375 if (succ) |
| |
376 { |
| |
377 FD_ZERO(&select_set); |
| |
378 FD_SET(sock_server, &select_set); |
| |
379 } |
| |
380 succ = (succ && |
| |
381 select(0, &select_set, NULL, NULL, NULL) != SOCKET_ERROR && |
| |
382 FD_ISSET(sock_server, &select_set)); |
| |
383 |
| |
384 /* accept (establish) connection from client socket */ |
| |
385 if (succ) |
| |
386 { |
| |
387 sock_server_established = |
| |
388 accept(sock_server, saddr_p, &saddr_len); |
| |
389 succ = (sock_server_established != INVALID_SOCKET); |
| |
390 } |
| |
391 |
| |
392 /* ensure, that client socket is writable */ |
| |
393 if (succ) |
| |
394 { |
| |
395 FD_ZERO(&select_set); |
| |
396 FD_SET(sock_client, &select_set); |
| |
397 } |
| |
398 succ = (succ && |
| |
399 select(0, NULL, &select_set, NULL, NULL) != SOCKET_ERROR && |
| |
400 FD_ISSET(sock_client, &select_set)); |
| |
401 |
| |
402 /* set sockets into blocking mode */ |
| |
403 arg = 0; |
| |
404 succ = (succ && |
| |
405 ioctlsocket(sock_client, FIONBIO, &arg) != SOCKET_ERROR); |
| |
406 arg = 0; |
| |
407 succ = (succ && |
| |
408 ioctlsocket(sock_server_established, FIONBIO, &arg) |
| |
409 != SOCKET_ERROR); |
| |
410 |
| |
411 /* we don't need (passive) server socket anymore */ |
| |
412 if (sock_server != INVALID_SOCKET) |
| |
413 closesocket(sock_server); |
| |
414 |
| |
415 if (succ) |
| |
416 { |
| |
417 purple_debug_misc("wpurple", |
| |
418 "wpurple_input_pipe created pipe [%d,%d]\n", |
| |
419 sock_client, sock_server_established); |
| |
420 pipefd[0] = sock_client; /* for reading */ |
| |
421 pipefd[1] = sock_server_established; /* for writing */ |
| |
422 return 0; |
| |
423 } |
| |
424 else |
| |
425 { |
| |
426 purple_debug_error("wpurple", "wpurple_input_pipe failed\n"); |
| |
427 if (sock_client != INVALID_SOCKET) |
| |
428 closesocket(sock_client); |
| |
429 if (sock_server_established != INVALID_SOCKET) |
| |
430 closesocket(sock_server_established); |
| |
431 errno = EMFILE; |
| |
432 return -1; |
| |
433 } |
| |
434 } |
| |
435 |
| 331 void wpurple_init(void) { |
436 void wpurple_init(void) { |
| 332 WORD wVersionRequested; |
437 WORD wVersionRequested; |
| 333 WSADATA wsaData; |
438 WSADATA wsaData; |
| 334 |
439 |
| 335 if (!g_thread_supported()) |
440 if (!g_thread_supported()) |