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