aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorBrent Cook <busterb@gmail.com>2017-01-15 10:17:13 -0600
committerBrent Cook <busterb@gmail.com>2017-01-15 16:00:16 -0600
commitdbd5fb28ec73a2d47ad0dd4530728f835dcf65aa (patch)
tree86b2828d33db7ccb3d837918172c3d5154e7a466
parentdfb6b11e5a5ba21c6658d87b4df83c2a05d2deab (diff)
downloadportable-dbd5fb28ec73a2d47ad0dd4530728f835dcf65aa.tar.gz
portable-dbd5fb28ec73a2d47ad0dd4530728f835dcf65aa.tar.bz2
portable-dbd5fb28ec73a2d47ad0dd4530728f835dcf65aa.zip
add windows versions of socketpair / pipe
-rw-r--r--tests/compat/pipe2.c127
1 files changed, 119 insertions, 8 deletions
diff --git a/tests/compat/pipe2.c b/tests/compat/pipe2.c
index e2aaa28..7600783 100644
--- a/tests/compat/pipe2.c
+++ b/tests/compat/pipe2.c
@@ -1,12 +1,110 @@
1/* 1/*
2 * Public domain 2 * Public domain
3 *
4 * pipe2/pipe/socketpair emulation
5 * Brent Cook <bcook@openbsd.org>
3 */ 6 */
4 7
8#include <errno.h>
5#include <fcntl.h> 9#include <fcntl.h>
6#include <unistd.h> 10#include <unistd.h>
7#include <sys/socket.h> 11#include <sys/socket.h>
12
8#undef socketpair 13#undef socketpair
9 14
15#ifdef _WIN32
16
17static int setfd(int fd, int flag)
18{
19 int rc = -1;
20 if (flag & FD_CLOEXEC) {
21 HANDLE h = (HANDLE)_get_osfhandle(fd);
22 if (h != NULL)
23 rc = SetHandleInformation(h, HANDLE_FLAG_INHERIT, 0) == 0 ? -1 : 0;
24 }
25 return rc;
26}
27
28static int setfl(int fd, int flag)
29{
30 int rc = -1;
31 if (flag & O_NONBLOCK) {
32 long mode = 1;
33 rc = ioctlsocket(fd, FIONBIO, &mode);
34 }
35 return rc;
36}
37
38int socketpair(int domain, int type, int protocol, int socket_vector[2])
39{
40 if (domain != AF_UNIX || !(type & SOCK_STREAM) || protocol != PF_UNSPEC)
41 return -1;
42
43 socket_vector[0] = -1;
44 socket_vector[1] = -1;
45
46 int listener = socket(AF_INET, SOCK_STREAM, IPPROTO_TCP);
47 if (listener == -1) {
48 return -1;
49 }
50
51 struct sockaddr_in addr = {
52 .sin_family = AF_INET,
53 .sin_addr.s_addr = htonl(INADDR_LOOPBACK),
54 .sin_port = 0,
55 };
56
57 int yes = 1, e;
58 if (setsockopt(listener, SOL_SOCKET, SO_REUSEADDR,
59 (void *)&yes, sizeof yes) == -1)
60 goto err;
61
62 if (bind(listener, (struct sockaddr *)&addr, sizeof addr) != 0)
63 goto err;
64
65 memset(&addr, 0, sizeof addr);
66 socklen_t addrlen = sizeof addr;
67 if (getsockname(listener, (struct sockaddr *)&addr, &addrlen) != 0)
68 goto err;
69
70 addr.sin_addr.s_addr = htonl(INADDR_LOOPBACK);
71 addr.sin_family = AF_INET;
72
73 if (listen(listener, 1) != 0)
74 goto err;
75
76 socket_vector[0] = WSASocket(AF_INET, SOCK_STREAM, 0, NULL, 0, 0);
77 if (socket_vector[0] == -1)
78 goto err;
79
80 if (connect(socket_vector[0], (struct sockaddr *)&addr, sizeof addr) != 0)
81 goto err;
82
83 socket_vector[1] = accept(listener, NULL, NULL);
84 if (socket_vector[1] == -1)
85 goto err;
86
87 closesocket(listener);
88 return 0;
89
90err:
91 e = WSAGetLastError();
92 closesocket(listener);
93 closesocket(socket_vector[0]);
94 closesocket(socket_vector[1]);
95 WSASetLastError(e);
96 socket_vector[0] = -1;
97 socket_vector[1] = -1;
98 return -1;
99}
100
101int pipe(int fildes[2])
102{
103 return socketpair(AF_UNIX, SOCK_STREAM | SOCK_NONBLOCK, PF_UNSPEC, fildes);
104}
105
106#else
107
10static int setfd(int fd, int flag) 108static int setfd(int fd, int flag)
11{ 109{
12 int flags = fcntl(fd, F_GETFD); 110 int flags = fcntl(fd, F_GETFD);
@@ -20,18 +118,25 @@ static int setfl(int fd, int flag)
20 flags |= flag; 118 flags |= flag;
21 return fcntl(fd, F_SETFL, flags); 119 return fcntl(fd, F_SETFL, flags);
22} 120}
121#endif
23 122
24int pipe2(int fildes[2], int flags) 123int pipe2(int fildes[2], int flags)
25{ 124{
26 int rc = pipe(fildes); 125 int rc = pipe(fildes);
27 if (rc == 0) { 126 if (rc == 0) {
28 if (flags & O_NONBLOCK) { 127 if (flags & O_NONBLOCK) {
29 setfl(fildes[0], O_NONBLOCK); 128 rc |= setfl(fildes[0], O_NONBLOCK);
30 setfl(fildes[1], O_NONBLOCK); 129 rc |= setfl(fildes[1], O_NONBLOCK);
31 } 130 }
32 if (flags & O_CLOEXEC) { 131 if (flags & O_CLOEXEC) {
33 setfd(fildes[0], FD_CLOEXEC); 132 rc |= setfd(fildes[0], FD_CLOEXEC);
34 setfd(fildes[1], FD_CLOEXEC); 133 rc |= setfd(fildes[1], FD_CLOEXEC);
134 }
135 if (rc != 0) {
136 int e = errno;
137 close(fildes[0]);
138 close(fildes[1]);
139 errno = e;
35 } 140 }
36 } 141 }
37 return rc; 142 return rc;
@@ -44,12 +149,18 @@ int bsd_socketpair(int domain, int type, int protocol, int socket_vector[2])
44 int rc = socketpair(domain, type, protocol, socket_vector); 149 int rc = socketpair(domain, type, protocol, socket_vector);
45 if (rc == 0) { 150 if (rc == 0) {
46 if (flags & SOCK_NONBLOCK) { 151 if (flags & SOCK_NONBLOCK) {
47 setfl(socket_vector[0], O_NONBLOCK); 152 rc |= setfl(socket_vector[0], O_NONBLOCK);
48 setfl(socket_vector[1], O_NONBLOCK); 153 rc |= setfl(socket_vector[1], O_NONBLOCK);
49 } 154 }
50 if (flags & SOCK_CLOEXEC) { 155 if (flags & SOCK_CLOEXEC) {
51 setfd(socket_vector[0], FD_CLOEXEC); 156 rc |= setfd(socket_vector[0], FD_CLOEXEC);
52 setfd(socket_vector[1], FD_CLOEXEC); 157 rc |= setfd(socket_vector[1], FD_CLOEXEC);
158 }
159 if (rc != 0) {
160 int e = errno;
161 close(socket_vector[0]);
162 close(socket_vector[1]);
163 errno = e;
53 } 164 }
54 } 165 }
55 return rc; 166 return rc;