diff options
| author | Brent Cook <busterb@gmail.com> | 2017-01-15 10:17:13 -0600 |
|---|---|---|
| committer | Brent Cook <busterb@gmail.com> | 2017-01-15 16:00:16 -0600 |
| commit | dbd5fb28ec73a2d47ad0dd4530728f835dcf65aa (patch) | |
| tree | 86b2828d33db7ccb3d837918172c3d5154e7a466 /tests | |
| parent | dfb6b11e5a5ba21c6658d87b4df83c2a05d2deab (diff) | |
| download | portable-dbd5fb28ec73a2d47ad0dd4530728f835dcf65aa.tar.gz portable-dbd5fb28ec73a2d47ad0dd4530728f835dcf65aa.tar.bz2 portable-dbd5fb28ec73a2d47ad0dd4530728f835dcf65aa.zip | |
add windows versions of socketpair / pipe
Diffstat (limited to 'tests')
| -rw-r--r-- | tests/compat/pipe2.c | 127 |
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 | |||
| 17 | static 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 | |||
| 28 | static 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 | |||
| 38 | int 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 | |||
| 90 | err: | ||
| 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 | |||
| 101 | int pipe(int fildes[2]) | ||
| 102 | { | ||
| 103 | return socketpair(AF_UNIX, SOCK_STREAM | SOCK_NONBLOCK, PF_UNSPEC, fildes); | ||
| 104 | } | ||
| 105 | |||
| 106 | #else | ||
| 107 | |||
| 10 | static int setfd(int fd, int flag) | 108 | static 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 | ||
| 24 | int pipe2(int fildes[2], int flags) | 123 | int 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; |
