Update Red Hat Copyright Notices
[nbdkit.git] / common / utils / windows-compat.c
blob9b63f18c20a92e9cdbdd678c7bfe5a994932b114
1 /* nbdkit
2 * Copyright Red Hat
4 * Redistribution and use in source and binary forms, with or without
5 * modification, are permitted provided that the following conditions are
6 * met:
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
30 * SUCH DAMAGE.
33 #include <config.h>
35 #include <stdio.h>
37 #ifdef WIN32
39 #include <winsock2.h>
40 #include <ws2tcpip.h>
41 #include <windows.h>
42 #include <fcntl.h>
43 #include <errno.h>
45 #include "windows-compat.h"
47 #undef accept
48 #undef bind
49 #undef closesocket
50 #undef getpeername
51 #undef listen
52 #undef getsockopt
53 #undef recv
54 #undef setsockopt
55 #undef socket
56 #undef send
58 #define GET_SOCKET_FROM_FD(fd) \
59 SOCKET sk = _get_osfhandle (fd); \
60 if (sk == INVALID_SOCKET) { \
61 errno = EBADF; \
62 return -1; \
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
69 static int
70 set_blocking (SOCKET sk)
72 u_long arg = 0;
74 if (ioctlsocket (sk, FIONBIO, &arg) < 0) {
75 errno = translate_winsock_error ("ioctlsocket", WSAGetLastError ());
76 return -1;
78 return 0;
81 int
82 win_accept (int fd, struct sockaddr *addr, socklen_t *len)
84 SOCKET new_sk;
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 ());
90 return -1;
92 if (set_blocking (new_sk) == -1) return -1;
93 return _open_osfhandle ((intptr_t) new_sk, O_RDWR|O_BINARY);
96 int
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 ());
103 return -1;
106 return 0;
110 win_closesocket (int fd)
112 GET_SOCKET_FROM_FD (fd);
114 if (closesocket (sk) < 0) {
115 errno = translate_winsock_error ("closesocket", WSAGetLastError ());
116 return -1;
119 return 0;
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 ());
129 return -1;
132 return 0;
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 ());
142 return -1;
145 return 0;
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 ());
156 return -1;
159 return 0;
163 win_recv (int fd, void *buf, size_t len, int flags)
165 int r;
166 GET_SOCKET_FROM_FD (fd);
168 r = recv (sk, buf, len, flags);
169 if (r < 0) {
170 errno = translate_winsock_error ("recv", WSAGetLastError ());
171 return -1;
174 return r;
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 ());
185 return -1;
188 return 0;
192 win_socket (int domain, int type, int protocol)
194 SOCKET sk;
196 sk = WSASocket (domain, type, protocol, NULL, 0, 0);
197 if (sk == INVALID_SOCKET) {
198 errno = translate_winsock_error ("socket", WSAGetLastError ());
199 return -1;
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)
209 int r;
210 GET_SOCKET_FROM_FD (fd);
212 r = send (sk, buf, len, flags);
213 if (r < 0) {
214 errno = translate_winsock_error ("send", WSAGetLastError ());
215 return -1;
218 return r;
221 #endif /* WIN32 */