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