xref: /openbmc/qemu/util/oslib-win32.c (revision 8ab67b6ebc721041b22aa0e60f5422166dada234)
1baacf047SPaolo Bonzini /*
2baacf047SPaolo Bonzini  * os-win32.c
3baacf047SPaolo Bonzini  *
4baacf047SPaolo Bonzini  * Copyright (c) 2003-2008 Fabrice Bellard
5c6196440SDaniel P. Berrange  * Copyright (c) 2010-2016 Red Hat, Inc.
6baacf047SPaolo Bonzini  *
7baacf047SPaolo Bonzini  * QEMU library functions for win32 which are shared between QEMU and
8baacf047SPaolo Bonzini  * the QEMU tools.
9baacf047SPaolo Bonzini  *
10baacf047SPaolo Bonzini  * Permission is hereby granted, free of charge, to any person obtaining a copy
11baacf047SPaolo Bonzini  * of this software and associated documentation files (the "Software"), to deal
12baacf047SPaolo Bonzini  * in the Software without restriction, including without limitation the rights
13baacf047SPaolo Bonzini  * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
14baacf047SPaolo Bonzini  * copies of the Software, and to permit persons to whom the Software is
15baacf047SPaolo Bonzini  * furnished to do so, subject to the following conditions:
16baacf047SPaolo Bonzini  *
17baacf047SPaolo Bonzini  * The above copyright notice and this permission notice shall be included in
18baacf047SPaolo Bonzini  * all copies or substantial portions of the Software.
19baacf047SPaolo Bonzini  *
20baacf047SPaolo Bonzini  * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
21baacf047SPaolo Bonzini  * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
22baacf047SPaolo Bonzini  * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
23baacf047SPaolo Bonzini  * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
24baacf047SPaolo Bonzini  * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
25baacf047SPaolo Bonzini  * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
26baacf047SPaolo Bonzini  * THE SOFTWARE.
27baacf047SPaolo Bonzini  */
28a8d25326SMarkus Armbruster 
29aafd7584SPeter Maydell #include "qemu/osdep.h"
30baacf047SPaolo Bonzini #include <windows.h>
31da34e65cSMarkus Armbruster #include "qapi/error.h"
32baacf047SPaolo Bonzini #include "qemu/main-loop.h"
33baacf047SPaolo Bonzini #include "trace.h"
34baacf047SPaolo Bonzini #include "qemu/sockets.h"
35f348b6d1SVeronia Bahaa #include "qemu/cutils.h"
368dbe22c6SDavid Hildenbrand #include "qemu/error-report.h"
37dfbd0b87SRichard Henderson #include <malloc.h>
38baacf047SPaolo Bonzini 
get_allocation_granularity(void)39714efd54SDavid Hildenbrand static int get_allocation_granularity(void)
40714efd54SDavid Hildenbrand {
41714efd54SDavid Hildenbrand     SYSTEM_INFO system_info;
42714efd54SDavid Hildenbrand 
43714efd54SDavid Hildenbrand     GetSystemInfo(&system_info);
44714efd54SDavid Hildenbrand     return system_info.dwAllocationGranularity;
45714efd54SDavid Hildenbrand }
46714efd54SDavid Hildenbrand 
qemu_anon_ram_alloc(size_t size,uint64_t * align,bool shared,bool noreserve)478dbe22c6SDavid Hildenbrand void *qemu_anon_ram_alloc(size_t size, uint64_t *align, bool shared,
488dbe22c6SDavid Hildenbrand                           bool noreserve)
49baacf047SPaolo Bonzini {
50baacf047SPaolo Bonzini     void *ptr;
51baacf047SPaolo Bonzini 
528dbe22c6SDavid Hildenbrand     if (noreserve) {
538dbe22c6SDavid Hildenbrand         /*
548dbe22c6SDavid Hildenbrand          * We need a MEM_COMMIT before accessing any memory in a MEM_RESERVE
558dbe22c6SDavid Hildenbrand          * area; we cannot easily mimic POSIX MAP_NORESERVE semantics.
568dbe22c6SDavid Hildenbrand          */
578dbe22c6SDavid Hildenbrand         error_report("Skipping reservation of swap space is not supported.");
588dbe22c6SDavid Hildenbrand         return NULL;
598dbe22c6SDavid Hildenbrand     }
608dbe22c6SDavid Hildenbrand 
6139228250SMarkus Armbruster     ptr = VirtualAlloc(NULL, size, MEM_COMMIT, PAGE_READWRITE);
626eebf958SPaolo Bonzini     trace_qemu_anon_ram_alloc(size, ptr);
63714efd54SDavid Hildenbrand 
64714efd54SDavid Hildenbrand     if (ptr && align) {
65714efd54SDavid Hildenbrand         *align = MAX(get_allocation_granularity(), getpagesize());
66714efd54SDavid Hildenbrand     }
67baacf047SPaolo Bonzini     return ptr;
68baacf047SPaolo Bonzini }
69baacf047SPaolo Bonzini 
qemu_anon_ram_free(void * ptr,size_t size)70e7a09b92SPaolo Bonzini void qemu_anon_ram_free(void *ptr, size_t size)
71e7a09b92SPaolo Bonzini {
72e7a09b92SPaolo Bonzini     trace_qemu_anon_ram_free(ptr, size);
73e7a09b92SPaolo Bonzini     if (ptr) {
74e7a09b92SPaolo Bonzini         VirtualFree(ptr, 0, MEM_RELEASE);
75e7a09b92SPaolo Bonzini     }
76e7a09b92SPaolo Bonzini }
77e7a09b92SPaolo Bonzini 
787c3afc85SYonggang Luo #ifndef _POSIX_THREAD_SAFE_FUNCTIONS
79baacf047SPaolo Bonzini /* FIXME: add proper locking */
gmtime_r(const time_t * timep,struct tm * result)80baacf047SPaolo Bonzini struct tm *gmtime_r(const time_t *timep, struct tm *result)
81baacf047SPaolo Bonzini {
82baacf047SPaolo Bonzini     struct tm *p = gmtime(timep);
83baacf047SPaolo Bonzini     memset(result, 0, sizeof(*result));
84baacf047SPaolo Bonzini     if (p) {
85baacf047SPaolo Bonzini         *result = *p;
86baacf047SPaolo Bonzini         p = result;
87baacf047SPaolo Bonzini     }
88baacf047SPaolo Bonzini     return p;
89baacf047SPaolo Bonzini }
90baacf047SPaolo Bonzini 
91baacf047SPaolo Bonzini /* FIXME: add proper locking */
localtime_r(const time_t * timep,struct tm * result)92baacf047SPaolo Bonzini struct tm *localtime_r(const time_t *timep, struct tm *result)
93baacf047SPaolo Bonzini {
94baacf047SPaolo Bonzini     struct tm *p = localtime(timep);
95baacf047SPaolo Bonzini     memset(result, 0, sizeof(*result));
96baacf047SPaolo Bonzini     if (p) {
97baacf047SPaolo Bonzini         *result = *p;
98baacf047SPaolo Bonzini         p = result;
99baacf047SPaolo Bonzini     }
100baacf047SPaolo Bonzini     return p;
101baacf047SPaolo Bonzini }
1027c3afc85SYonggang Luo #endif /* _POSIX_THREAD_SAFE_FUNCTIONS */
103baacf047SPaolo Bonzini 
socket_error(void)104b16a44e1SDaniel P. Berrange static int socket_error(void)
105c6196440SDaniel P. Berrange {
106c6196440SDaniel P. Berrange     switch (WSAGetLastError()) {
107c6196440SDaniel P. Berrange     case 0:
108c6196440SDaniel P. Berrange         return 0;
109c6196440SDaniel P. Berrange     case WSAEINTR:
110c6196440SDaniel P. Berrange         return EINTR;
111c6196440SDaniel P. Berrange     case WSAEINVAL:
112c6196440SDaniel P. Berrange         return EINVAL;
113c6196440SDaniel P. Berrange     case WSA_INVALID_HANDLE:
114c6196440SDaniel P. Berrange         return EBADF;
115c6196440SDaniel P. Berrange     case WSA_NOT_ENOUGH_MEMORY:
116c6196440SDaniel P. Berrange         return ENOMEM;
117c6196440SDaniel P. Berrange     case WSA_INVALID_PARAMETER:
118c6196440SDaniel P. Berrange         return EINVAL;
119c6196440SDaniel P. Berrange     case WSAENAMETOOLONG:
120c6196440SDaniel P. Berrange         return ENAMETOOLONG;
121c6196440SDaniel P. Berrange     case WSAENOTEMPTY:
122c6196440SDaniel P. Berrange         return ENOTEMPTY;
123c6196440SDaniel P. Berrange     case WSAEWOULDBLOCK:
124c6196440SDaniel P. Berrange          /* not using EWOULDBLOCK as we don't want code to have
125c6196440SDaniel P. Berrange           * to check both EWOULDBLOCK and EAGAIN */
126c6196440SDaniel P. Berrange         return EAGAIN;
127c6196440SDaniel P. Berrange     case WSAEINPROGRESS:
128c6196440SDaniel P. Berrange         return EINPROGRESS;
129c6196440SDaniel P. Berrange     case WSAEALREADY:
130c6196440SDaniel P. Berrange         return EALREADY;
131c6196440SDaniel P. Berrange     case WSAENOTSOCK:
132c6196440SDaniel P. Berrange         return ENOTSOCK;
133c6196440SDaniel P. Berrange     case WSAEDESTADDRREQ:
134c6196440SDaniel P. Berrange         return EDESTADDRREQ;
135c6196440SDaniel P. Berrange     case WSAEMSGSIZE:
136c6196440SDaniel P. Berrange         return EMSGSIZE;
137c6196440SDaniel P. Berrange     case WSAEPROTOTYPE:
138c6196440SDaniel P. Berrange         return EPROTOTYPE;
139c6196440SDaniel P. Berrange     case WSAENOPROTOOPT:
140c6196440SDaniel P. Berrange         return ENOPROTOOPT;
141c6196440SDaniel P. Berrange     case WSAEPROTONOSUPPORT:
142c6196440SDaniel P. Berrange         return EPROTONOSUPPORT;
143c6196440SDaniel P. Berrange     case WSAEOPNOTSUPP:
144c6196440SDaniel P. Berrange         return EOPNOTSUPP;
145c6196440SDaniel P. Berrange     case WSAEAFNOSUPPORT:
146c6196440SDaniel P. Berrange         return EAFNOSUPPORT;
147c6196440SDaniel P. Berrange     case WSAEADDRINUSE:
148c6196440SDaniel P. Berrange         return EADDRINUSE;
149c6196440SDaniel P. Berrange     case WSAEADDRNOTAVAIL:
150c6196440SDaniel P. Berrange         return EADDRNOTAVAIL;
151c6196440SDaniel P. Berrange     case WSAENETDOWN:
152c6196440SDaniel P. Berrange         return ENETDOWN;
153c6196440SDaniel P. Berrange     case WSAENETUNREACH:
154c6196440SDaniel P. Berrange         return ENETUNREACH;
155c6196440SDaniel P. Berrange     case WSAENETRESET:
156c6196440SDaniel P. Berrange         return ENETRESET;
157c6196440SDaniel P. Berrange     case WSAECONNABORTED:
158c6196440SDaniel P. Berrange         return ECONNABORTED;
159c6196440SDaniel P. Berrange     case WSAECONNRESET:
160c6196440SDaniel P. Berrange         return ECONNRESET;
161c6196440SDaniel P. Berrange     case WSAENOBUFS:
162c6196440SDaniel P. Berrange         return ENOBUFS;
163c6196440SDaniel P. Berrange     case WSAEISCONN:
164c6196440SDaniel P. Berrange         return EISCONN;
165c6196440SDaniel P. Berrange     case WSAENOTCONN:
166c6196440SDaniel P. Berrange         return ENOTCONN;
167c6196440SDaniel P. Berrange     case WSAETIMEDOUT:
168c6196440SDaniel P. Berrange         return ETIMEDOUT;
169c6196440SDaniel P. Berrange     case WSAECONNREFUSED:
170c6196440SDaniel P. Berrange         return ECONNREFUSED;
171c6196440SDaniel P. Berrange     case WSAELOOP:
172c6196440SDaniel P. Berrange         return ELOOP;
173c6196440SDaniel P. Berrange     case WSAEHOSTUNREACH:
174c6196440SDaniel P. Berrange         return EHOSTUNREACH;
175c6196440SDaniel P. Berrange     default:
176c6196440SDaniel P. Berrange         return EIO;
177c6196440SDaniel P. Berrange     }
178c6196440SDaniel P. Berrange }
179c6196440SDaniel P. Berrange 
qemu_socket_set_block(int fd)180ff5927baSMarc-André Lureau void qemu_socket_set_block(int fd)
181894022e6SLaurent Vivier {
182894022e6SLaurent Vivier     unsigned long opt = 0;
183a4aafea2SMarc-André Lureau     qemu_socket_unselect(fd, NULL);
184894022e6SLaurent Vivier     ioctlsocket(fd, FIONBIO, &opt);
185894022e6SLaurent Vivier }
186894022e6SLaurent Vivier 
qemu_socket_try_set_nonblock(int fd)187ff5927baSMarc-André Lureau int qemu_socket_try_set_nonblock(int fd)
188894022e6SLaurent Vivier {
189894022e6SLaurent Vivier     unsigned long opt = 1;
190894022e6SLaurent Vivier     if (ioctlsocket(fd, FIONBIO, &opt) != NO_ERROR) {
191894022e6SLaurent Vivier         return -socket_error();
192894022e6SLaurent Vivier     }
193894022e6SLaurent Vivier     return 0;
194894022e6SLaurent Vivier }
195894022e6SLaurent Vivier 
qemu_socket_set_nonblock(int fd)196ff5927baSMarc-André Lureau void qemu_socket_set_nonblock(int fd)
197894022e6SLaurent Vivier {
198ff5927baSMarc-André Lureau     (void)qemu_socket_try_set_nonblock(fd);
199894022e6SLaurent Vivier }
200894022e6SLaurent Vivier 
socket_set_fast_reuse(int fd)201894022e6SLaurent Vivier int socket_set_fast_reuse(int fd)
202894022e6SLaurent Vivier {
203894022e6SLaurent Vivier     /* Enabling the reuse of an endpoint that was used by a socket still in
204894022e6SLaurent Vivier      * TIME_WAIT state is usually performed by setting SO_REUSEADDR. On Windows
205894022e6SLaurent Vivier      * fast reuse is the default and SO_REUSEADDR does strange things. So we
206894022e6SLaurent Vivier      * don't have to do anything here. More info can be found at:
207894022e6SLaurent Vivier      * http://msdn.microsoft.com/en-us/library/windows/desktop/ms740621.aspx */
208894022e6SLaurent Vivier     return 0;
209894022e6SLaurent Vivier }
210894022e6SLaurent Vivier 
inet_aton(const char * cp,struct in_addr * ia)211baacf047SPaolo Bonzini int inet_aton(const char *cp, struct in_addr *ia)
212baacf047SPaolo Bonzini {
213baacf047SPaolo Bonzini     uint32_t addr = inet_addr(cp);
214baacf047SPaolo Bonzini     if (addr == 0xffffffff) {
215baacf047SPaolo Bonzini         return 0;
216baacf047SPaolo Bonzini     }
217baacf047SPaolo Bonzini     ia->s_addr = addr;
218baacf047SPaolo Bonzini     return 1;
219baacf047SPaolo Bonzini }
220baacf047SPaolo Bonzini 
qemu_set_cloexec(int fd)221baacf047SPaolo Bonzini void qemu_set_cloexec(int fd)
222baacf047SPaolo Bonzini {
223baacf047SPaolo Bonzini }
224baacf047SPaolo Bonzini 
qemu_get_thread_id(void)225baacf047SPaolo Bonzini int qemu_get_thread_id(void)
226baacf047SPaolo Bonzini {
227baacf047SPaolo Bonzini     return GetCurrentThreadId();
228baacf047SPaolo Bonzini }
229e2ea3515SLaszlo Ersek 
230e2ea3515SLaszlo Ersek char *
qemu_get_local_state_dir(void)2311fbf2665SMarc-André Lureau qemu_get_local_state_dir(void)
232e2ea3515SLaszlo Ersek {
23349e0128cSMarc-André Lureau     const char * const *data_dirs = g_get_system_data_dirs();
234e2ea3515SLaszlo Ersek 
23549e0128cSMarc-André Lureau     g_assert(data_dirs && data_dirs[0]);
23649e0128cSMarc-André Lureau 
23749e0128cSMarc-André Lureau     return g_strdup(data_dirs[0]);
238e2ea3515SLaszlo Ersek }
23913401ba0SStefan Hajnoczi 
qemu_set_tty_echo(int fd,bool echo)24013401ba0SStefan Hajnoczi void qemu_set_tty_echo(int fd, bool echo)
24113401ba0SStefan Hajnoczi {
24213401ba0SStefan Hajnoczi     HANDLE handle = (HANDLE)_get_osfhandle(fd);
24313401ba0SStefan Hajnoczi     DWORD dwMode = 0;
24413401ba0SStefan Hajnoczi 
24513401ba0SStefan Hajnoczi     if (handle == INVALID_HANDLE_VALUE) {
24613401ba0SStefan Hajnoczi         return;
24713401ba0SStefan Hajnoczi     }
24813401ba0SStefan Hajnoczi 
24913401ba0SStefan Hajnoczi     GetConsoleMode(handle, &dwMode);
25013401ba0SStefan Hajnoczi 
25113401ba0SStefan Hajnoczi     if (echo) {
25213401ba0SStefan Hajnoczi         SetConsoleMode(handle, dwMode | ENABLE_ECHO_INPUT | ENABLE_LINE_INPUT);
25313401ba0SStefan Hajnoczi     } else {
25413401ba0SStefan Hajnoczi         SetConsoleMode(handle,
25513401ba0SStefan Hajnoczi                        dwMode & ~(ENABLE_ECHO_INPUT | ENABLE_LINE_INPUT));
25613401ba0SStefan Hajnoczi     }
25713401ba0SStefan Hajnoczi }
25810f5bff6SFam Zheng 
getpagesize(void)259a28c2f2dSStefan Weil int getpagesize(void)
26038183310SPaolo Bonzini {
26138183310SPaolo Bonzini     SYSTEM_INFO system_info;
26238183310SPaolo Bonzini 
26338183310SPaolo Bonzini     GetSystemInfo(&system_info);
26438183310SPaolo Bonzini     return system_info.dwPageSize;
26538183310SPaolo Bonzini }
26638183310SPaolo Bonzini 
qemu_prealloc_mem(int fd,char * area,size_t sz,int max_threads,ThreadContext * tc,bool async,Error ** errp)267b622ee98SPhilippe Mathieu-Daudé bool qemu_prealloc_mem(int fd, char *area, size_t sz, int max_threads,
268*04accf43SMark Kanda                        ThreadContext *tc, bool async, Error **errp)
26938183310SPaolo Bonzini {
27038183310SPaolo Bonzini     int i;
2718e3b0cbbSMarc-André Lureau     size_t pagesize = qemu_real_host_page_size();
27238183310SPaolo Bonzini 
2736556aadcSDavid Hildenbrand     sz = (sz + pagesize - 1) & -pagesize;
2746556aadcSDavid Hildenbrand     for (i = 0; i < sz / pagesize; i++) {
27538183310SPaolo Bonzini         memset(area + pagesize * i, 0, 1);
27638183310SPaolo Bonzini     }
277b622ee98SPhilippe Mathieu-Daudé 
278b622ee98SPhilippe Mathieu-Daudé     return true;
27938183310SPaolo Bonzini }
280d57e4e48SDaniel P. Berrange 
qemu_finish_async_prealloc_mem(Error ** errp)281*04accf43SMark Kanda bool qemu_finish_async_prealloc_mem(Error **errp)
282*04accf43SMark Kanda {
283*04accf43SMark Kanda     /* async prealloc not supported, there is nothing to finish */
284*04accf43SMark Kanda     return true;
285*04accf43SMark Kanda }
286*04accf43SMark Kanda 
qemu_get_pid_name(pid_t pid)2877dc9ae43SMichal Privoznik char *qemu_get_pid_name(pid_t pid)
2887dc9ae43SMichal Privoznik {
2897dc9ae43SMichal Privoznik     /* XXX Implement me */
2907dc9ae43SMichal Privoznik     abort();
2917dc9ae43SMichal Privoznik }
2927dc9ae43SMichal Privoznik 
2937dc9ae43SMichal Privoznik 
qemu_socket_select(int sockfd,WSAEVENT hEventObject,long lNetworkEvents,Error ** errp)294abe34282SMarc-André Lureau bool qemu_socket_select(int sockfd, WSAEVENT hEventObject,
295f5fd677aSMarc-André Lureau                         long lNetworkEvents, Error **errp)
296f5fd677aSMarc-André Lureau {
297abe34282SMarc-André Lureau     SOCKET s = _get_osfhandle(sockfd);
298abe34282SMarc-André Lureau 
299f5fd677aSMarc-André Lureau     if (errp == NULL) {
300f5fd677aSMarc-André Lureau         errp = &error_warn;
301f5fd677aSMarc-André Lureau     }
302f5fd677aSMarc-André Lureau 
303abe34282SMarc-André Lureau     if (s == INVALID_SOCKET) {
304abe34282SMarc-André Lureau         error_setg(errp, "invalid socket fd=%d", sockfd);
305abe34282SMarc-André Lureau         return false;
306abe34282SMarc-André Lureau     }
307abe34282SMarc-André Lureau 
308f5fd677aSMarc-André Lureau     if (WSAEventSelect(s, hEventObject, lNetworkEvents) != 0) {
309f5fd677aSMarc-André Lureau         error_setg_win32(errp, WSAGetLastError(), "failed to WSAEventSelect()");
310f5fd677aSMarc-André Lureau         return false;
311f5fd677aSMarc-André Lureau     }
312f5fd677aSMarc-André Lureau 
313f5fd677aSMarc-André Lureau     return true;
314f5fd677aSMarc-André Lureau }
315f5fd677aSMarc-André Lureau 
qemu_socket_unselect(int sockfd,Error ** errp)316abe34282SMarc-André Lureau bool qemu_socket_unselect(int sockfd, Error **errp)
317a4aafea2SMarc-André Lureau {
318abe34282SMarc-André Lureau     return qemu_socket_select(sockfd, NULL, 0, errp);
319a4aafea2SMarc-André Lureau }
320a4aafea2SMarc-André Lureau 
qemu_socketpair(int domain,int type,int protocol,int sv[2])3210a237f4dSMarc-André Lureau int qemu_socketpair(int domain, int type, int protocol, int sv[2])
3220a237f4dSMarc-André Lureau {
3230a237f4dSMarc-André Lureau     struct sockaddr_un addr = {
3240a237f4dSMarc-André Lureau         0,
3250a237f4dSMarc-André Lureau     };
3260a237f4dSMarc-André Lureau     socklen_t socklen;
3270a237f4dSMarc-André Lureau     int listener = -1;
3280a237f4dSMarc-André Lureau     int client = -1;
3290a237f4dSMarc-André Lureau     int server = -1;
3300a237f4dSMarc-André Lureau     g_autofree char *path = NULL;
3310a237f4dSMarc-André Lureau     int tmpfd;
3320a237f4dSMarc-André Lureau     u_long arg;
3330a237f4dSMarc-André Lureau     int ret = -1;
3340a237f4dSMarc-André Lureau 
3350a237f4dSMarc-André Lureau     g_return_val_if_fail(sv != NULL, -1);
3360a237f4dSMarc-André Lureau 
3370a237f4dSMarc-André Lureau     addr.sun_family = AF_UNIX;
3380a237f4dSMarc-André Lureau     socklen = sizeof(addr);
3390a237f4dSMarc-André Lureau 
3400a237f4dSMarc-André Lureau     tmpfd = g_file_open_tmp(NULL, &path, NULL);
3410a237f4dSMarc-André Lureau     if (tmpfd == -1 || !path) {
3420a237f4dSMarc-André Lureau         errno = EACCES;
3430a237f4dSMarc-André Lureau         goto out;
3440a237f4dSMarc-André Lureau     }
3450a237f4dSMarc-André Lureau 
3460a237f4dSMarc-André Lureau     close(tmpfd);
3470a237f4dSMarc-André Lureau 
3480a237f4dSMarc-André Lureau     if (strlen(path) >= sizeof(addr.sun_path)) {
3490a237f4dSMarc-André Lureau         errno = EINVAL;
3500a237f4dSMarc-André Lureau         goto out;
3510a237f4dSMarc-André Lureau     }
3520a237f4dSMarc-André Lureau 
3530a237f4dSMarc-André Lureau     strncpy(addr.sun_path, path, sizeof(addr.sun_path) - 1);
3540a237f4dSMarc-André Lureau 
3550a237f4dSMarc-André Lureau     listener = socket(domain, type, protocol);
3560a237f4dSMarc-André Lureau     if (listener == -1) {
3570a237f4dSMarc-André Lureau         goto out;
3580a237f4dSMarc-André Lureau     }
3590a237f4dSMarc-André Lureau 
3600a237f4dSMarc-André Lureau     if (DeleteFile(path) == 0 && GetLastError() != ERROR_FILE_NOT_FOUND) {
3610a237f4dSMarc-André Lureau         errno = EACCES;
3620a237f4dSMarc-André Lureau         goto out;
3630a237f4dSMarc-André Lureau     }
3640a237f4dSMarc-André Lureau     g_clear_pointer(&path, g_free);
3650a237f4dSMarc-André Lureau 
3660a237f4dSMarc-André Lureau     if (bind(listener, (struct sockaddr *)&addr, socklen) == -1) {
3670a237f4dSMarc-André Lureau         goto out;
3680a237f4dSMarc-André Lureau     }
3690a237f4dSMarc-André Lureau 
3700a237f4dSMarc-André Lureau     if (listen(listener, 1) == -1) {
3710a237f4dSMarc-André Lureau         goto out;
3720a237f4dSMarc-André Lureau     }
3730a237f4dSMarc-André Lureau 
3740a237f4dSMarc-André Lureau     client = socket(domain, type, protocol);
3750a237f4dSMarc-André Lureau     if (client == -1) {
3760a237f4dSMarc-André Lureau         goto out;
3770a237f4dSMarc-André Lureau     }
3780a237f4dSMarc-André Lureau 
3790a237f4dSMarc-André Lureau     arg = 1;
3800a237f4dSMarc-André Lureau     if (ioctlsocket(client, FIONBIO, &arg) != NO_ERROR) {
3810a237f4dSMarc-André Lureau         goto out;
3820a237f4dSMarc-André Lureau     }
3830a237f4dSMarc-André Lureau 
3840a237f4dSMarc-André Lureau     if (connect(client, (struct sockaddr *)&addr, socklen) == -1 &&
3850a237f4dSMarc-André Lureau         WSAGetLastError() != WSAEWOULDBLOCK) {
3860a237f4dSMarc-André Lureau         goto out;
3870a237f4dSMarc-André Lureau     }
3880a237f4dSMarc-André Lureau 
3890a237f4dSMarc-André Lureau     server = accept(listener, NULL, NULL);
3900a237f4dSMarc-André Lureau     if (server == -1) {
3910a237f4dSMarc-André Lureau         goto out;
3920a237f4dSMarc-André Lureau     }
3930a237f4dSMarc-André Lureau 
3940a237f4dSMarc-André Lureau     arg = 0;
3950a237f4dSMarc-André Lureau     if (ioctlsocket(client, FIONBIO, &arg) != NO_ERROR) {
3960a237f4dSMarc-André Lureau         goto out;
3970a237f4dSMarc-André Lureau     }
3980a237f4dSMarc-André Lureau 
3990a237f4dSMarc-André Lureau     arg = 0;
4000a237f4dSMarc-André Lureau     if (ioctlsocket(client, SIO_AF_UNIX_GETPEERPID, &arg) != NO_ERROR) {
4010a237f4dSMarc-André Lureau         goto out;
4020a237f4dSMarc-André Lureau     }
4030a237f4dSMarc-André Lureau 
4040a237f4dSMarc-André Lureau     if (arg != GetCurrentProcessId()) {
4050a237f4dSMarc-André Lureau         errno = EPERM;
4060a237f4dSMarc-André Lureau         goto out;
4070a237f4dSMarc-André Lureau     }
4080a237f4dSMarc-André Lureau 
4090a237f4dSMarc-André Lureau     sv[0] = server;
4100a237f4dSMarc-André Lureau     server = -1;
4110a237f4dSMarc-André Lureau     sv[1] = client;
4120a237f4dSMarc-André Lureau     client = -1;
4130a237f4dSMarc-André Lureau     ret = 0;
4140a237f4dSMarc-André Lureau 
4150a237f4dSMarc-André Lureau out:
4160a237f4dSMarc-André Lureau     if (listener != -1) {
4170a237f4dSMarc-André Lureau         close(listener);
4180a237f4dSMarc-André Lureau     }
4190a237f4dSMarc-André Lureau     if (client != -1) {
4200a237f4dSMarc-André Lureau         close(client);
4210a237f4dSMarc-André Lureau     }
4220a237f4dSMarc-André Lureau     if (server != -1) {
4230a237f4dSMarc-André Lureau         close(server);
4240a237f4dSMarc-André Lureau     }
4250a237f4dSMarc-André Lureau     if (path) {
4260a237f4dSMarc-André Lureau         DeleteFile(path);
4270a237f4dSMarc-André Lureau     }
4280a237f4dSMarc-André Lureau     return ret;
4290a237f4dSMarc-André Lureau }
4300a237f4dSMarc-André Lureau 
431a2d96af4SDaniel P. Berrange #undef connect
qemu_connect_wrap(int sockfd,const struct sockaddr * addr,socklen_t addrlen)432a2d96af4SDaniel P. Berrange int qemu_connect_wrap(int sockfd, const struct sockaddr *addr,
433a2d96af4SDaniel P. Berrange                       socklen_t addrlen)
434a2d96af4SDaniel P. Berrange {
435a2d96af4SDaniel P. Berrange     int ret;
436abe34282SMarc-André Lureau     SOCKET s = _get_osfhandle(sockfd);
437abe34282SMarc-André Lureau 
438abe34282SMarc-André Lureau     if (s == INVALID_SOCKET) {
439abe34282SMarc-André Lureau         return -1;
440abe34282SMarc-André Lureau     }
441abe34282SMarc-André Lureau 
442abe34282SMarc-André Lureau     ret = connect(s, addr, addrlen);
443a2d96af4SDaniel P. Berrange     if (ret < 0) {
444f1cd5d41SMarc-André Lureau         if (WSAGetLastError() == WSAEWOULDBLOCK) {
445f1cd5d41SMarc-André Lureau             errno = EINPROGRESS;
446f1cd5d41SMarc-André Lureau         } else {
447a2d96af4SDaniel P. Berrange             errno = socket_error();
448a2d96af4SDaniel P. Berrange         }
449f1cd5d41SMarc-André Lureau     }
450a2d96af4SDaniel P. Berrange     return ret;
451a2d96af4SDaniel P. Berrange }
452a2d96af4SDaniel P. Berrange 
453a2d96af4SDaniel P. Berrange 
454a2d96af4SDaniel P. Berrange #undef listen
qemu_listen_wrap(int sockfd,int backlog)455a2d96af4SDaniel P. Berrange int qemu_listen_wrap(int sockfd, int backlog)
456a2d96af4SDaniel P. Berrange {
457a2d96af4SDaniel P. Berrange     int ret;
458abe34282SMarc-André Lureau     SOCKET s = _get_osfhandle(sockfd);
459abe34282SMarc-André Lureau 
460abe34282SMarc-André Lureau     if (s == INVALID_SOCKET) {
461abe34282SMarc-André Lureau         return -1;
462abe34282SMarc-André Lureau     }
463abe34282SMarc-André Lureau 
464abe34282SMarc-André Lureau     ret = listen(s, backlog);
465a2d96af4SDaniel P. Berrange     if (ret < 0) {
466a2d96af4SDaniel P. Berrange         errno = socket_error();
467a2d96af4SDaniel P. Berrange     }
468a2d96af4SDaniel P. Berrange     return ret;
469a2d96af4SDaniel P. Berrange }
470a2d96af4SDaniel P. Berrange 
471a2d96af4SDaniel P. Berrange 
472a2d96af4SDaniel P. Berrange #undef bind
qemu_bind_wrap(int sockfd,const struct sockaddr * addr,socklen_t addrlen)473a2d96af4SDaniel P. Berrange int qemu_bind_wrap(int sockfd, const struct sockaddr *addr,
474a2d96af4SDaniel P. Berrange                    socklen_t addrlen)
475a2d96af4SDaniel P. Berrange {
476a2d96af4SDaniel P. Berrange     int ret;
477abe34282SMarc-André Lureau     SOCKET s = _get_osfhandle(sockfd);
478abe34282SMarc-André Lureau 
479abe34282SMarc-André Lureau     if (s == INVALID_SOCKET) {
480abe34282SMarc-André Lureau         return -1;
481a2d96af4SDaniel P. Berrange     }
482a2d96af4SDaniel P. Berrange 
483abe34282SMarc-André Lureau     ret = bind(s, addr, addrlen);
484a2d96af4SDaniel P. Berrange     if (ret < 0) {
485a2d96af4SDaniel P. Berrange         errno = socket_error();
486a2d96af4SDaniel P. Berrange     }
487a2d96af4SDaniel P. Berrange     return ret;
488a2d96af4SDaniel P. Berrange }
489a2d96af4SDaniel P. Berrange 
49075b773d8SMarc-André Lureau QEMU_USED EXCEPTION_DISPOSITION
win32_close_exception_handler(struct _EXCEPTION_RECORD * exception_record,void * registration,struct _CONTEXT * context,void * dispatcher)491c5b5288cSThomas Huth win32_close_exception_handler(struct _EXCEPTION_RECORD *exception_record,
492c5b5288cSThomas Huth                               void *registration, struct _CONTEXT *context,
493c5b5288cSThomas Huth                               void *dispatcher)
494d89f30b4SMarc-André Lureau {
495d89f30b4SMarc-André Lureau     return EXCEPTION_EXECUTE_HANDLER;
496d89f30b4SMarc-André Lureau }
497d89f30b4SMarc-André Lureau 
49825657fc6SMarc-André Lureau #undef close
qemu_close_socket_osfhandle(int fd)499f3ab43acSMarc-André Lureau int qemu_close_socket_osfhandle(int fd)
500a2d96af4SDaniel P. Berrange {
501f3ab43acSMarc-André Lureau     SOCKET s = _get_osfhandle(fd);
502abe34282SMarc-André Lureau     DWORD flags = 0;
503abe34282SMarc-André Lureau 
504abe34282SMarc-André Lureau     /*
505abe34282SMarc-André Lureau      * If we were to just call _close on the descriptor, it would close the
506abe34282SMarc-André Lureau      * HANDLE, but it wouldn't free any of the resources associated to the
507abe34282SMarc-André Lureau      * SOCKET, and we can't call _close after calling closesocket, because
508abe34282SMarc-André Lureau      * closesocket has already closed the HANDLE, and _close would attempt to
509abe34282SMarc-André Lureau      * close the HANDLE again, resulting in a double free. We can however
510abe34282SMarc-André Lureau      * protect the HANDLE from actually being closed long enough to close the
511abe34282SMarc-André Lureau      * file descriptor, then close the socket itself.
512abe34282SMarc-André Lureau      */
513abe34282SMarc-André Lureau     if (!GetHandleInformation((HANDLE)s, &flags)) {
514abe34282SMarc-André Lureau         errno = EACCES;
515abe34282SMarc-André Lureau         return -1;
516abe34282SMarc-André Lureau     }
517abe34282SMarc-André Lureau 
518abe34282SMarc-André Lureau     if (!SetHandleInformation((HANDLE)s, HANDLE_FLAG_PROTECT_FROM_CLOSE, HANDLE_FLAG_PROTECT_FROM_CLOSE)) {
519abe34282SMarc-André Lureau         errno = EACCES;
520abe34282SMarc-André Lureau         return -1;
521abe34282SMarc-André Lureau     }
522abe34282SMarc-André Lureau 
523d89f30b4SMarc-André Lureau     __try1(win32_close_exception_handler) {
524abe34282SMarc-André Lureau         /*
525d89f30b4SMarc-André Lureau          * close() returns EBADF since we PROTECT_FROM_CLOSE the underlying
526d89f30b4SMarc-André Lureau          * handle, but the FD is actually freed
527abe34282SMarc-André Lureau          */
528f3ab43acSMarc-André Lureau         if (close(fd) < 0 && errno != EBADF) {
529f3ab43acSMarc-André Lureau             return -1;
530abe34282SMarc-André Lureau         }
531d89f30b4SMarc-André Lureau     }
532d89f30b4SMarc-André Lureau     __except1 {
533d89f30b4SMarc-André Lureau     }
534abe34282SMarc-André Lureau 
535f3ab43acSMarc-André Lureau     if (!SetHandleInformation((HANDLE)s, flags, flags)) {
536f3ab43acSMarc-André Lureau         errno = EACCES;
537f3ab43acSMarc-André Lureau         return -1;
538f3ab43acSMarc-André Lureau     }
539f3ab43acSMarc-André Lureau 
540f3ab43acSMarc-André Lureau     return 0;
541f3ab43acSMarc-André Lureau }
542f3ab43acSMarc-André Lureau 
qemu_close_wrap(int fd)543f3ab43acSMarc-André Lureau int qemu_close_wrap(int fd)
544f3ab43acSMarc-André Lureau {
545f3ab43acSMarc-André Lureau     SOCKET s = INVALID_SOCKET;
546f3ab43acSMarc-André Lureau     int ret = -1;
547f3ab43acSMarc-André Lureau 
548f3ab43acSMarc-André Lureau     if (!fd_is_socket(fd)) {
549f3ab43acSMarc-André Lureau         return close(fd);
550f3ab43acSMarc-André Lureau     }
551f3ab43acSMarc-André Lureau 
552f3ab43acSMarc-André Lureau     s = _get_osfhandle(fd);
553f3ab43acSMarc-André Lureau     qemu_close_socket_osfhandle(fd);
554f3ab43acSMarc-André Lureau 
555abe34282SMarc-André Lureau     ret = closesocket(s);
556abe34282SMarc-André Lureau     if (ret < 0) {
557abe34282SMarc-André Lureau         errno = socket_error();
558abe34282SMarc-André Lureau     }
559abe34282SMarc-André Lureau 
560abe34282SMarc-André Lureau     return ret;
561abe34282SMarc-André Lureau }
562abe34282SMarc-André Lureau 
563abe34282SMarc-André Lureau 
564abe34282SMarc-André Lureau #undef socket
qemu_socket_wrap(int domain,int type,int protocol)565abe34282SMarc-André Lureau int qemu_socket_wrap(int domain, int type, int protocol)
566abe34282SMarc-André Lureau {
567abe34282SMarc-André Lureau     SOCKET s;
568abe34282SMarc-André Lureau     int fd;
569abe34282SMarc-André Lureau 
570abe34282SMarc-André Lureau     s = socket(domain, type, protocol);
571abe34282SMarc-André Lureau     if (s == -1) {
572abe34282SMarc-André Lureau         errno = socket_error();
573abe34282SMarc-André Lureau         return -1;
574abe34282SMarc-André Lureau     }
575abe34282SMarc-André Lureau 
576abe34282SMarc-André Lureau     fd = _open_osfhandle(s, _O_BINARY);
577abe34282SMarc-André Lureau     if (fd < 0) {
578abe34282SMarc-André Lureau         closesocket(s);
579abe34282SMarc-André Lureau         /* _open_osfhandle may not set errno, and closesocket() may override it */
580abe34282SMarc-André Lureau         errno = ENOMEM;
581abe34282SMarc-André Lureau     }
582abe34282SMarc-André Lureau 
583abe34282SMarc-André Lureau     return fd;
584abe34282SMarc-André Lureau }
585abe34282SMarc-André Lureau 
586abe34282SMarc-André Lureau 
587abe34282SMarc-André Lureau #undef accept
qemu_accept_wrap(int sockfd,struct sockaddr * addr,socklen_t * addrlen)588abe34282SMarc-André Lureau int qemu_accept_wrap(int sockfd, struct sockaddr *addr,
589abe34282SMarc-André Lureau                      socklen_t *addrlen)
590abe34282SMarc-André Lureau {
591abe34282SMarc-André Lureau     int fd;
592abe34282SMarc-André Lureau     SOCKET s = _get_osfhandle(sockfd);
593abe34282SMarc-André Lureau 
594abe34282SMarc-André Lureau     if (s == INVALID_SOCKET) {
595abe34282SMarc-André Lureau         return -1;
596abe34282SMarc-André Lureau     }
597abe34282SMarc-André Lureau 
598abe34282SMarc-André Lureau     s = accept(s, addr, addrlen);
599abe34282SMarc-André Lureau     if (s == -1) {
600abe34282SMarc-André Lureau         errno = socket_error();
601abe34282SMarc-André Lureau         return -1;
602abe34282SMarc-André Lureau     }
603abe34282SMarc-André Lureau 
604abe34282SMarc-André Lureau     fd = _open_osfhandle(s, _O_BINARY);
605abe34282SMarc-André Lureau     if (fd < 0) {
606abe34282SMarc-André Lureau         closesocket(s);
607abe34282SMarc-André Lureau         /* _open_osfhandle may not set errno, and closesocket() may override it */
608abe34282SMarc-André Lureau         errno = ENOMEM;
609abe34282SMarc-André Lureau     }
610abe34282SMarc-André Lureau 
611abe34282SMarc-André Lureau     return fd;
612abe34282SMarc-André Lureau }
613abe34282SMarc-André Lureau 
614abe34282SMarc-André Lureau 
615abe34282SMarc-André Lureau #undef shutdown
qemu_shutdown_wrap(int sockfd,int how)616abe34282SMarc-André Lureau int qemu_shutdown_wrap(int sockfd, int how)
617abe34282SMarc-André Lureau {
618abe34282SMarc-André Lureau     int ret;
619abe34282SMarc-André Lureau     SOCKET s = _get_osfhandle(sockfd);
620abe34282SMarc-André Lureau 
621abe34282SMarc-André Lureau     if (s == INVALID_SOCKET) {
622abe34282SMarc-André Lureau         return -1;
623abe34282SMarc-André Lureau     }
624abe34282SMarc-André Lureau 
625abe34282SMarc-André Lureau     ret = shutdown(s, how);
626abe34282SMarc-André Lureau     if (ret < 0) {
627abe34282SMarc-André Lureau         errno = socket_error();
628abe34282SMarc-André Lureau     }
629abe34282SMarc-André Lureau     return ret;
630abe34282SMarc-André Lureau }
631abe34282SMarc-André Lureau 
632abe34282SMarc-André Lureau 
633abe34282SMarc-André Lureau #undef ioctlsocket
qemu_ioctlsocket_wrap(int fd,int req,void * val)634abe34282SMarc-André Lureau int qemu_ioctlsocket_wrap(int fd, int req, void *val)
635abe34282SMarc-André Lureau {
636abe34282SMarc-André Lureau     int ret;
637abe34282SMarc-André Lureau     SOCKET s = _get_osfhandle(fd);
638abe34282SMarc-André Lureau 
639abe34282SMarc-André Lureau     if (s == INVALID_SOCKET) {
640abe34282SMarc-André Lureau         return -1;
641abe34282SMarc-André Lureau     }
642abe34282SMarc-André Lureau 
643abe34282SMarc-André Lureau     ret = ioctlsocket(s, req, val);
644a2d96af4SDaniel P. Berrange     if (ret < 0) {
645a2d96af4SDaniel P. Berrange         errno = socket_error();
646a2d96af4SDaniel P. Berrange     }
647a2d96af4SDaniel P. Berrange     return ret;
648a2d96af4SDaniel P. Berrange }
649a2d96af4SDaniel P. Berrange 
650a2d96af4SDaniel P. Berrange 
651a2d96af4SDaniel P. Berrange #undef getsockopt
qemu_getsockopt_wrap(int sockfd,int level,int optname,void * optval,socklen_t * optlen)652a2d96af4SDaniel P. Berrange int qemu_getsockopt_wrap(int sockfd, int level, int optname,
653a2d96af4SDaniel P. Berrange                          void *optval, socklen_t *optlen)
654a2d96af4SDaniel P. Berrange {
655a2d96af4SDaniel P. Berrange     int ret;
656abe34282SMarc-André Lureau     SOCKET s = _get_osfhandle(sockfd);
657abe34282SMarc-André Lureau 
658abe34282SMarc-André Lureau     if (s == INVALID_SOCKET) {
659abe34282SMarc-André Lureau         return -1;
660abe34282SMarc-André Lureau     }
661abe34282SMarc-André Lureau 
662abe34282SMarc-André Lureau     ret = getsockopt(s, level, optname, optval, optlen);
663a2d96af4SDaniel P. Berrange     if (ret < 0) {
664a2d96af4SDaniel P. Berrange         errno = socket_error();
665a2d96af4SDaniel P. Berrange     }
666a2d96af4SDaniel P. Berrange     return ret;
667a2d96af4SDaniel P. Berrange }
668a2d96af4SDaniel P. Berrange 
669a2d96af4SDaniel P. Berrange 
670a2d96af4SDaniel P. Berrange #undef setsockopt
qemu_setsockopt_wrap(int sockfd,int level,int optname,const void * optval,socklen_t optlen)671a2d96af4SDaniel P. Berrange int qemu_setsockopt_wrap(int sockfd, int level, int optname,
672a2d96af4SDaniel P. Berrange                          const void *optval, socklen_t optlen)
673a2d96af4SDaniel P. Berrange {
674a2d96af4SDaniel P. Berrange     int ret;
675abe34282SMarc-André Lureau     SOCKET s = _get_osfhandle(sockfd);
676abe34282SMarc-André Lureau 
677abe34282SMarc-André Lureau     if (s == INVALID_SOCKET) {
678abe34282SMarc-André Lureau         return -1;
679abe34282SMarc-André Lureau     }
680abe34282SMarc-André Lureau 
681abe34282SMarc-André Lureau     ret = setsockopt(s, level, optname, optval, optlen);
682a2d96af4SDaniel P. Berrange     if (ret < 0) {
683a2d96af4SDaniel P. Berrange         errno = socket_error();
684a2d96af4SDaniel P. Berrange     }
685a2d96af4SDaniel P. Berrange     return ret;
686a2d96af4SDaniel P. Berrange }
687a2d96af4SDaniel P. Berrange 
688a2d96af4SDaniel P. Berrange 
689a2d96af4SDaniel P. Berrange #undef getpeername
qemu_getpeername_wrap(int sockfd,struct sockaddr * addr,socklen_t * addrlen)690a2d96af4SDaniel P. Berrange int qemu_getpeername_wrap(int sockfd, struct sockaddr *addr,
691a2d96af4SDaniel P. Berrange                           socklen_t *addrlen)
692a2d96af4SDaniel P. Berrange {
693a2d96af4SDaniel P. Berrange     int ret;
694abe34282SMarc-André Lureau     SOCKET s = _get_osfhandle(sockfd);
695abe34282SMarc-André Lureau 
696abe34282SMarc-André Lureau     if (s == INVALID_SOCKET) {
697abe34282SMarc-André Lureau         return -1;
698abe34282SMarc-André Lureau     }
699abe34282SMarc-André Lureau 
700abe34282SMarc-André Lureau     ret = getpeername(s, addr, addrlen);
701a2d96af4SDaniel P. Berrange     if (ret < 0) {
702a2d96af4SDaniel P. Berrange         errno = socket_error();
703a2d96af4SDaniel P. Berrange     }
704a2d96af4SDaniel P. Berrange     return ret;
705a2d96af4SDaniel P. Berrange }
706a2d96af4SDaniel P. Berrange 
707a2d96af4SDaniel P. Berrange 
708a2d96af4SDaniel P. Berrange #undef getsockname
qemu_getsockname_wrap(int sockfd,struct sockaddr * addr,socklen_t * addrlen)709a2d96af4SDaniel P. Berrange int qemu_getsockname_wrap(int sockfd, struct sockaddr *addr,
710a2d96af4SDaniel P. Berrange                           socklen_t *addrlen)
711a2d96af4SDaniel P. Berrange {
712a2d96af4SDaniel P. Berrange     int ret;
713abe34282SMarc-André Lureau     SOCKET s = _get_osfhandle(sockfd);
714abe34282SMarc-André Lureau 
715abe34282SMarc-André Lureau     if (s == INVALID_SOCKET) {
716abe34282SMarc-André Lureau         return -1;
717abe34282SMarc-André Lureau     }
718abe34282SMarc-André Lureau 
719abe34282SMarc-André Lureau     ret = getsockname(s, addr, addrlen);
720a2d96af4SDaniel P. Berrange     if (ret < 0) {
721a2d96af4SDaniel P. Berrange         errno = socket_error();
722a2d96af4SDaniel P. Berrange     }
723a2d96af4SDaniel P. Berrange     return ret;
724a2d96af4SDaniel P. Berrange }
725a2d96af4SDaniel P. Berrange 
726a2d96af4SDaniel P. Berrange 
727a2d96af4SDaniel P. Berrange #undef send
qemu_send_wrap(int sockfd,const void * buf,size_t len,int flags)728a2d96af4SDaniel P. Berrange ssize_t qemu_send_wrap(int sockfd, const void *buf, size_t len, int flags)
729a2d96af4SDaniel P. Berrange {
730a2d96af4SDaniel P. Berrange     int ret;
731abe34282SMarc-André Lureau     SOCKET s = _get_osfhandle(sockfd);
732abe34282SMarc-André Lureau 
733abe34282SMarc-André Lureau     if (s == INVALID_SOCKET) {
734abe34282SMarc-André Lureau         return -1;
735abe34282SMarc-André Lureau     }
736abe34282SMarc-André Lureau 
737abe34282SMarc-André Lureau     ret = send(s, buf, len, flags);
738a2d96af4SDaniel P. Berrange     if (ret < 0) {
739a2d96af4SDaniel P. Berrange         errno = socket_error();
740a2d96af4SDaniel P. Berrange     }
741a2d96af4SDaniel P. Berrange     return ret;
742a2d96af4SDaniel P. Berrange }
743a2d96af4SDaniel P. Berrange 
744a2d96af4SDaniel P. Berrange 
745a2d96af4SDaniel P. Berrange #undef sendto
qemu_sendto_wrap(int sockfd,const void * buf,size_t len,int flags,const struct sockaddr * addr,socklen_t addrlen)746a2d96af4SDaniel P. Berrange ssize_t qemu_sendto_wrap(int sockfd, const void *buf, size_t len, int flags,
747a2d96af4SDaniel P. Berrange                          const struct sockaddr *addr, socklen_t addrlen)
748a2d96af4SDaniel P. Berrange {
749a2d96af4SDaniel P. Berrange     int ret;
750abe34282SMarc-André Lureau     SOCKET s = _get_osfhandle(sockfd);
751abe34282SMarc-André Lureau 
752abe34282SMarc-André Lureau     if (s == INVALID_SOCKET) {
753abe34282SMarc-André Lureau         return -1;
754abe34282SMarc-André Lureau     }
755abe34282SMarc-André Lureau 
756abe34282SMarc-André Lureau     ret = sendto(s, buf, len, flags, addr, addrlen);
757a2d96af4SDaniel P. Berrange     if (ret < 0) {
758a2d96af4SDaniel P. Berrange         errno = socket_error();
759a2d96af4SDaniel P. Berrange     }
760a2d96af4SDaniel P. Berrange     return ret;
761a2d96af4SDaniel P. Berrange }
762a2d96af4SDaniel P. Berrange 
763a2d96af4SDaniel P. Berrange 
764a2d96af4SDaniel P. Berrange #undef recv
qemu_recv_wrap(int sockfd,void * buf,size_t len,int flags)765a2d96af4SDaniel P. Berrange ssize_t qemu_recv_wrap(int sockfd, void *buf, size_t len, int flags)
766a2d96af4SDaniel P. Berrange {
767a2d96af4SDaniel P. Berrange     int ret;
768abe34282SMarc-André Lureau     SOCKET s = _get_osfhandle(sockfd);
769abe34282SMarc-André Lureau 
770abe34282SMarc-André Lureau     if (s == INVALID_SOCKET) {
771abe34282SMarc-André Lureau         return -1;
772abe34282SMarc-André Lureau     }
773abe34282SMarc-André Lureau 
774abe34282SMarc-André Lureau     ret = recv(s, buf, len, flags);
775a2d96af4SDaniel P. Berrange     if (ret < 0) {
776a2d96af4SDaniel P. Berrange         errno = socket_error();
777a2d96af4SDaniel P. Berrange     }
778a2d96af4SDaniel P. Berrange     return ret;
779a2d96af4SDaniel P. Berrange }
780a2d96af4SDaniel P. Berrange 
781a2d96af4SDaniel P. Berrange 
782a2d96af4SDaniel P. Berrange #undef recvfrom
qemu_recvfrom_wrap(int sockfd,void * buf,size_t len,int flags,struct sockaddr * addr,socklen_t * addrlen)783a2d96af4SDaniel P. Berrange ssize_t qemu_recvfrom_wrap(int sockfd, void *buf, size_t len, int flags,
784a2d96af4SDaniel P. Berrange                            struct sockaddr *addr, socklen_t *addrlen)
785a2d96af4SDaniel P. Berrange {
786a2d96af4SDaniel P. Berrange     int ret;
787abe34282SMarc-André Lureau     SOCKET s = _get_osfhandle(sockfd);
788abe34282SMarc-André Lureau 
789abe34282SMarc-André Lureau     if (s == INVALID_SOCKET) {
790abe34282SMarc-André Lureau         return -1;
791abe34282SMarc-André Lureau     }
792abe34282SMarc-André Lureau 
793abe34282SMarc-André Lureau     ret = recvfrom(s, buf, len, flags, addr, addrlen);
794a2d96af4SDaniel P. Berrange     if (ret < 0) {
795a2d96af4SDaniel P. Berrange         errno = socket_error();
796a2d96af4SDaniel P. Berrange     }
797a2d96af4SDaniel P. Berrange     return ret;
798a2d96af4SDaniel P. Berrange }
7999e6bdef2SMarc-André Lureau 
qemu_write_pidfile(const char * filename,Error ** errp)8009e6bdef2SMarc-André Lureau bool qemu_write_pidfile(const char *filename, Error **errp)
8019e6bdef2SMarc-André Lureau {
8029e6bdef2SMarc-André Lureau     char buffer[128];
8039e6bdef2SMarc-André Lureau     int len;
8049e6bdef2SMarc-André Lureau     HANDLE file;
8059e6bdef2SMarc-André Lureau     OVERLAPPED overlap;
8069e6bdef2SMarc-André Lureau     BOOL ret;
8079e6bdef2SMarc-André Lureau     memset(&overlap, 0, sizeof(overlap));
8089e6bdef2SMarc-André Lureau 
8099e6bdef2SMarc-André Lureau     file = CreateFile(filename, GENERIC_WRITE, FILE_SHARE_READ, NULL,
8109e6bdef2SMarc-André Lureau                       OPEN_ALWAYS, FILE_ATTRIBUTE_NORMAL, NULL);
8119e6bdef2SMarc-André Lureau 
8129e6bdef2SMarc-André Lureau     if (file == INVALID_HANDLE_VALUE) {
8139e6bdef2SMarc-André Lureau         error_setg(errp, "Failed to create PID file");
8149e6bdef2SMarc-André Lureau         return false;
8159e6bdef2SMarc-André Lureau     }
8169e6bdef2SMarc-André Lureau     len = snprintf(buffer, sizeof(buffer), FMT_pid "\n", (pid_t)getpid());
8179e6bdef2SMarc-André Lureau     ret = WriteFile(file, (LPCVOID)buffer, (DWORD)len,
8189e6bdef2SMarc-André Lureau                     NULL, &overlap);
8199e6bdef2SMarc-André Lureau     CloseHandle(file);
8209e6bdef2SMarc-André Lureau     if (ret == 0) {
8219e6bdef2SMarc-André Lureau         error_setg(errp, "Failed to write PID file");
8229e6bdef2SMarc-André Lureau         return false;
8239e6bdef2SMarc-André Lureau     }
8249e6bdef2SMarc-André Lureau     return true;
8259e6bdef2SMarc-André Lureau }
826e47f4765SMichal Privoznik 
qemu_get_host_physmem(void)827ad06ef0eSAlex Bennée size_t qemu_get_host_physmem(void)
828ad06ef0eSAlex Bennée {
829986babaaSAlex Bennée     MEMORYSTATUSEX statex;
830986babaaSAlex Bennée     statex.dwLength = sizeof(statex);
831986babaaSAlex Bennée 
832986babaaSAlex Bennée     if (GlobalMemoryStatusEx(&statex)) {
833986babaaSAlex Bennée         return statex.ullTotalPhys;
834986babaaSAlex Bennée     }
835ad06ef0eSAlex Bennée     return 0;
836ad06ef0eSAlex Bennée }
83773991a92SMarc-André Lureau 
qemu_msync(void * addr,size_t length,int fd)83873991a92SMarc-André Lureau int qemu_msync(void *addr, size_t length, int fd)
83973991a92SMarc-André Lureau {
84073991a92SMarc-André Lureau     /**
84173991a92SMarc-André Lureau      * Perform the sync based on the file descriptor
84273991a92SMarc-André Lureau      * The sync range will most probably be wider than the one
84373991a92SMarc-André Lureau      * requested - but it will still get the job done
84473991a92SMarc-André Lureau      */
84573991a92SMarc-André Lureau     return qemu_fdatasync(fd);
84673991a92SMarc-André Lureau }
84709b4c198SMarc-André Lureau 
qemu_win32_map_alloc(size_t size,HANDLE * h,Error ** errp)84809b4c198SMarc-André Lureau void *qemu_win32_map_alloc(size_t size, HANDLE *h, Error **errp)
84909b4c198SMarc-André Lureau {
85009b4c198SMarc-André Lureau     void *bits;
85109b4c198SMarc-André Lureau 
85209b4c198SMarc-André Lureau     trace_win32_map_alloc(size);
85309b4c198SMarc-André Lureau 
85409b4c198SMarc-André Lureau     *h = CreateFileMapping(INVALID_HANDLE_VALUE, NULL, PAGE_READWRITE, 0,
85509b4c198SMarc-André Lureau                           size, NULL);
85609b4c198SMarc-André Lureau     if (*h == NULL) {
85709b4c198SMarc-André Lureau         error_setg_win32(errp, GetLastError(), "Failed to CreateFileMapping");
85809b4c198SMarc-André Lureau         return NULL;
85909b4c198SMarc-André Lureau     }
86009b4c198SMarc-André Lureau 
86109b4c198SMarc-André Lureau     bits = MapViewOfFile(*h, FILE_MAP_ALL_ACCESS, 0, 0, size);
86209b4c198SMarc-André Lureau     if (bits == NULL) {
86309b4c198SMarc-André Lureau         error_setg_win32(errp, GetLastError(), "Failed to MapViewOfFile");
86409b4c198SMarc-André Lureau         CloseHandle(*h);
86509b4c198SMarc-André Lureau         return NULL;
86609b4c198SMarc-André Lureau     }
86709b4c198SMarc-André Lureau 
86809b4c198SMarc-André Lureau     return bits;
86909b4c198SMarc-André Lureau }
87009b4c198SMarc-André Lureau 
qemu_win32_map_free(void * ptr,HANDLE h,Error ** errp)87109b4c198SMarc-André Lureau void qemu_win32_map_free(void *ptr, HANDLE h, Error **errp)
87209b4c198SMarc-André Lureau {
87309b4c198SMarc-André Lureau     trace_win32_map_free(ptr, h);
87409b4c198SMarc-André Lureau 
87509b4c198SMarc-André Lureau     if (UnmapViewOfFile(ptr) == 0) {
87609b4c198SMarc-André Lureau         error_setg_win32(errp, GetLastError(), "Failed to UnmapViewOfFile");
87709b4c198SMarc-André Lureau     }
87809b4c198SMarc-André Lureau     CloseHandle(h);
87909b4c198SMarc-André Lureau }
880