]> git.proxmox.com Git - mirror_qemu.git/blame - slirp/src/util.c
Merge remote-tracking branch 'remotes/bonzini/tags/for-upstream' into staging
[mirror_qemu.git] / slirp / src / util.c
CommitLineData
707bd47e
MAL
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
5a4af0d4
MAL
34#if defined(_WIN32)
35int slirp_inet_aton(const char *cp, struct in_addr *ia)
707bd47e
MAL
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
848c7092
MAL
46void 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
707bd47e
MAL
60static 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 */
74int 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
93static 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
adf1add2 170int slirp_ioctlsocket_wrap(int fd, int req, void *val)
707bd47e
MAL
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
adf1add2 181int slirp_closesocket_wrap(int fd)
707bd47e
MAL
182{
183 int ret;
184 ret = closesocket(fd);
185 if (ret < 0) {
186 errno = socket_error();
187 }
188 return ret;
189}
adf1add2
MAL
190
191#undef connect
192int 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
203int 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
214int 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
225int 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
236int 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
247int 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
258int 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
270int 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
282int 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
294int 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
306ssize_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
317ssize_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
329ssize_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
340ssize_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}
707bd47e 350#endif /* WIN32 */
d1c4b3e9
MAL
351
352void 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}