]> git.proxmox.com Git - mirror_qemu.git/blob - slirp/src/util.c
Merge remote-tracking branch 'remotes/bonzini/tags/for-upstream' into staging
[mirror_qemu.git] / slirp / src / util.c
1 /*
2 * util.c (mostly based on QEMU os-win32.c)
3 *
4 * Copyright (c) 2003-2008 Fabrice Bellard
5 * Copyright (c) 2010-2016 Red Hat, Inc.
6 *
7 * QEMU library functions for win32 which are shared between QEMU and
8 * the QEMU tools.
9 *
10 * Permission is hereby granted, free of charge, to any person obtaining a copy
11 * of this software and associated documentation files (the "Software"), to deal
12 * in the Software without restriction, including without limitation the rights
13 * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
14 * copies of the Software, and to permit persons to whom the Software is
15 * furnished to do so, subject to the following conditions:
16 *
17 * The above copyright notice and this permission notice shall be included in
18 * all copies or substantial portions of the Software.
19 *
20 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
21 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
22 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
23 * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
24 * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
25 * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
26 * THE SOFTWARE.
27 */
28 #include "util.h"
29
30 #include <glib.h>
31 #include <fcntl.h>
32 #include <stdint.h>
33
34 #if defined(_WIN32)
35 int slirp_inet_aton(const char *cp, struct in_addr *ia)
36 {
37 uint32_t addr = inet_addr(cp);
38 if (addr == 0xffffffff) {
39 return 0;
40 }
41 ia->s_addr = addr;
42 return 1;
43 }
44 #endif
45
46 void slirp_set_nonblock(int fd)
47 {
48 #ifndef _WIN32
49 int f;
50 f = fcntl(fd, F_GETFL);
51 assert(f != -1);
52 f = fcntl(fd, F_SETFL, f | O_NONBLOCK);
53 assert(f != -1);
54 #else
55 unsigned long opt = 1;
56 ioctlsocket(fd, FIONBIO, &opt);
57 #endif
58 }
59
60 static void slirp_set_cloexec(int fd)
61 {
62 #ifndef _WIN32
63 int f;
64 f = fcntl(fd, F_GETFD);
65 assert(f != -1);
66 f = fcntl(fd, F_SETFD, f | FD_CLOEXEC);
67 assert(f != -1);
68 #endif
69 }
70
71 /*
72 * Opens a socket with FD_CLOEXEC set
73 */
74 int slirp_socket(int domain, int type, int protocol)
75 {
76 int ret;
77
78 #ifdef SOCK_CLOEXEC
79 ret = socket(domain, type | SOCK_CLOEXEC, protocol);
80 if (ret != -1 || errno != EINVAL) {
81 return ret;
82 }
83 #endif
84 ret = socket(domain, type, protocol);
85 if (ret >= 0) {
86 slirp_set_cloexec(ret);
87 }
88
89 return ret;
90 }
91
92 #ifdef _WIN32
93 static int socket_error(void)
94 {
95 switch (WSAGetLastError()) {
96 case 0:
97 return 0;
98 case WSAEINTR:
99 return EINTR;
100 case WSAEINVAL:
101 return EINVAL;
102 case WSA_INVALID_HANDLE:
103 return EBADF;
104 case WSA_NOT_ENOUGH_MEMORY:
105 return ENOMEM;
106 case WSA_INVALID_PARAMETER:
107 return EINVAL;
108 case WSAENAMETOOLONG:
109 return ENAMETOOLONG;
110 case WSAENOTEMPTY:
111 return ENOTEMPTY;
112 case WSAEWOULDBLOCK:
113 /* not using EWOULDBLOCK as we don't want code to have
114 * to check both EWOULDBLOCK and EAGAIN */
115 return EAGAIN;
116 case WSAEINPROGRESS:
117 return EINPROGRESS;
118 case WSAEALREADY:
119 return EALREADY;
120 case WSAENOTSOCK:
121 return ENOTSOCK;
122 case WSAEDESTADDRREQ:
123 return EDESTADDRREQ;
124 case WSAEMSGSIZE:
125 return EMSGSIZE;
126 case WSAEPROTOTYPE:
127 return EPROTOTYPE;
128 case WSAENOPROTOOPT:
129 return ENOPROTOOPT;
130 case WSAEPROTONOSUPPORT:
131 return EPROTONOSUPPORT;
132 case WSAEOPNOTSUPP:
133 return EOPNOTSUPP;
134 case WSAEAFNOSUPPORT:
135 return EAFNOSUPPORT;
136 case WSAEADDRINUSE:
137 return EADDRINUSE;
138 case WSAEADDRNOTAVAIL:
139 return EADDRNOTAVAIL;
140 case WSAENETDOWN:
141 return ENETDOWN;
142 case WSAENETUNREACH:
143 return ENETUNREACH;
144 case WSAENETRESET:
145 return ENETRESET;
146 case WSAECONNABORTED:
147 return ECONNABORTED;
148 case WSAECONNRESET:
149 return ECONNRESET;
150 case WSAENOBUFS:
151 return ENOBUFS;
152 case WSAEISCONN:
153 return EISCONN;
154 case WSAENOTCONN:
155 return ENOTCONN;
156 case WSAETIMEDOUT:
157 return ETIMEDOUT;
158 case WSAECONNREFUSED:
159 return ECONNREFUSED;
160 case WSAELOOP:
161 return ELOOP;
162 case WSAEHOSTUNREACH:
163 return EHOSTUNREACH;
164 default:
165 return EIO;
166 }
167 }
168
169 #undef ioctlsocket
170 int slirp_ioctlsocket_wrap(int fd, int req, void *val)
171 {
172 int ret;
173 ret = ioctlsocket(fd, req, val);
174 if (ret < 0) {
175 errno = socket_error();
176 }
177 return ret;
178 }
179
180 #undef closesocket
181 int slirp_closesocket_wrap(int fd)
182 {
183 int ret;
184 ret = closesocket(fd);
185 if (ret < 0) {
186 errno = socket_error();
187 }
188 return ret;
189 }
190
191 #undef connect
192 int slirp_connect_wrap(int sockfd, const struct sockaddr *addr, int addrlen)
193 {
194 int ret;
195 ret = connect(sockfd, addr, addrlen);
196 if (ret < 0) {
197 errno = socket_error();
198 }
199 return ret;
200 }
201
202 #undef listen
203 int slirp_listen_wrap(int sockfd, int backlog)
204 {
205 int ret;
206 ret = listen(sockfd, backlog);
207 if (ret < 0) {
208 errno = socket_error();
209 }
210 return ret;
211 }
212
213 #undef bind
214 int slirp_bind_wrap(int sockfd, const struct sockaddr *addr, int addrlen)
215 {
216 int ret;
217 ret = bind(sockfd, addr, addrlen);
218 if (ret < 0) {
219 errno = socket_error();
220 }
221 return ret;
222 }
223
224 #undef socket
225 int slirp_socket_wrap(int domain, int type, int protocol)
226 {
227 int ret;
228 ret = socket(domain, type, protocol);
229 if (ret < 0) {
230 errno = socket_error();
231 }
232 return ret;
233 }
234
235 #undef accept
236 int slirp_accept_wrap(int sockfd, struct sockaddr *addr, int *addrlen)
237 {
238 int ret;
239 ret = accept(sockfd, addr, addrlen);
240 if (ret < 0) {
241 errno = socket_error();
242 }
243 return ret;
244 }
245
246 #undef shutdown
247 int slirp_shutdown_wrap(int sockfd, int how)
248 {
249 int ret;
250 ret = shutdown(sockfd, how);
251 if (ret < 0) {
252 errno = socket_error();
253 }
254 return ret;
255 }
256
257 #undef getsockopt
258 int slirp_getsockopt_wrap(int sockfd, int level, int optname,
259 void *optval, int *optlen)
260 {
261 int ret;
262 ret = getsockopt(sockfd, level, optname, optval, optlen);
263 if (ret < 0) {
264 errno = socket_error();
265 }
266 return ret;
267 }
268
269 #undef setsockopt
270 int slirp_setsockopt_wrap(int sockfd, int level, int optname,
271 const void *optval, int optlen)
272 {
273 int ret;
274 ret = setsockopt(sockfd, level, optname, optval, optlen);
275 if (ret < 0) {
276 errno = socket_error();
277 }
278 return ret;
279 }
280
281 #undef getpeername
282 int slirp_getpeername_wrap(int sockfd, struct sockaddr *addr,
283 int *addrlen)
284 {
285 int ret;
286 ret = getpeername(sockfd, addr, addrlen);
287 if (ret < 0) {
288 errno = socket_error();
289 }
290 return ret;
291 }
292
293 #undef getsockname
294 int slirp_getsockname_wrap(int sockfd, struct sockaddr *addr,
295 int *addrlen)
296 {
297 int ret;
298 ret = getsockname(sockfd, addr, addrlen);
299 if (ret < 0) {
300 errno = socket_error();
301 }
302 return ret;
303 }
304
305 #undef send
306 ssize_t slirp_send_wrap(int sockfd, const void *buf, size_t len, int flags)
307 {
308 int ret;
309 ret = send(sockfd, buf, len, flags);
310 if (ret < 0) {
311 errno = socket_error();
312 }
313 return ret;
314 }
315
316 #undef sendto
317 ssize_t slirp_sendto_wrap(int sockfd, const void *buf, size_t len, int flags,
318 const struct sockaddr *addr, int addrlen)
319 {
320 int ret;
321 ret = sendto(sockfd, buf, len, flags, addr, addrlen);
322 if (ret < 0) {
323 errno = socket_error();
324 }
325 return ret;
326 }
327
328 #undef recv
329 ssize_t slirp_recv_wrap(int sockfd, void *buf, size_t len, int flags)
330 {
331 int ret;
332 ret = recv(sockfd, buf, len, flags);
333 if (ret < 0) {
334 errno = socket_error();
335 }
336 return ret;
337 }
338
339 #undef recvfrom
340 ssize_t slirp_recvfrom_wrap(int sockfd, void *buf, size_t len, int flags,
341 struct sockaddr *addr, int *addrlen)
342 {
343 int ret;
344 ret = recvfrom(sockfd, buf, len, flags, addr, addrlen);
345 if (ret < 0) {
346 errno = socket_error();
347 }
348 return ret;
349 }
350 #endif /* WIN32 */
351
352 void slirp_pstrcpy(char *buf, int buf_size, const char *str)
353 {
354 int c;
355 char *q = buf;
356
357 if (buf_size <= 0)
358 return;
359
360 for(;;) {
361 c = *str++;
362 if (c == 0 || q >= buf + buf_size - 1)
363 break;
364 *q++ = c;
365 }
366 *q = '\0';
367 }