xref: /openbmc/qemu/util/oslib-win32.c (revision 75b773d8)
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,Error ** errp)2676556aadcSDavid Hildenbrand void qemu_prealloc_mem(int fd, char *area, size_t sz, int max_threads,
268e04a34e5SDavid Hildenbrand                        ThreadContext *tc, 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     }
27738183310SPaolo Bonzini }
278d57e4e48SDaniel P. Berrange 
qemu_get_pid_name(pid_t pid)2797dc9ae43SMichal Privoznik char *qemu_get_pid_name(pid_t pid)
2807dc9ae43SMichal Privoznik {
2817dc9ae43SMichal Privoznik     /* XXX Implement me */
2827dc9ae43SMichal Privoznik     abort();
2837dc9ae43SMichal Privoznik }
2847dc9ae43SMichal Privoznik 
2857dc9ae43SMichal Privoznik 
qemu_socket_select(int sockfd,WSAEVENT hEventObject,long lNetworkEvents,Error ** errp)286abe34282SMarc-André Lureau bool qemu_socket_select(int sockfd, WSAEVENT hEventObject,
287f5fd677aSMarc-André Lureau                         long lNetworkEvents, Error **errp)
288f5fd677aSMarc-André Lureau {
289abe34282SMarc-André Lureau     SOCKET s = _get_osfhandle(sockfd);
290abe34282SMarc-André Lureau 
291f5fd677aSMarc-André Lureau     if (errp == NULL) {
292f5fd677aSMarc-André Lureau         errp = &error_warn;
293f5fd677aSMarc-André Lureau     }
294f5fd677aSMarc-André Lureau 
295abe34282SMarc-André Lureau     if (s == INVALID_SOCKET) {
296abe34282SMarc-André Lureau         error_setg(errp, "invalid socket fd=%d", sockfd);
297abe34282SMarc-André Lureau         return false;
298abe34282SMarc-André Lureau     }
299abe34282SMarc-André Lureau 
300f5fd677aSMarc-André Lureau     if (WSAEventSelect(s, hEventObject, lNetworkEvents) != 0) {
301f5fd677aSMarc-André Lureau         error_setg_win32(errp, WSAGetLastError(), "failed to WSAEventSelect()");
302f5fd677aSMarc-André Lureau         return false;
303f5fd677aSMarc-André Lureau     }
304f5fd677aSMarc-André Lureau 
305f5fd677aSMarc-André Lureau     return true;
306f5fd677aSMarc-André Lureau }
307f5fd677aSMarc-André Lureau 
qemu_socket_unselect(int sockfd,Error ** errp)308abe34282SMarc-André Lureau bool qemu_socket_unselect(int sockfd, Error **errp)
309a4aafea2SMarc-André Lureau {
310abe34282SMarc-André Lureau     return qemu_socket_select(sockfd, NULL, 0, errp);
311a4aafea2SMarc-André Lureau }
312a4aafea2SMarc-André Lureau 
qemu_socketpair(int domain,int type,int protocol,int sv[2])3130a237f4dSMarc-André Lureau int qemu_socketpair(int domain, int type, int protocol, int sv[2])
3140a237f4dSMarc-André Lureau {
3150a237f4dSMarc-André Lureau     struct sockaddr_un addr = {
3160a237f4dSMarc-André Lureau         0,
3170a237f4dSMarc-André Lureau     };
3180a237f4dSMarc-André Lureau     socklen_t socklen;
3190a237f4dSMarc-André Lureau     int listener = -1;
3200a237f4dSMarc-André Lureau     int client = -1;
3210a237f4dSMarc-André Lureau     int server = -1;
3220a237f4dSMarc-André Lureau     g_autofree char *path = NULL;
3230a237f4dSMarc-André Lureau     int tmpfd;
3240a237f4dSMarc-André Lureau     u_long arg;
3250a237f4dSMarc-André Lureau     int ret = -1;
3260a237f4dSMarc-André Lureau 
3270a237f4dSMarc-André Lureau     g_return_val_if_fail(sv != NULL, -1);
3280a237f4dSMarc-André Lureau 
3290a237f4dSMarc-André Lureau     addr.sun_family = AF_UNIX;
3300a237f4dSMarc-André Lureau     socklen = sizeof(addr);
3310a237f4dSMarc-André Lureau 
3320a237f4dSMarc-André Lureau     tmpfd = g_file_open_tmp(NULL, &path, NULL);
3330a237f4dSMarc-André Lureau     if (tmpfd == -1 || !path) {
3340a237f4dSMarc-André Lureau         errno = EACCES;
3350a237f4dSMarc-André Lureau         goto out;
3360a237f4dSMarc-André Lureau     }
3370a237f4dSMarc-André Lureau 
3380a237f4dSMarc-André Lureau     close(tmpfd);
3390a237f4dSMarc-André Lureau 
3400a237f4dSMarc-André Lureau     if (strlen(path) >= sizeof(addr.sun_path)) {
3410a237f4dSMarc-André Lureau         errno = EINVAL;
3420a237f4dSMarc-André Lureau         goto out;
3430a237f4dSMarc-André Lureau     }
3440a237f4dSMarc-André Lureau 
3450a237f4dSMarc-André Lureau     strncpy(addr.sun_path, path, sizeof(addr.sun_path) - 1);
3460a237f4dSMarc-André Lureau 
3470a237f4dSMarc-André Lureau     listener = socket(domain, type, protocol);
3480a237f4dSMarc-André Lureau     if (listener == -1) {
3490a237f4dSMarc-André Lureau         goto out;
3500a237f4dSMarc-André Lureau     }
3510a237f4dSMarc-André Lureau 
3520a237f4dSMarc-André Lureau     if (DeleteFile(path) == 0 && GetLastError() != ERROR_FILE_NOT_FOUND) {
3530a237f4dSMarc-André Lureau         errno = EACCES;
3540a237f4dSMarc-André Lureau         goto out;
3550a237f4dSMarc-André Lureau     }
3560a237f4dSMarc-André Lureau     g_clear_pointer(&path, g_free);
3570a237f4dSMarc-André Lureau 
3580a237f4dSMarc-André Lureau     if (bind(listener, (struct sockaddr *)&addr, socklen) == -1) {
3590a237f4dSMarc-André Lureau         goto out;
3600a237f4dSMarc-André Lureau     }
3610a237f4dSMarc-André Lureau 
3620a237f4dSMarc-André Lureau     if (listen(listener, 1) == -1) {
3630a237f4dSMarc-André Lureau         goto out;
3640a237f4dSMarc-André Lureau     }
3650a237f4dSMarc-André Lureau 
3660a237f4dSMarc-André Lureau     client = socket(domain, type, protocol);
3670a237f4dSMarc-André Lureau     if (client == -1) {
3680a237f4dSMarc-André Lureau         goto out;
3690a237f4dSMarc-André Lureau     }
3700a237f4dSMarc-André Lureau 
3710a237f4dSMarc-André Lureau     arg = 1;
3720a237f4dSMarc-André Lureau     if (ioctlsocket(client, FIONBIO, &arg) != NO_ERROR) {
3730a237f4dSMarc-André Lureau         goto out;
3740a237f4dSMarc-André Lureau     }
3750a237f4dSMarc-André Lureau 
3760a237f4dSMarc-André Lureau     if (connect(client, (struct sockaddr *)&addr, socklen) == -1 &&
3770a237f4dSMarc-André Lureau         WSAGetLastError() != WSAEWOULDBLOCK) {
3780a237f4dSMarc-André Lureau         goto out;
3790a237f4dSMarc-André Lureau     }
3800a237f4dSMarc-André Lureau 
3810a237f4dSMarc-André Lureau     server = accept(listener, NULL, NULL);
3820a237f4dSMarc-André Lureau     if (server == -1) {
3830a237f4dSMarc-André Lureau         goto out;
3840a237f4dSMarc-André Lureau     }
3850a237f4dSMarc-André Lureau 
3860a237f4dSMarc-André Lureau     arg = 0;
3870a237f4dSMarc-André Lureau     if (ioctlsocket(client, FIONBIO, &arg) != NO_ERROR) {
3880a237f4dSMarc-André Lureau         goto out;
3890a237f4dSMarc-André Lureau     }
3900a237f4dSMarc-André Lureau 
3910a237f4dSMarc-André Lureau     arg = 0;
3920a237f4dSMarc-André Lureau     if (ioctlsocket(client, SIO_AF_UNIX_GETPEERPID, &arg) != NO_ERROR) {
3930a237f4dSMarc-André Lureau         goto out;
3940a237f4dSMarc-André Lureau     }
3950a237f4dSMarc-André Lureau 
3960a237f4dSMarc-André Lureau     if (arg != GetCurrentProcessId()) {
3970a237f4dSMarc-André Lureau         errno = EPERM;
3980a237f4dSMarc-André Lureau         goto out;
3990a237f4dSMarc-André Lureau     }
4000a237f4dSMarc-André Lureau 
4010a237f4dSMarc-André Lureau     sv[0] = server;
4020a237f4dSMarc-André Lureau     server = -1;
4030a237f4dSMarc-André Lureau     sv[1] = client;
4040a237f4dSMarc-André Lureau     client = -1;
4050a237f4dSMarc-André Lureau     ret = 0;
4060a237f4dSMarc-André Lureau 
4070a237f4dSMarc-André Lureau out:
4080a237f4dSMarc-André Lureau     if (listener != -1) {
4090a237f4dSMarc-André Lureau         close(listener);
4100a237f4dSMarc-André Lureau     }
4110a237f4dSMarc-André Lureau     if (client != -1) {
4120a237f4dSMarc-André Lureau         close(client);
4130a237f4dSMarc-André Lureau     }
4140a237f4dSMarc-André Lureau     if (server != -1) {
4150a237f4dSMarc-André Lureau         close(server);
4160a237f4dSMarc-André Lureau     }
4170a237f4dSMarc-André Lureau     if (path) {
4180a237f4dSMarc-André Lureau         DeleteFile(path);
4190a237f4dSMarc-André Lureau     }
4200a237f4dSMarc-André Lureau     return ret;
4210a237f4dSMarc-André Lureau }
4220a237f4dSMarc-André Lureau 
423a2d96af4SDaniel P. Berrange #undef connect
qemu_connect_wrap(int sockfd,const struct sockaddr * addr,socklen_t addrlen)424a2d96af4SDaniel P. Berrange int qemu_connect_wrap(int sockfd, const struct sockaddr *addr,
425a2d96af4SDaniel P. Berrange                       socklen_t addrlen)
426a2d96af4SDaniel P. Berrange {
427a2d96af4SDaniel P. Berrange     int ret;
428abe34282SMarc-André Lureau     SOCKET s = _get_osfhandle(sockfd);
429abe34282SMarc-André Lureau 
430abe34282SMarc-André Lureau     if (s == INVALID_SOCKET) {
431abe34282SMarc-André Lureau         return -1;
432abe34282SMarc-André Lureau     }
433abe34282SMarc-André Lureau 
434abe34282SMarc-André Lureau     ret = connect(s, addr, addrlen);
435a2d96af4SDaniel P. Berrange     if (ret < 0) {
436f1cd5d41SMarc-André Lureau         if (WSAGetLastError() == WSAEWOULDBLOCK) {
437f1cd5d41SMarc-André Lureau             errno = EINPROGRESS;
438f1cd5d41SMarc-André Lureau         } else {
439a2d96af4SDaniel P. Berrange             errno = socket_error();
440a2d96af4SDaniel P. Berrange         }
441f1cd5d41SMarc-André Lureau     }
442a2d96af4SDaniel P. Berrange     return ret;
443a2d96af4SDaniel P. Berrange }
444a2d96af4SDaniel P. Berrange 
445a2d96af4SDaniel P. Berrange 
446a2d96af4SDaniel P. Berrange #undef listen
qemu_listen_wrap(int sockfd,int backlog)447a2d96af4SDaniel P. Berrange int qemu_listen_wrap(int sockfd, int backlog)
448a2d96af4SDaniel P. Berrange {
449a2d96af4SDaniel P. Berrange     int ret;
450abe34282SMarc-André Lureau     SOCKET s = _get_osfhandle(sockfd);
451abe34282SMarc-André Lureau 
452abe34282SMarc-André Lureau     if (s == INVALID_SOCKET) {
453abe34282SMarc-André Lureau         return -1;
454abe34282SMarc-André Lureau     }
455abe34282SMarc-André Lureau 
456abe34282SMarc-André Lureau     ret = listen(s, backlog);
457a2d96af4SDaniel P. Berrange     if (ret < 0) {
458a2d96af4SDaniel P. Berrange         errno = socket_error();
459a2d96af4SDaniel P. Berrange     }
460a2d96af4SDaniel P. Berrange     return ret;
461a2d96af4SDaniel P. Berrange }
462a2d96af4SDaniel P. Berrange 
463a2d96af4SDaniel P. Berrange 
464a2d96af4SDaniel P. Berrange #undef bind
qemu_bind_wrap(int sockfd,const struct sockaddr * addr,socklen_t addrlen)465a2d96af4SDaniel P. Berrange int qemu_bind_wrap(int sockfd, const struct sockaddr *addr,
466a2d96af4SDaniel P. Berrange                    socklen_t addrlen)
467a2d96af4SDaniel P. Berrange {
468a2d96af4SDaniel P. Berrange     int ret;
469abe34282SMarc-André Lureau     SOCKET s = _get_osfhandle(sockfd);
470abe34282SMarc-André Lureau 
471abe34282SMarc-André Lureau     if (s == INVALID_SOCKET) {
472abe34282SMarc-André Lureau         return -1;
473a2d96af4SDaniel P. Berrange     }
474a2d96af4SDaniel P. Berrange 
475abe34282SMarc-André Lureau     ret = bind(s, addr, addrlen);
476a2d96af4SDaniel P. Berrange     if (ret < 0) {
477a2d96af4SDaniel P. Berrange         errno = socket_error();
478a2d96af4SDaniel P. Berrange     }
479a2d96af4SDaniel P. Berrange     return ret;
480a2d96af4SDaniel P. Berrange }
481a2d96af4SDaniel P. Berrange 
482*75b773d8SMarc-André Lureau QEMU_USED EXCEPTION_DISPOSITION
win32_close_exception_handler(struct _EXCEPTION_RECORD * exception_record,void * registration,struct _CONTEXT * context,void * dispatcher)483c5b5288cSThomas Huth win32_close_exception_handler(struct _EXCEPTION_RECORD *exception_record,
484c5b5288cSThomas Huth                               void *registration, struct _CONTEXT *context,
485c5b5288cSThomas Huth                               void *dispatcher)
486d89f30b4SMarc-André Lureau {
487d89f30b4SMarc-André Lureau     return EXCEPTION_EXECUTE_HANDLER;
488d89f30b4SMarc-André Lureau }
489d89f30b4SMarc-André Lureau 
49025657fc6SMarc-André Lureau #undef close
qemu_close_socket_osfhandle(int fd)491f3ab43acSMarc-André Lureau int qemu_close_socket_osfhandle(int fd)
492a2d96af4SDaniel P. Berrange {
493f3ab43acSMarc-André Lureau     SOCKET s = _get_osfhandle(fd);
494abe34282SMarc-André Lureau     DWORD flags = 0;
495abe34282SMarc-André Lureau 
496abe34282SMarc-André Lureau     /*
497abe34282SMarc-André Lureau      * If we were to just call _close on the descriptor, it would close the
498abe34282SMarc-André Lureau      * HANDLE, but it wouldn't free any of the resources associated to the
499abe34282SMarc-André Lureau      * SOCKET, and we can't call _close after calling closesocket, because
500abe34282SMarc-André Lureau      * closesocket has already closed the HANDLE, and _close would attempt to
501abe34282SMarc-André Lureau      * close the HANDLE again, resulting in a double free. We can however
502abe34282SMarc-André Lureau      * protect the HANDLE from actually being closed long enough to close the
503abe34282SMarc-André Lureau      * file descriptor, then close the socket itself.
504abe34282SMarc-André Lureau      */
505abe34282SMarc-André Lureau     if (!GetHandleInformation((HANDLE)s, &flags)) {
506abe34282SMarc-André Lureau         errno = EACCES;
507abe34282SMarc-André Lureau         return -1;
508abe34282SMarc-André Lureau     }
509abe34282SMarc-André Lureau 
510abe34282SMarc-André Lureau     if (!SetHandleInformation((HANDLE)s, HANDLE_FLAG_PROTECT_FROM_CLOSE, HANDLE_FLAG_PROTECT_FROM_CLOSE)) {
511abe34282SMarc-André Lureau         errno = EACCES;
512abe34282SMarc-André Lureau         return -1;
513abe34282SMarc-André Lureau     }
514abe34282SMarc-André Lureau 
515d89f30b4SMarc-André Lureau     __try1(win32_close_exception_handler) {
516abe34282SMarc-André Lureau         /*
517d89f30b4SMarc-André Lureau          * close() returns EBADF since we PROTECT_FROM_CLOSE the underlying
518d89f30b4SMarc-André Lureau          * handle, but the FD is actually freed
519abe34282SMarc-André Lureau          */
520f3ab43acSMarc-André Lureau         if (close(fd) < 0 && errno != EBADF) {
521f3ab43acSMarc-André Lureau             return -1;
522abe34282SMarc-André Lureau         }
523d89f30b4SMarc-André Lureau     }
524d89f30b4SMarc-André Lureau     __except1 {
525d89f30b4SMarc-André Lureau     }
526abe34282SMarc-André Lureau 
527f3ab43acSMarc-André Lureau     if (!SetHandleInformation((HANDLE)s, flags, flags)) {
528f3ab43acSMarc-André Lureau         errno = EACCES;
529f3ab43acSMarc-André Lureau         return -1;
530f3ab43acSMarc-André Lureau     }
531f3ab43acSMarc-André Lureau 
532f3ab43acSMarc-André Lureau     return 0;
533f3ab43acSMarc-André Lureau }
534f3ab43acSMarc-André Lureau 
qemu_close_wrap(int fd)535f3ab43acSMarc-André Lureau int qemu_close_wrap(int fd)
536f3ab43acSMarc-André Lureau {
537f3ab43acSMarc-André Lureau     SOCKET s = INVALID_SOCKET;
538f3ab43acSMarc-André Lureau     int ret = -1;
539f3ab43acSMarc-André Lureau 
540f3ab43acSMarc-André Lureau     if (!fd_is_socket(fd)) {
541f3ab43acSMarc-André Lureau         return close(fd);
542f3ab43acSMarc-André Lureau     }
543f3ab43acSMarc-André Lureau 
544f3ab43acSMarc-André Lureau     s = _get_osfhandle(fd);
545f3ab43acSMarc-André Lureau     qemu_close_socket_osfhandle(fd);
546f3ab43acSMarc-André Lureau 
547abe34282SMarc-André Lureau     ret = closesocket(s);
548abe34282SMarc-André Lureau     if (ret < 0) {
549abe34282SMarc-André Lureau         errno = socket_error();
550abe34282SMarc-André Lureau     }
551abe34282SMarc-André Lureau 
552abe34282SMarc-André Lureau     return ret;
553abe34282SMarc-André Lureau }
554abe34282SMarc-André Lureau 
555abe34282SMarc-André Lureau 
556abe34282SMarc-André Lureau #undef socket
qemu_socket_wrap(int domain,int type,int protocol)557abe34282SMarc-André Lureau int qemu_socket_wrap(int domain, int type, int protocol)
558abe34282SMarc-André Lureau {
559abe34282SMarc-André Lureau     SOCKET s;
560abe34282SMarc-André Lureau     int fd;
561abe34282SMarc-André Lureau 
562abe34282SMarc-André Lureau     s = socket(domain, type, protocol);
563abe34282SMarc-André Lureau     if (s == -1) {
564abe34282SMarc-André Lureau         errno = socket_error();
565abe34282SMarc-André Lureau         return -1;
566abe34282SMarc-André Lureau     }
567abe34282SMarc-André Lureau 
568abe34282SMarc-André Lureau     fd = _open_osfhandle(s, _O_BINARY);
569abe34282SMarc-André Lureau     if (fd < 0) {
570abe34282SMarc-André Lureau         closesocket(s);
571abe34282SMarc-André Lureau         /* _open_osfhandle may not set errno, and closesocket() may override it */
572abe34282SMarc-André Lureau         errno = ENOMEM;
573abe34282SMarc-André Lureau     }
574abe34282SMarc-André Lureau 
575abe34282SMarc-André Lureau     return fd;
576abe34282SMarc-André Lureau }
577abe34282SMarc-André Lureau 
578abe34282SMarc-André Lureau 
579abe34282SMarc-André Lureau #undef accept
qemu_accept_wrap(int sockfd,struct sockaddr * addr,socklen_t * addrlen)580abe34282SMarc-André Lureau int qemu_accept_wrap(int sockfd, struct sockaddr *addr,
581abe34282SMarc-André Lureau                      socklen_t *addrlen)
582abe34282SMarc-André Lureau {
583abe34282SMarc-André Lureau     int fd;
584abe34282SMarc-André Lureau     SOCKET s = _get_osfhandle(sockfd);
585abe34282SMarc-André Lureau 
586abe34282SMarc-André Lureau     if (s == INVALID_SOCKET) {
587abe34282SMarc-André Lureau         return -1;
588abe34282SMarc-André Lureau     }
589abe34282SMarc-André Lureau 
590abe34282SMarc-André Lureau     s = accept(s, addr, addrlen);
591abe34282SMarc-André Lureau     if (s == -1) {
592abe34282SMarc-André Lureau         errno = socket_error();
593abe34282SMarc-André Lureau         return -1;
594abe34282SMarc-André Lureau     }
595abe34282SMarc-André Lureau 
596abe34282SMarc-André Lureau     fd = _open_osfhandle(s, _O_BINARY);
597abe34282SMarc-André Lureau     if (fd < 0) {
598abe34282SMarc-André Lureau         closesocket(s);
599abe34282SMarc-André Lureau         /* _open_osfhandle may not set errno, and closesocket() may override it */
600abe34282SMarc-André Lureau         errno = ENOMEM;
601abe34282SMarc-André Lureau     }
602abe34282SMarc-André Lureau 
603abe34282SMarc-André Lureau     return fd;
604abe34282SMarc-André Lureau }
605abe34282SMarc-André Lureau 
606abe34282SMarc-André Lureau 
607abe34282SMarc-André Lureau #undef shutdown
qemu_shutdown_wrap(int sockfd,int how)608abe34282SMarc-André Lureau int qemu_shutdown_wrap(int sockfd, int how)
609abe34282SMarc-André Lureau {
610abe34282SMarc-André Lureau     int ret;
611abe34282SMarc-André Lureau     SOCKET s = _get_osfhandle(sockfd);
612abe34282SMarc-André Lureau 
613abe34282SMarc-André Lureau     if (s == INVALID_SOCKET) {
614abe34282SMarc-André Lureau         return -1;
615abe34282SMarc-André Lureau     }
616abe34282SMarc-André Lureau 
617abe34282SMarc-André Lureau     ret = shutdown(s, how);
618abe34282SMarc-André Lureau     if (ret < 0) {
619abe34282SMarc-André Lureau         errno = socket_error();
620abe34282SMarc-André Lureau     }
621abe34282SMarc-André Lureau     return ret;
622abe34282SMarc-André Lureau }
623abe34282SMarc-André Lureau 
624abe34282SMarc-André Lureau 
625abe34282SMarc-André Lureau #undef ioctlsocket
qemu_ioctlsocket_wrap(int fd,int req,void * val)626abe34282SMarc-André Lureau int qemu_ioctlsocket_wrap(int fd, int req, void *val)
627abe34282SMarc-André Lureau {
628abe34282SMarc-André Lureau     int ret;
629abe34282SMarc-André Lureau     SOCKET s = _get_osfhandle(fd);
630abe34282SMarc-André Lureau 
631abe34282SMarc-André Lureau     if (s == INVALID_SOCKET) {
632abe34282SMarc-André Lureau         return -1;
633abe34282SMarc-André Lureau     }
634abe34282SMarc-André Lureau 
635abe34282SMarc-André Lureau     ret = ioctlsocket(s, req, val);
636a2d96af4SDaniel P. Berrange     if (ret < 0) {
637a2d96af4SDaniel P. Berrange         errno = socket_error();
638a2d96af4SDaniel P. Berrange     }
639a2d96af4SDaniel P. Berrange     return ret;
640a2d96af4SDaniel P. Berrange }
641a2d96af4SDaniel P. Berrange 
642a2d96af4SDaniel P. Berrange 
643a2d96af4SDaniel P. Berrange #undef getsockopt
qemu_getsockopt_wrap(int sockfd,int level,int optname,void * optval,socklen_t * optlen)644a2d96af4SDaniel P. Berrange int qemu_getsockopt_wrap(int sockfd, int level, int optname,
645a2d96af4SDaniel P. Berrange                          void *optval, socklen_t *optlen)
646a2d96af4SDaniel P. Berrange {
647a2d96af4SDaniel P. Berrange     int ret;
648abe34282SMarc-André Lureau     SOCKET s = _get_osfhandle(sockfd);
649abe34282SMarc-André Lureau 
650abe34282SMarc-André Lureau     if (s == INVALID_SOCKET) {
651abe34282SMarc-André Lureau         return -1;
652abe34282SMarc-André Lureau     }
653abe34282SMarc-André Lureau 
654abe34282SMarc-André Lureau     ret = getsockopt(s, level, optname, optval, optlen);
655a2d96af4SDaniel P. Berrange     if (ret < 0) {
656a2d96af4SDaniel P. Berrange         errno = socket_error();
657a2d96af4SDaniel P. Berrange     }
658a2d96af4SDaniel P. Berrange     return ret;
659a2d96af4SDaniel P. Berrange }
660a2d96af4SDaniel P. Berrange 
661a2d96af4SDaniel P. Berrange 
662a2d96af4SDaniel P. Berrange #undef setsockopt
qemu_setsockopt_wrap(int sockfd,int level,int optname,const void * optval,socklen_t optlen)663a2d96af4SDaniel P. Berrange int qemu_setsockopt_wrap(int sockfd, int level, int optname,
664a2d96af4SDaniel P. Berrange                          const void *optval, socklen_t optlen)
665a2d96af4SDaniel P. Berrange {
666a2d96af4SDaniel P. Berrange     int ret;
667abe34282SMarc-André Lureau     SOCKET s = _get_osfhandle(sockfd);
668abe34282SMarc-André Lureau 
669abe34282SMarc-André Lureau     if (s == INVALID_SOCKET) {
670abe34282SMarc-André Lureau         return -1;
671abe34282SMarc-André Lureau     }
672abe34282SMarc-André Lureau 
673abe34282SMarc-André Lureau     ret = setsockopt(s, level, optname, optval, optlen);
674a2d96af4SDaniel P. Berrange     if (ret < 0) {
675a2d96af4SDaniel P. Berrange         errno = socket_error();
676a2d96af4SDaniel P. Berrange     }
677a2d96af4SDaniel P. Berrange     return ret;
678a2d96af4SDaniel P. Berrange }
679a2d96af4SDaniel P. Berrange 
680a2d96af4SDaniel P. Berrange 
681a2d96af4SDaniel P. Berrange #undef getpeername
qemu_getpeername_wrap(int sockfd,struct sockaddr * addr,socklen_t * addrlen)682a2d96af4SDaniel P. Berrange int qemu_getpeername_wrap(int sockfd, struct sockaddr *addr,
683a2d96af4SDaniel P. Berrange                           socklen_t *addrlen)
684a2d96af4SDaniel P. Berrange {
685a2d96af4SDaniel P. Berrange     int ret;
686abe34282SMarc-André Lureau     SOCKET s = _get_osfhandle(sockfd);
687abe34282SMarc-André Lureau 
688abe34282SMarc-André Lureau     if (s == INVALID_SOCKET) {
689abe34282SMarc-André Lureau         return -1;
690abe34282SMarc-André Lureau     }
691abe34282SMarc-André Lureau 
692abe34282SMarc-André Lureau     ret = getpeername(s, addr, addrlen);
693a2d96af4SDaniel P. Berrange     if (ret < 0) {
694a2d96af4SDaniel P. Berrange         errno = socket_error();
695a2d96af4SDaniel P. Berrange     }
696a2d96af4SDaniel P. Berrange     return ret;
697a2d96af4SDaniel P. Berrange }
698a2d96af4SDaniel P. Berrange 
699a2d96af4SDaniel P. Berrange 
700a2d96af4SDaniel P. Berrange #undef getsockname
qemu_getsockname_wrap(int sockfd,struct sockaddr * addr,socklen_t * addrlen)701a2d96af4SDaniel P. Berrange int qemu_getsockname_wrap(int sockfd, struct sockaddr *addr,
702a2d96af4SDaniel P. Berrange                           socklen_t *addrlen)
703a2d96af4SDaniel P. Berrange {
704a2d96af4SDaniel P. Berrange     int ret;
705abe34282SMarc-André Lureau     SOCKET s = _get_osfhandle(sockfd);
706abe34282SMarc-André Lureau 
707abe34282SMarc-André Lureau     if (s == INVALID_SOCKET) {
708abe34282SMarc-André Lureau         return -1;
709abe34282SMarc-André Lureau     }
710abe34282SMarc-André Lureau 
711abe34282SMarc-André Lureau     ret = getsockname(s, addr, addrlen);
712a2d96af4SDaniel P. Berrange     if (ret < 0) {
713a2d96af4SDaniel P. Berrange         errno = socket_error();
714a2d96af4SDaniel P. Berrange     }
715a2d96af4SDaniel P. Berrange     return ret;
716a2d96af4SDaniel P. Berrange }
717a2d96af4SDaniel P. Berrange 
718a2d96af4SDaniel P. Berrange 
719a2d96af4SDaniel P. Berrange #undef send
qemu_send_wrap(int sockfd,const void * buf,size_t len,int flags)720a2d96af4SDaniel P. Berrange ssize_t qemu_send_wrap(int sockfd, const void *buf, size_t len, int flags)
721a2d96af4SDaniel P. Berrange {
722a2d96af4SDaniel P. Berrange     int ret;
723abe34282SMarc-André Lureau     SOCKET s = _get_osfhandle(sockfd);
724abe34282SMarc-André Lureau 
725abe34282SMarc-André Lureau     if (s == INVALID_SOCKET) {
726abe34282SMarc-André Lureau         return -1;
727abe34282SMarc-André Lureau     }
728abe34282SMarc-André Lureau 
729abe34282SMarc-André Lureau     ret = send(s, buf, len, flags);
730a2d96af4SDaniel P. Berrange     if (ret < 0) {
731a2d96af4SDaniel P. Berrange         errno = socket_error();
732a2d96af4SDaniel P. Berrange     }
733a2d96af4SDaniel P. Berrange     return ret;
734a2d96af4SDaniel P. Berrange }
735a2d96af4SDaniel P. Berrange 
736a2d96af4SDaniel P. Berrange 
737a2d96af4SDaniel P. Berrange #undef sendto
qemu_sendto_wrap(int sockfd,const void * buf,size_t len,int flags,const struct sockaddr * addr,socklen_t addrlen)738a2d96af4SDaniel P. Berrange ssize_t qemu_sendto_wrap(int sockfd, const void *buf, size_t len, int flags,
739a2d96af4SDaniel P. Berrange                          const struct sockaddr *addr, socklen_t addrlen)
740a2d96af4SDaniel P. Berrange {
741a2d96af4SDaniel P. Berrange     int ret;
742abe34282SMarc-André Lureau     SOCKET s = _get_osfhandle(sockfd);
743abe34282SMarc-André Lureau 
744abe34282SMarc-André Lureau     if (s == INVALID_SOCKET) {
745abe34282SMarc-André Lureau         return -1;
746abe34282SMarc-André Lureau     }
747abe34282SMarc-André Lureau 
748abe34282SMarc-André Lureau     ret = sendto(s, buf, len, flags, addr, addrlen);
749a2d96af4SDaniel P. Berrange     if (ret < 0) {
750a2d96af4SDaniel P. Berrange         errno = socket_error();
751a2d96af4SDaniel P. Berrange     }
752a2d96af4SDaniel P. Berrange     return ret;
753a2d96af4SDaniel P. Berrange }
754a2d96af4SDaniel P. Berrange 
755a2d96af4SDaniel P. Berrange 
756a2d96af4SDaniel P. Berrange #undef recv
qemu_recv_wrap(int sockfd,void * buf,size_t len,int flags)757a2d96af4SDaniel P. Berrange ssize_t qemu_recv_wrap(int sockfd, void *buf, size_t len, int flags)
758a2d96af4SDaniel P. Berrange {
759a2d96af4SDaniel P. Berrange     int ret;
760abe34282SMarc-André Lureau     SOCKET s = _get_osfhandle(sockfd);
761abe34282SMarc-André Lureau 
762abe34282SMarc-André Lureau     if (s == INVALID_SOCKET) {
763abe34282SMarc-André Lureau         return -1;
764abe34282SMarc-André Lureau     }
765abe34282SMarc-André Lureau 
766abe34282SMarc-André Lureau     ret = recv(s, buf, len, flags);
767a2d96af4SDaniel P. Berrange     if (ret < 0) {
768a2d96af4SDaniel P. Berrange         errno = socket_error();
769a2d96af4SDaniel P. Berrange     }
770a2d96af4SDaniel P. Berrange     return ret;
771a2d96af4SDaniel P. Berrange }
772a2d96af4SDaniel P. Berrange 
773a2d96af4SDaniel P. Berrange 
774a2d96af4SDaniel P. Berrange #undef recvfrom
qemu_recvfrom_wrap(int sockfd,void * buf,size_t len,int flags,struct sockaddr * addr,socklen_t * addrlen)775a2d96af4SDaniel P. Berrange ssize_t qemu_recvfrom_wrap(int sockfd, void *buf, size_t len, int flags,
776a2d96af4SDaniel P. Berrange                            struct sockaddr *addr, socklen_t *addrlen)
777a2d96af4SDaniel P. Berrange {
778a2d96af4SDaniel P. Berrange     int ret;
779abe34282SMarc-André Lureau     SOCKET s = _get_osfhandle(sockfd);
780abe34282SMarc-André Lureau 
781abe34282SMarc-André Lureau     if (s == INVALID_SOCKET) {
782abe34282SMarc-André Lureau         return -1;
783abe34282SMarc-André Lureau     }
784abe34282SMarc-André Lureau 
785abe34282SMarc-André Lureau     ret = recvfrom(s, buf, len, flags, addr, addrlen);
786a2d96af4SDaniel P. Berrange     if (ret < 0) {
787a2d96af4SDaniel P. Berrange         errno = socket_error();
788a2d96af4SDaniel P. Berrange     }
789a2d96af4SDaniel P. Berrange     return ret;
790a2d96af4SDaniel P. Berrange }
7919e6bdef2SMarc-André Lureau 
qemu_write_pidfile(const char * filename,Error ** errp)7929e6bdef2SMarc-André Lureau bool qemu_write_pidfile(const char *filename, Error **errp)
7939e6bdef2SMarc-André Lureau {
7949e6bdef2SMarc-André Lureau     char buffer[128];
7959e6bdef2SMarc-André Lureau     int len;
7969e6bdef2SMarc-André Lureau     HANDLE file;
7979e6bdef2SMarc-André Lureau     OVERLAPPED overlap;
7989e6bdef2SMarc-André Lureau     BOOL ret;
7999e6bdef2SMarc-André Lureau     memset(&overlap, 0, sizeof(overlap));
8009e6bdef2SMarc-André Lureau 
8019e6bdef2SMarc-André Lureau     file = CreateFile(filename, GENERIC_WRITE, FILE_SHARE_READ, NULL,
8029e6bdef2SMarc-André Lureau                       OPEN_ALWAYS, FILE_ATTRIBUTE_NORMAL, NULL);
8039e6bdef2SMarc-André Lureau 
8049e6bdef2SMarc-André Lureau     if (file == INVALID_HANDLE_VALUE) {
8059e6bdef2SMarc-André Lureau         error_setg(errp, "Failed to create PID file");
8069e6bdef2SMarc-André Lureau         return false;
8079e6bdef2SMarc-André Lureau     }
8089e6bdef2SMarc-André Lureau     len = snprintf(buffer, sizeof(buffer), FMT_pid "\n", (pid_t)getpid());
8099e6bdef2SMarc-André Lureau     ret = WriteFile(file, (LPCVOID)buffer, (DWORD)len,
8109e6bdef2SMarc-André Lureau                     NULL, &overlap);
8119e6bdef2SMarc-André Lureau     CloseHandle(file);
8129e6bdef2SMarc-André Lureau     if (ret == 0) {
8139e6bdef2SMarc-André Lureau         error_setg(errp, "Failed to write PID file");
8149e6bdef2SMarc-André Lureau         return false;
8159e6bdef2SMarc-André Lureau     }
8169e6bdef2SMarc-André Lureau     return true;
8179e6bdef2SMarc-André Lureau }
818e47f4765SMichal Privoznik 
qemu_get_host_physmem(void)819ad06ef0eSAlex Bennée size_t qemu_get_host_physmem(void)
820ad06ef0eSAlex Bennée {
821986babaaSAlex Bennée     MEMORYSTATUSEX statex;
822986babaaSAlex Bennée     statex.dwLength = sizeof(statex);
823986babaaSAlex Bennée 
824986babaaSAlex Bennée     if (GlobalMemoryStatusEx(&statex)) {
825986babaaSAlex Bennée         return statex.ullTotalPhys;
826986babaaSAlex Bennée     }
827ad06ef0eSAlex Bennée     return 0;
828ad06ef0eSAlex Bennée }
82973991a92SMarc-André Lureau 
qemu_msync(void * addr,size_t length,int fd)83073991a92SMarc-André Lureau int qemu_msync(void *addr, size_t length, int fd)
83173991a92SMarc-André Lureau {
83273991a92SMarc-André Lureau     /**
83373991a92SMarc-André Lureau      * Perform the sync based on the file descriptor
83473991a92SMarc-André Lureau      * The sync range will most probably be wider than the one
83573991a92SMarc-André Lureau      * requested - but it will still get the job done
83673991a92SMarc-André Lureau      */
83773991a92SMarc-André Lureau     return qemu_fdatasync(fd);
83873991a92SMarc-André Lureau }
83909b4c198SMarc-André Lureau 
qemu_win32_map_alloc(size_t size,HANDLE * h,Error ** errp)84009b4c198SMarc-André Lureau void *qemu_win32_map_alloc(size_t size, HANDLE *h, Error **errp)
84109b4c198SMarc-André Lureau {
84209b4c198SMarc-André Lureau     void *bits;
84309b4c198SMarc-André Lureau 
84409b4c198SMarc-André Lureau     trace_win32_map_alloc(size);
84509b4c198SMarc-André Lureau 
84609b4c198SMarc-André Lureau     *h = CreateFileMapping(INVALID_HANDLE_VALUE, NULL, PAGE_READWRITE, 0,
84709b4c198SMarc-André Lureau                           size, NULL);
84809b4c198SMarc-André Lureau     if (*h == NULL) {
84909b4c198SMarc-André Lureau         error_setg_win32(errp, GetLastError(), "Failed to CreateFileMapping");
85009b4c198SMarc-André Lureau         return NULL;
85109b4c198SMarc-André Lureau     }
85209b4c198SMarc-André Lureau 
85309b4c198SMarc-André Lureau     bits = MapViewOfFile(*h, FILE_MAP_ALL_ACCESS, 0, 0, size);
85409b4c198SMarc-André Lureau     if (bits == NULL) {
85509b4c198SMarc-André Lureau         error_setg_win32(errp, GetLastError(), "Failed to MapViewOfFile");
85609b4c198SMarc-André Lureau         CloseHandle(*h);
85709b4c198SMarc-André Lureau         return NULL;
85809b4c198SMarc-André Lureau     }
85909b4c198SMarc-André Lureau 
86009b4c198SMarc-André Lureau     return bits;
86109b4c198SMarc-André Lureau }
86209b4c198SMarc-André Lureau 
qemu_win32_map_free(void * ptr,HANDLE h,Error ** errp)86309b4c198SMarc-André Lureau void qemu_win32_map_free(void *ptr, HANDLE h, Error **errp)
86409b4c198SMarc-André Lureau {
86509b4c198SMarc-André Lureau     trace_win32_map_free(ptr, h);
86609b4c198SMarc-André Lureau 
86709b4c198SMarc-André Lureau     if (UnmapViewOfFile(ptr) == 0) {
86809b4c198SMarc-André Lureau         error_setg_win32(errp, GetLastError(), "Failed to UnmapViewOfFile");
86909b4c198SMarc-André Lureau     }
87009b4c198SMarc-André Lureau     CloseHandle(h);
87109b4c198SMarc-André Lureau }
872