4 * Redistribution and use in source and binary forms, with or without
5 * modification, are permitted provided that the following conditions are
8 * * Redistributions of source code must retain the above copyright
9 * notice, this list of conditions and the following disclaimer.
11 * * Redistributions in binary form must reproduce the above copyright
12 * notice, this list of conditions and the following disclaimer in the
13 * documentation and/or other materials provided with the distribution.
15 * * Neither the name of Red Hat nor the names of its contributors may be
16 * used to endorse or promote products derived from this software without
17 * specific prior written permission.
19 * THIS SOFTWARE IS PROVIDED BY RED HAT AND CONTRIBUTORS ''AS IS'' AND
20 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
21 * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A
22 * PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL RED HAT OR
23 * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
24 * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
25 * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF
26 * USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
27 * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
28 * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
29 * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
45 #include "windows-compat.h"
58 #define GET_SOCKET_FROM_FD(fd) \
59 SOCKET sk = _get_osfhandle (fd); \
60 if (sk == INVALID_SOCKET) { \
65 /* Sockets are non-blocking by default. Make them blocking. This
66 * introduces a bunch of caveats, see:
67 * http://www.sockets.com/winsock.htm#Overview_BlockingNonBlocking
70 set_blocking (SOCKET sk
)
74 if (ioctlsocket (sk
, FIONBIO
, &arg
) < 0) {
75 errno
= translate_winsock_error ("ioctlsocket", WSAGetLastError ());
82 win_accept (int fd
, struct sockaddr
*addr
, socklen_t
*len
)
85 GET_SOCKET_FROM_FD (fd
);
87 new_sk
= accept (sk
, addr
, len
);
88 if (new_sk
== INVALID_SOCKET
) {
89 errno
= translate_winsock_error ("accept", WSAGetLastError ());
92 if (set_blocking (new_sk
) == -1) return -1;
93 return _open_osfhandle ((intptr_t) new_sk
, O_RDWR
|O_BINARY
);
97 win_bind (int fd
, const struct sockaddr
*addr
, socklen_t len
)
99 GET_SOCKET_FROM_FD (fd
);
101 if (bind (sk
, addr
, len
) < 0) {
102 errno
= translate_winsock_error ("bind", WSAGetLastError ());
110 win_closesocket (int fd
)
112 GET_SOCKET_FROM_FD (fd
);
114 if (closesocket (sk
) < 0) {
115 errno
= translate_winsock_error ("closesocket", WSAGetLastError ());
123 win_getpeername (int fd
, struct sockaddr
*addr
, socklen_t
*len
)
125 GET_SOCKET_FROM_FD (fd
);
127 if (getpeername (sk
, addr
, len
) < 0) {
128 errno
= translate_winsock_error ("getpeername", WSAGetLastError ());
136 win_listen (int fd
, int backlog
)
138 GET_SOCKET_FROM_FD (fd
);
140 if (listen (sk
, backlog
) < 0) {
141 errno
= translate_winsock_error ("listen", WSAGetLastError ());
149 win_getsockopt (int fd
, int level
, int optname
,
150 void *optval
, socklen_t
*optlen
)
152 GET_SOCKET_FROM_FD (fd
);
154 if (getsockopt (sk
, level
, optname
, optval
, optlen
) < 0) {
155 errno
= translate_winsock_error ("getsockopt", WSAGetLastError ());
163 win_recv (int fd
, void *buf
, size_t len
, int flags
)
166 GET_SOCKET_FROM_FD (fd
);
168 r
= recv (sk
, buf
, len
, flags
);
170 errno
= translate_winsock_error ("recv", WSAGetLastError ());
178 win_setsockopt (int fd
, int level
, int optname
,
179 const void *optval
, socklen_t optlen
)
181 GET_SOCKET_FROM_FD (fd
);
183 if (setsockopt (sk
, level
, optname
, optval
, optlen
) < 0) {
184 errno
= translate_winsock_error ("setsockopt", WSAGetLastError ());
192 win_socket (int domain
, int type
, int protocol
)
196 sk
= WSASocket (domain
, type
, protocol
, NULL
, 0, 0);
197 if (sk
== INVALID_SOCKET
) {
198 errno
= translate_winsock_error ("socket", WSAGetLastError ());
202 if (set_blocking (sk
) == -1) return -1;
203 return _open_osfhandle ((intptr_t) sk
, O_RDWR
|O_BINARY
);
207 win_send (int fd
, const void *buf
, size_t len
, int flags
)
210 GET_SOCKET_FROM_FD (fd
);
212 r
= send (sk
, buf
, len
, flags
);
214 errno
= translate_winsock_error ("send", WSAGetLastError ());