xref: /qemu/util/oslib-win32.c (revision 9736ee382e95ead06a838fe0b0498e0cb3845270)
1  /*
2   * os-win32.c
3   *
4   * Copyright (c) 2003-2008 Fabrice Bellard
5   * Copyright (c) 2010-2016 Red Hat, Inc.
6   *
7   * QEMU library functions for win32 which are shared between QEMU and
8   * the QEMU tools.
9   *
10   * Permission is hereby granted, free of charge, to any person obtaining a copy
11   * of this software and associated documentation files (the "Software"), to deal
12   * in the Software without restriction, including without limitation the rights
13   * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
14   * copies of the Software, and to permit persons to whom the Software is
15   * furnished to do so, subject to the following conditions:
16   *
17   * The above copyright notice and this permission notice shall be included in
18   * all copies or substantial portions of the Software.
19   *
20   * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
21   * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
22   * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
23   * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
24   * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
25   * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
26   * THE SOFTWARE.
27   */
28  
29  #include "qemu/osdep.h"
30  #include <windows.h>
31  #include "qapi/error.h"
32  #include "qemu/main-loop.h"
33  #include "trace.h"
34  #include "qemu/sockets.h"
35  #include "qemu/cutils.h"
36  #include "qemu/error-report.h"
37  #include <malloc.h>
38  
get_allocation_granularity(void)39  static int get_allocation_granularity(void)
40  {
41      SYSTEM_INFO system_info;
42  
43      GetSystemInfo(&system_info);
44      return system_info.dwAllocationGranularity;
45  }
46  
qemu_anon_ram_alloc(size_t size,uint64_t * align,bool shared,bool noreserve)47  void *qemu_anon_ram_alloc(size_t size, uint64_t *align, bool shared,
48                            bool noreserve)
49  {
50      void *ptr;
51  
52      if (noreserve) {
53          /*
54           * We need a MEM_COMMIT before accessing any memory in a MEM_RESERVE
55           * area; we cannot easily mimic POSIX MAP_NORESERVE semantics.
56           */
57          error_report("Skipping reservation of swap space is not supported.");
58          return NULL;
59      }
60  
61      ptr = VirtualAlloc(NULL, size, MEM_COMMIT, PAGE_READWRITE);
62      trace_qemu_anon_ram_alloc(size, ptr);
63  
64      if (ptr && align) {
65          *align = MAX(get_allocation_granularity(), getpagesize());
66      }
67      return ptr;
68  }
69  
qemu_anon_ram_free(void * ptr,size_t size)70  void qemu_anon_ram_free(void *ptr, size_t size)
71  {
72      trace_qemu_anon_ram_free(ptr, size);
73      if (ptr) {
74          VirtualFree(ptr, 0, MEM_RELEASE);
75      }
76  }
77  
78  #ifndef _POSIX_THREAD_SAFE_FUNCTIONS
79  /* FIXME: add proper locking */
gmtime_r(const time_t * timep,struct tm * result)80  struct tm *gmtime_r(const time_t *timep, struct tm *result)
81  {
82      struct tm *p = gmtime(timep);
83      memset(result, 0, sizeof(*result));
84      if (p) {
85          *result = *p;
86          p = result;
87      }
88      return p;
89  }
90  
91  /* FIXME: add proper locking */
localtime_r(const time_t * timep,struct tm * result)92  struct tm *localtime_r(const time_t *timep, struct tm *result)
93  {
94      struct tm *p = localtime(timep);
95      memset(result, 0, sizeof(*result));
96      if (p) {
97          *result = *p;
98          p = result;
99      }
100      return p;
101  }
102  #endif /* _POSIX_THREAD_SAFE_FUNCTIONS */
103  
socket_error(void)104  static int socket_error(void)
105  {
106      switch (WSAGetLastError()) {
107      case 0:
108          return 0;
109      case WSAEINTR:
110          return EINTR;
111      case WSAEINVAL:
112          return EINVAL;
113      case WSA_INVALID_HANDLE:
114          return EBADF;
115      case WSA_NOT_ENOUGH_MEMORY:
116          return ENOMEM;
117      case WSA_INVALID_PARAMETER:
118          return EINVAL;
119      case WSAENAMETOOLONG:
120          return ENAMETOOLONG;
121      case WSAENOTEMPTY:
122          return ENOTEMPTY;
123      case WSAEWOULDBLOCK:
124           /* not using EWOULDBLOCK as we don't want code to have
125            * to check both EWOULDBLOCK and EAGAIN */
126          return EAGAIN;
127      case WSAEINPROGRESS:
128          return EINPROGRESS;
129      case WSAEALREADY:
130          return EALREADY;
131      case WSAENOTSOCK:
132          return ENOTSOCK;
133      case WSAEDESTADDRREQ:
134          return EDESTADDRREQ;
135      case WSAEMSGSIZE:
136          return EMSGSIZE;
137      case WSAEPROTOTYPE:
138          return EPROTOTYPE;
139      case WSAENOPROTOOPT:
140          return ENOPROTOOPT;
141      case WSAEPROTONOSUPPORT:
142          return EPROTONOSUPPORT;
143      case WSAEOPNOTSUPP:
144          return EOPNOTSUPP;
145      case WSAEAFNOSUPPORT:
146          return EAFNOSUPPORT;
147      case WSAEADDRINUSE:
148          return EADDRINUSE;
149      case WSAEADDRNOTAVAIL:
150          return EADDRNOTAVAIL;
151      case WSAENETDOWN:
152          return ENETDOWN;
153      case WSAENETUNREACH:
154          return ENETUNREACH;
155      case WSAENETRESET:
156          return ENETRESET;
157      case WSAECONNABORTED:
158          return ECONNABORTED;
159      case WSAECONNRESET:
160          return ECONNRESET;
161      case WSAENOBUFS:
162          return ENOBUFS;
163      case WSAEISCONN:
164          return EISCONN;
165      case WSAENOTCONN:
166          return ENOTCONN;
167      case WSAETIMEDOUT:
168          return ETIMEDOUT;
169      case WSAECONNREFUSED:
170          return ECONNREFUSED;
171      case WSAELOOP:
172          return ELOOP;
173      case WSAEHOSTUNREACH:
174          return EHOSTUNREACH;
175      default:
176          return EIO;
177      }
178  }
179  
qemu_socket_set_block(int fd)180  void qemu_socket_set_block(int fd)
181  {
182      unsigned long opt = 0;
183      qemu_socket_unselect(fd, NULL);
184      ioctlsocket(fd, FIONBIO, &opt);
185  }
186  
qemu_socket_try_set_nonblock(int fd)187  int qemu_socket_try_set_nonblock(int fd)
188  {
189      unsigned long opt = 1;
190      if (ioctlsocket(fd, FIONBIO, &opt) != NO_ERROR) {
191          return -socket_error();
192      }
193      return 0;
194  }
195  
qemu_socket_set_nonblock(int fd)196  void qemu_socket_set_nonblock(int fd)
197  {
198      (void)qemu_socket_try_set_nonblock(fd);
199  }
200  
socket_set_fast_reuse(int fd)201  int socket_set_fast_reuse(int fd)
202  {
203      /* Enabling the reuse of an endpoint that was used by a socket still in
204       * TIME_WAIT state is usually performed by setting SO_REUSEADDR. On Windows
205       * fast reuse is the default and SO_REUSEADDR does strange things. So we
206       * don't have to do anything here. More info can be found at:
207       * http://msdn.microsoft.com/en-us/library/windows/desktop/ms740621.aspx */
208      return 0;
209  }
210  
inet_aton(const char * cp,struct in_addr * ia)211  int inet_aton(const char *cp, struct in_addr *ia)
212  {
213      uint32_t addr = inet_addr(cp);
214      if (addr == 0xffffffff) {
215          return 0;
216      }
217      ia->s_addr = addr;
218      return 1;
219  }
220  
qemu_set_cloexec(int fd)221  void qemu_set_cloexec(int fd)
222  {
223  }
224  
qemu_get_thread_id(void)225  int qemu_get_thread_id(void)
226  {
227      return GetCurrentThreadId();
228  }
229  
230  char *
qemu_get_local_state_dir(void)231  qemu_get_local_state_dir(void)
232  {
233      const char * const *data_dirs = g_get_system_data_dirs();
234  
235      g_assert(data_dirs && data_dirs[0]);
236  
237      return g_strdup(data_dirs[0]);
238  }
239  
qemu_set_tty_echo(int fd,bool echo)240  void qemu_set_tty_echo(int fd, bool echo)
241  {
242      HANDLE handle = (HANDLE)_get_osfhandle(fd);
243      DWORD dwMode = 0;
244  
245      if (handle == INVALID_HANDLE_VALUE) {
246          return;
247      }
248  
249      GetConsoleMode(handle, &dwMode);
250  
251      if (echo) {
252          SetConsoleMode(handle, dwMode | ENABLE_ECHO_INPUT | ENABLE_LINE_INPUT);
253      } else {
254          SetConsoleMode(handle,
255                         dwMode & ~(ENABLE_ECHO_INPUT | ENABLE_LINE_INPUT));
256      }
257  }
258  
getpagesize(void)259  int getpagesize(void)
260  {
261      SYSTEM_INFO system_info;
262  
263      GetSystemInfo(&system_info);
264      return system_info.dwPageSize;
265  }
266  
qemu_prealloc_mem(int fd,char * area,size_t sz,int max_threads,ThreadContext * tc,bool async,Error ** errp)267  bool qemu_prealloc_mem(int fd, char *area, size_t sz, int max_threads,
268                         ThreadContext *tc, bool async, Error **errp)
269  {
270      int i;
271      size_t pagesize = qemu_real_host_page_size();
272  
273      sz = (sz + pagesize - 1) & -pagesize;
274      for (i = 0; i < sz / pagesize; i++) {
275          memset(area + pagesize * i, 0, 1);
276      }
277  
278      return true;
279  }
280  
qemu_finish_async_prealloc_mem(Error ** errp)281  bool qemu_finish_async_prealloc_mem(Error **errp)
282  {
283      /* async prealloc not supported, there is nothing to finish */
284      return true;
285  }
286  
qemu_get_pid_name(pid_t pid)287  char *qemu_get_pid_name(pid_t pid)
288  {
289      /* XXX Implement me */
290      abort();
291  }
292  
293  
qemu_socket_select(int sockfd,WSAEVENT hEventObject,long lNetworkEvents,Error ** errp)294  bool qemu_socket_select(int sockfd, WSAEVENT hEventObject,
295                          long lNetworkEvents, Error **errp)
296  {
297      SOCKET s = _get_osfhandle(sockfd);
298  
299      if (errp == NULL) {
300          errp = &error_warn;
301      }
302  
303      if (s == INVALID_SOCKET) {
304          error_setg(errp, "invalid socket fd=%d", sockfd);
305          return false;
306      }
307  
308      if (WSAEventSelect(s, hEventObject, lNetworkEvents) != 0) {
309          error_setg_win32(errp, WSAGetLastError(), "failed to WSAEventSelect()");
310          return false;
311      }
312  
313      return true;
314  }
315  
qemu_socket_unselect(int sockfd,Error ** errp)316  bool qemu_socket_unselect(int sockfd, Error **errp)
317  {
318      return qemu_socket_select(sockfd, NULL, 0, errp);
319  }
320  
qemu_socketpair(int domain,int type,int protocol,int sv[2])321  int qemu_socketpair(int domain, int type, int protocol, int sv[2])
322  {
323      struct sockaddr_un addr = {
324          0,
325      };
326      socklen_t socklen;
327      int listener = -1;
328      int client = -1;
329      int server = -1;
330      g_autofree char *path = NULL;
331      int tmpfd;
332      u_long arg;
333      int ret = -1;
334  
335      g_return_val_if_fail(sv != NULL, -1);
336  
337      addr.sun_family = AF_UNIX;
338      socklen = sizeof(addr);
339  
340      tmpfd = g_file_open_tmp(NULL, &path, NULL);
341      if (tmpfd == -1 || !path) {
342          errno = EACCES;
343          goto out;
344      }
345  
346      close(tmpfd);
347  
348      if (strlen(path) >= sizeof(addr.sun_path)) {
349          errno = EINVAL;
350          goto out;
351      }
352  
353      strncpy(addr.sun_path, path, sizeof(addr.sun_path) - 1);
354  
355      listener = socket(domain, type, protocol);
356      if (listener == -1) {
357          goto out;
358      }
359  
360      if (DeleteFile(path) == 0 && GetLastError() != ERROR_FILE_NOT_FOUND) {
361          errno = EACCES;
362          goto out;
363      }
364      g_clear_pointer(&path, g_free);
365  
366      if (bind(listener, (struct sockaddr *)&addr, socklen) == -1) {
367          goto out;
368      }
369  
370      if (listen(listener, 1) == -1) {
371          goto out;
372      }
373  
374      client = socket(domain, type, protocol);
375      if (client == -1) {
376          goto out;
377      }
378  
379      arg = 1;
380      if (ioctlsocket(client, FIONBIO, &arg) != NO_ERROR) {
381          goto out;
382      }
383  
384      if (connect(client, (struct sockaddr *)&addr, socklen) == -1 &&
385          WSAGetLastError() != WSAEWOULDBLOCK) {
386          goto out;
387      }
388  
389      server = accept(listener, NULL, NULL);
390      if (server == -1) {
391          goto out;
392      }
393  
394      arg = 0;
395      if (ioctlsocket(client, FIONBIO, &arg) != NO_ERROR) {
396          goto out;
397      }
398  
399      arg = 0;
400      if (ioctlsocket(client, SIO_AF_UNIX_GETPEERPID, &arg) != NO_ERROR) {
401          goto out;
402      }
403  
404      if (arg != GetCurrentProcessId()) {
405          errno = EPERM;
406          goto out;
407      }
408  
409      sv[0] = server;
410      server = -1;
411      sv[1] = client;
412      client = -1;
413      ret = 0;
414  
415  out:
416      if (listener != -1) {
417          close(listener);
418      }
419      if (client != -1) {
420          close(client);
421      }
422      if (server != -1) {
423          close(server);
424      }
425      if (path) {
426          DeleteFile(path);
427      }
428      return ret;
429  }
430  
431  #undef connect
qemu_connect_wrap(int sockfd,const struct sockaddr * addr,socklen_t addrlen)432  int qemu_connect_wrap(int sockfd, const struct sockaddr *addr,
433                        socklen_t addrlen)
434  {
435      int ret;
436      SOCKET s = _get_osfhandle(sockfd);
437  
438      if (s == INVALID_SOCKET) {
439          return -1;
440      }
441  
442      ret = connect(s, addr, addrlen);
443      if (ret < 0) {
444          if (WSAGetLastError() == WSAEWOULDBLOCK) {
445              errno = EINPROGRESS;
446          } else {
447              errno = socket_error();
448          }
449      }
450      return ret;
451  }
452  
453  
454  #undef listen
qemu_listen_wrap(int sockfd,int backlog)455  int qemu_listen_wrap(int sockfd, int backlog)
456  {
457      int ret;
458      SOCKET s = _get_osfhandle(sockfd);
459  
460      if (s == INVALID_SOCKET) {
461          return -1;
462      }
463  
464      ret = listen(s, backlog);
465      if (ret < 0) {
466          errno = socket_error();
467      }
468      return ret;
469  }
470  
471  
472  #undef bind
qemu_bind_wrap(int sockfd,const struct sockaddr * addr,socklen_t addrlen)473  int qemu_bind_wrap(int sockfd, const struct sockaddr *addr,
474                     socklen_t addrlen)
475  {
476      int ret;
477      SOCKET s = _get_osfhandle(sockfd);
478  
479      if (s == INVALID_SOCKET) {
480          return -1;
481      }
482  
483      ret = bind(s, addr, addrlen);
484      if (ret < 0) {
485          errno = socket_error();
486      }
487      return ret;
488  }
489  
490  QEMU_USED EXCEPTION_DISPOSITION
win32_close_exception_handler(struct _EXCEPTION_RECORD * exception_record,void * registration,struct _CONTEXT * context,void * dispatcher)491  win32_close_exception_handler(struct _EXCEPTION_RECORD *exception_record,
492                                void *registration, struct _CONTEXT *context,
493                                void *dispatcher)
494  {
495      return EXCEPTION_EXECUTE_HANDLER;
496  }
497  
498  #undef close
qemu_close_socket_osfhandle(int fd)499  int qemu_close_socket_osfhandle(int fd)
500  {
501      SOCKET s = _get_osfhandle(fd);
502      DWORD flags = 0;
503  
504      /*
505       * If we were to just call _close on the descriptor, it would close the
506       * HANDLE, but it wouldn't free any of the resources associated to the
507       * SOCKET, and we can't call _close after calling closesocket, because
508       * closesocket has already closed the HANDLE, and _close would attempt to
509       * close the HANDLE again, resulting in a double free. We can however
510       * protect the HANDLE from actually being closed long enough to close the
511       * file descriptor, then close the socket itself.
512       */
513      if (!GetHandleInformation((HANDLE)s, &flags)) {
514          errno = EACCES;
515          return -1;
516      }
517  
518      if (!SetHandleInformation((HANDLE)s, HANDLE_FLAG_PROTECT_FROM_CLOSE, HANDLE_FLAG_PROTECT_FROM_CLOSE)) {
519          errno = EACCES;
520          return -1;
521      }
522  
523      __try1(win32_close_exception_handler) {
524          /*
525           * close() returns EBADF since we PROTECT_FROM_CLOSE the underlying
526           * handle, but the FD is actually freed
527           */
528          if (close(fd) < 0 && errno != EBADF) {
529              return -1;
530          }
531      }
532      __except1 {
533      }
534  
535      if (!SetHandleInformation((HANDLE)s, flags, flags)) {
536          errno = EACCES;
537          return -1;
538      }
539  
540      return 0;
541  }
542  
qemu_close_wrap(int fd)543  int qemu_close_wrap(int fd)
544  {
545      SOCKET s = INVALID_SOCKET;
546      int ret = -1;
547  
548      if (!fd_is_socket(fd)) {
549          return close(fd);
550      }
551  
552      s = _get_osfhandle(fd);
553      qemu_close_socket_osfhandle(fd);
554  
555      ret = closesocket(s);
556      if (ret < 0) {
557          errno = socket_error();
558      }
559  
560      return ret;
561  }
562  
563  
564  #undef socket
qemu_socket_wrap(int domain,int type,int protocol)565  int qemu_socket_wrap(int domain, int type, int protocol)
566  {
567      SOCKET s;
568      int fd;
569  
570      s = socket(domain, type, protocol);
571      if (s == -1) {
572          errno = socket_error();
573          return -1;
574      }
575  
576      fd = _open_osfhandle(s, _O_BINARY);
577      if (fd < 0) {
578          closesocket(s);
579          /* _open_osfhandle may not set errno, and closesocket() may override it */
580          errno = ENOMEM;
581      }
582  
583      return fd;
584  }
585  
586  
587  #undef accept
qemu_accept_wrap(int sockfd,struct sockaddr * addr,socklen_t * addrlen)588  int qemu_accept_wrap(int sockfd, struct sockaddr *addr,
589                       socklen_t *addrlen)
590  {
591      int fd;
592      SOCKET s = _get_osfhandle(sockfd);
593  
594      if (s == INVALID_SOCKET) {
595          return -1;
596      }
597  
598      s = accept(s, addr, addrlen);
599      if (s == -1) {
600          errno = socket_error();
601          return -1;
602      }
603  
604      fd = _open_osfhandle(s, _O_BINARY);
605      if (fd < 0) {
606          closesocket(s);
607          /* _open_osfhandle may not set errno, and closesocket() may override it */
608          errno = ENOMEM;
609      }
610  
611      return fd;
612  }
613  
614  
615  #undef shutdown
qemu_shutdown_wrap(int sockfd,int how)616  int qemu_shutdown_wrap(int sockfd, int how)
617  {
618      int ret;
619      SOCKET s = _get_osfhandle(sockfd);
620  
621      if (s == INVALID_SOCKET) {
622          return -1;
623      }
624  
625      ret = shutdown(s, how);
626      if (ret < 0) {
627          errno = socket_error();
628      }
629      return ret;
630  }
631  
632  
633  #undef ioctlsocket
qemu_ioctlsocket_wrap(int fd,int req,void * val)634  int qemu_ioctlsocket_wrap(int fd, int req, void *val)
635  {
636      int ret;
637      SOCKET s = _get_osfhandle(fd);
638  
639      if (s == INVALID_SOCKET) {
640          return -1;
641      }
642  
643      ret = ioctlsocket(s, req, val);
644      if (ret < 0) {
645          errno = socket_error();
646      }
647      return ret;
648  }
649  
650  
651  #undef getsockopt
qemu_getsockopt_wrap(int sockfd,int level,int optname,void * optval,socklen_t * optlen)652  int qemu_getsockopt_wrap(int sockfd, int level, int optname,
653                           void *optval, socklen_t *optlen)
654  {
655      int ret;
656      SOCKET s = _get_osfhandle(sockfd);
657  
658      if (s == INVALID_SOCKET) {
659          return -1;
660      }
661  
662      ret = getsockopt(s, level, optname, optval, optlen);
663      if (ret < 0) {
664          errno = socket_error();
665      }
666      return ret;
667  }
668  
669  
670  #undef setsockopt
qemu_setsockopt_wrap(int sockfd,int level,int optname,const void * optval,socklen_t optlen)671  int qemu_setsockopt_wrap(int sockfd, int level, int optname,
672                           const void *optval, socklen_t optlen)
673  {
674      int ret;
675      SOCKET s = _get_osfhandle(sockfd);
676  
677      if (s == INVALID_SOCKET) {
678          return -1;
679      }
680  
681      ret = setsockopt(s, level, optname, optval, optlen);
682      if (ret < 0) {
683          errno = socket_error();
684      }
685      return ret;
686  }
687  
688  
689  #undef getpeername
qemu_getpeername_wrap(int sockfd,struct sockaddr * addr,socklen_t * addrlen)690  int qemu_getpeername_wrap(int sockfd, struct sockaddr *addr,
691                            socklen_t *addrlen)
692  {
693      int ret;
694      SOCKET s = _get_osfhandle(sockfd);
695  
696      if (s == INVALID_SOCKET) {
697          return -1;
698      }
699  
700      ret = getpeername(s, addr, addrlen);
701      if (ret < 0) {
702          errno = socket_error();
703      }
704      return ret;
705  }
706  
707  
708  #undef getsockname
qemu_getsockname_wrap(int sockfd,struct sockaddr * addr,socklen_t * addrlen)709  int qemu_getsockname_wrap(int sockfd, struct sockaddr *addr,
710                            socklen_t *addrlen)
711  {
712      int ret;
713      SOCKET s = _get_osfhandle(sockfd);
714  
715      if (s == INVALID_SOCKET) {
716          return -1;
717      }
718  
719      ret = getsockname(s, addr, addrlen);
720      if (ret < 0) {
721          errno = socket_error();
722      }
723      return ret;
724  }
725  
726  
727  #undef send
qemu_send_wrap(int sockfd,const void * buf,size_t len,int flags)728  ssize_t qemu_send_wrap(int sockfd, const void *buf, size_t len, int flags)
729  {
730      int ret;
731      SOCKET s = _get_osfhandle(sockfd);
732  
733      if (s == INVALID_SOCKET) {
734          return -1;
735      }
736  
737      ret = send(s, buf, len, flags);
738      if (ret < 0) {
739          errno = socket_error();
740      }
741      return ret;
742  }
743  
744  
745  #undef sendto
qemu_sendto_wrap(int sockfd,const void * buf,size_t len,int flags,const struct sockaddr * addr,socklen_t addrlen)746  ssize_t qemu_sendto_wrap(int sockfd, const void *buf, size_t len, int flags,
747                           const struct sockaddr *addr, socklen_t addrlen)
748  {
749      int ret;
750      SOCKET s = _get_osfhandle(sockfd);
751  
752      if (s == INVALID_SOCKET) {
753          return -1;
754      }
755  
756      ret = sendto(s, buf, len, flags, addr, addrlen);
757      if (ret < 0) {
758          errno = socket_error();
759      }
760      return ret;
761  }
762  
763  
764  #undef recv
qemu_recv_wrap(int sockfd,void * buf,size_t len,int flags)765  ssize_t qemu_recv_wrap(int sockfd, void *buf, size_t len, int flags)
766  {
767      int ret;
768      SOCKET s = _get_osfhandle(sockfd);
769  
770      if (s == INVALID_SOCKET) {
771          return -1;
772      }
773  
774      ret = recv(s, buf, len, flags);
775      if (ret < 0) {
776          errno = socket_error();
777      }
778      return ret;
779  }
780  
781  
782  #undef recvfrom
qemu_recvfrom_wrap(int sockfd,void * buf,size_t len,int flags,struct sockaddr * addr,socklen_t * addrlen)783  ssize_t qemu_recvfrom_wrap(int sockfd, void *buf, size_t len, int flags,
784                             struct sockaddr *addr, socklen_t *addrlen)
785  {
786      int ret;
787      SOCKET s = _get_osfhandle(sockfd);
788  
789      if (s == INVALID_SOCKET) {
790          return -1;
791      }
792  
793      ret = recvfrom(s, buf, len, flags, addr, addrlen);
794      if (ret < 0) {
795          errno = socket_error();
796      }
797      return ret;
798  }
799  
qemu_write_pidfile(const char * filename,Error ** errp)800  bool qemu_write_pidfile(const char *filename, Error **errp)
801  {
802      char buffer[128];
803      int len;
804      HANDLE file;
805      OVERLAPPED overlap;
806      BOOL ret;
807      memset(&overlap, 0, sizeof(overlap));
808  
809      file = CreateFile(filename, GENERIC_WRITE, FILE_SHARE_READ, NULL,
810                        OPEN_ALWAYS, FILE_ATTRIBUTE_NORMAL, NULL);
811  
812      if (file == INVALID_HANDLE_VALUE) {
813          error_setg(errp, "Failed to create PID file");
814          return false;
815      }
816      len = snprintf(buffer, sizeof(buffer), FMT_pid "\n", (pid_t)getpid());
817      ret = WriteFile(file, (LPCVOID)buffer, (DWORD)len,
818                      NULL, &overlap);
819      CloseHandle(file);
820      if (ret == 0) {
821          error_setg(errp, "Failed to write PID file");
822          return false;
823      }
824      return true;
825  }
826  
qemu_get_host_physmem(void)827  size_t qemu_get_host_physmem(void)
828  {
829      MEMORYSTATUSEX statex;
830      statex.dwLength = sizeof(statex);
831  
832      if (GlobalMemoryStatusEx(&statex)) {
833          return statex.ullTotalPhys;
834      }
835      return 0;
836  }
837  
qemu_msync(void * addr,size_t length,int fd)838  int qemu_msync(void *addr, size_t length, int fd)
839  {
840      /**
841       * Perform the sync based on the file descriptor
842       * The sync range will most probably be wider than the one
843       * requested - but it will still get the job done
844       */
845      return qemu_fdatasync(fd);
846  }
847  
qemu_win32_map_alloc(size_t size,HANDLE * h,Error ** errp)848  void *qemu_win32_map_alloc(size_t size, HANDLE *h, Error **errp)
849  {
850      void *bits;
851  
852      trace_win32_map_alloc(size);
853  
854      *h = CreateFileMapping(INVALID_HANDLE_VALUE, NULL, PAGE_READWRITE, 0,
855                            size, NULL);
856      if (*h == NULL) {
857          error_setg_win32(errp, GetLastError(), "Failed to CreateFileMapping");
858          return NULL;
859      }
860  
861      bits = MapViewOfFile(*h, FILE_MAP_ALL_ACCESS, 0, 0, size);
862      if (bits == NULL) {
863          error_setg_win32(errp, GetLastError(), "Failed to MapViewOfFile");
864          CloseHandle(*h);
865          return NULL;
866      }
867  
868      return bits;
869  }
870  
qemu_win32_map_free(void * ptr,HANDLE h,Error ** errp)871  void qemu_win32_map_free(void *ptr, HANDLE h, Error **errp)
872  {
873      trace_win32_map_free(ptr, h);
874  
875      if (UnmapViewOfFile(ptr) == 0) {
876          error_setg_win32(errp, GetLastError(), "Failed to UnmapViewOfFile");
877      }
878      CloseHandle(h);
879  }
880  
qemu_shm_alloc(size_t size,Error ** errp)881  int qemu_shm_alloc(size_t size, Error **errp)
882  {
883      error_setg(errp, "Shared memory is not supported.");
884      return -1;
885  }
886