/* * util.c (mostly based on QEMU os-win32.c) * * Copyright (c) 2003-2008 Fabrice Bellard * Copyright (c) 2010-2016 Red Hat, Inc. * * QEMU library functions for win32 which are shared between QEMU and * the QEMU tools. * * Permission is hereby granted, free of charge, to any person obtaining a copy * of this software and associated documentation files (the "Software"), to deal * in the Software without restriction, including without limitation the rights * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell * copies of the Software, and to permit persons to whom the Software is * furnished to do so, subject to the following conditions: * * The above copyright notice and this permission notice shall be included in * all copies or substantial portions of the Software. * * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN * THE SOFTWARE. */ #include "util.h" #include #include #include #if defined(_WIN32) && !defined(WITH_QEMU) int inet_aton(const char *cp, struct in_addr *ia) { uint32_t addr = inet_addr(cp); if (addr == 0xffffffff) { return 0; } ia->s_addr = addr; return 1; } #endif void slirp_set_nonblock(int fd) { #ifndef _WIN32 int f; f = fcntl(fd, F_GETFL); assert(f != -1); f = fcntl(fd, F_SETFL, f | O_NONBLOCK); assert(f != -1); #else unsigned long opt = 1; ioctlsocket(fd, FIONBIO, &opt); #endif } static void slirp_set_cloexec(int fd) { #ifndef _WIN32 int f; f = fcntl(fd, F_GETFD); assert(f != -1); f = fcntl(fd, F_SETFD, f | FD_CLOEXEC); assert(f != -1); #endif } /* * Opens a socket with FD_CLOEXEC set */ int slirp_socket(int domain, int type, int protocol) { int ret; #ifdef SOCK_CLOEXEC ret = socket(domain, type | SOCK_CLOEXEC, protocol); if (ret != -1 || errno != EINVAL) { return ret; } #endif ret = socket(domain, type, protocol); if (ret >= 0) { slirp_set_cloexec(ret); } return ret; } #ifdef _WIN32 static int socket_error(void) { switch (WSAGetLastError()) { case 0: return 0; case WSAEINTR: return EINTR; case WSAEINVAL: return EINVAL; case WSA_INVALID_HANDLE: return EBADF; case WSA_NOT_ENOUGH_MEMORY: return ENOMEM; case WSA_INVALID_PARAMETER: return EINVAL; case WSAENAMETOOLONG: return ENAMETOOLONG; case WSAENOTEMPTY: return ENOTEMPTY; case WSAEWOULDBLOCK: /* not using EWOULDBLOCK as we don't want code to have * to check both EWOULDBLOCK and EAGAIN */ return EAGAIN; case WSAEINPROGRESS: return EINPROGRESS; case WSAEALREADY: return EALREADY; case WSAENOTSOCK: return ENOTSOCK; case WSAEDESTADDRREQ: return EDESTADDRREQ; case WSAEMSGSIZE: return EMSGSIZE; case WSAEPROTOTYPE: return EPROTOTYPE; case WSAENOPROTOOPT: return ENOPROTOOPT; case WSAEPROTONOSUPPORT: return EPROTONOSUPPORT; case WSAEOPNOTSUPP: return EOPNOTSUPP; case WSAEAFNOSUPPORT: return EAFNOSUPPORT; case WSAEADDRINUSE: return EADDRINUSE; case WSAEADDRNOTAVAIL: return EADDRNOTAVAIL; case WSAENETDOWN: return ENETDOWN; case WSAENETUNREACH: return ENETUNREACH; case WSAENETRESET: return ENETRESET; case WSAECONNABORTED: return ECONNABORTED; case WSAECONNRESET: return ECONNRESET; case WSAENOBUFS: return ENOBUFS; case WSAEISCONN: return EISCONN; case WSAENOTCONN: return ENOTCONN; case WSAETIMEDOUT: return ETIMEDOUT; case WSAECONNREFUSED: return ECONNREFUSED; case WSAELOOP: return ELOOP; case WSAEHOSTUNREACH: return EHOSTUNREACH; default: return EIO; } } #undef ioctlsocket int slirp_ioctlsocket(int fd, int req, void *val) { int ret; ret = ioctlsocket(fd, req, val); if (ret < 0) { errno = socket_error(); } return ret; } #undef closesocket int slirp_closesocket(int fd) { int ret; ret = closesocket(fd); if (ret < 0) { errno = socket_error(); } return ret; } #endif /* WIN32 */