libpurple/win32/win32dep.c

branch
soc.2012.gg
changeset 33291
b70ab10887a7
parent 30738
34c16a8692ce
child 33861
71533f0d5dc0
equal deleted inserted replaced
33290:63898cecf274 33291:b70ab10887a7
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())

mercurial