xref: /php-src/win32/sockets.c (revision 01b3fc03)
1 /*
2    +----------------------------------------------------------------------+
3    | Copyright (c) The PHP Group                                          |
4    +----------------------------------------------------------------------+
5    | This source file is subject to version 3.01 of the PHP license,      |
6    | that is bundled with this package in the file LICENSE, and is        |
7    | available through the world-wide-web at the following url:           |
8    | https://www.php.net/license/3_01.txt                                 |
9    | If you did not receive a copy of the PHP license and are unable to   |
10    | obtain it through the world-wide-web, please send a note to          |
11    | license@php.net so we can mail you a copy immediately.               |
12    +----------------------------------------------------------------------+
13    | Authors: Chris Vandomelen <chrisv@b0rked.dhs.org>                    |
14    |          Sterling Hughes  <sterling@php.net>                         |
15    |                                                                      |
16    | WinSock: Daniel Beulshausen <daniel@php4win.de>                      |
17    +----------------------------------------------------------------------+
18  */
19 
20 /* Code originally from ext/sockets */
21 
22 #include <stdio.h>
23 #include <fcntl.h>
24 
25 #include "php.h"
26 
socketpair_win32(int domain,int type,int protocol,SOCKET sock[2],int overlapped)27 PHPAPI int socketpair_win32(int domain, int type, int protocol, SOCKET sock[2], int overlapped)
28 {
29 	struct sockaddr_in address;
30 	SOCKET redirect;
31 	int size = sizeof(address);
32 
33 	if (domain != AF_INET) {
34 		WSASetLastError(WSAENOPROTOOPT);
35 		return -1;
36 	}
37 
38 	sock[1] = redirect = INVALID_SOCKET;
39 
40 	sock[0] = socket(domain, type, protocol);
41 	if (INVALID_SOCKET == sock[0]) {
42 		goto error;
43 	}
44 
45 	address.sin_addr.s_addr	= INADDR_ANY;
46 	address.sin_family = AF_INET;
47 	address.sin_port = 0;
48 
49 	if (bind(sock[0], (struct sockaddr *) &address, sizeof(address)) != 0) {
50 		goto error;
51 	}
52 
53 	if (getsockname(sock[0], (struct sockaddr *) &address, &size) != 0) {
54 		goto error;
55 	}
56 
57 	if (listen(sock[0], 2) != 0) {
58 		goto error;
59 	}
60 
61 	if (overlapped) {
62 		sock[1] = socket(domain, type, protocol);
63 	} else {
64 		sock[1] = WSASocket(domain, type, protocol, NULL, 0, 0);
65 	}
66 
67 	if (INVALID_SOCKET == sock[1]) {
68 		goto error;
69 	}
70 
71 	address.sin_addr.s_addr = htonl(INADDR_LOOPBACK);
72 	if (connect(sock[1], (struct sockaddr *) &address, sizeof(address)) != 0) {
73 		goto error;
74 	}
75 
76 	redirect = accept(sock[0], (struct sockaddr *) &address, &size);
77 	if (INVALID_SOCKET == redirect) {
78 		goto error;
79 	}
80 
81 	closesocket(sock[0]);
82 	sock[0] = redirect;
83 
84 	return 0;
85 
86 error:
87 	closesocket(redirect);
88 	closesocket(sock[0]);
89 	closesocket(sock[1]);
90 	WSASetLastError(WSAECONNABORTED);
91 	return -1;
92 }
93 
socketpair(int domain,int type,int protocol,SOCKET sock[2])94 PHPAPI int socketpair(int domain, int type, int protocol, SOCKET sock[2])
95 {
96 	return socketpair_win32(domain, type, protocol, sock, 1);
97 }
98