xref: /openbmc/qemu/util/oslib-win32.c (revision 69430111)
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  * The implementation of g_poll (functions poll_rest, g_poll) at the end of
29  * this file are based on code from GNOME glib-2 and use a different license,
30  * see the license comment there.
31  */
32 
33 #include "qemu/osdep.h"
34 #include <windows.h>
35 #include "qemu-common.h"
36 #include "qapi/error.h"
37 #include "sysemu/sysemu.h"
38 #include "qemu/main-loop.h"
39 #include "trace.h"
40 #include "qemu/sockets.h"
41 #include "qemu/cutils.h"
42 
43 /* this must come after including "trace.h" */
44 #include <shlobj.h>
45 
46 void *qemu_oom_check(void *ptr)
47 {
48     if (ptr == NULL) {
49         fprintf(stderr, "Failed to allocate memory: %lu\n", GetLastError());
50         abort();
51     }
52     return ptr;
53 }
54 
55 void *qemu_try_memalign(size_t alignment, size_t size)
56 {
57     void *ptr;
58 
59     if (!size) {
60         abort();
61     }
62     ptr = VirtualAlloc(NULL, size, MEM_COMMIT, PAGE_READWRITE);
63     trace_qemu_memalign(alignment, size, ptr);
64     return ptr;
65 }
66 
67 void *qemu_memalign(size_t alignment, size_t size)
68 {
69     return qemu_oom_check(qemu_try_memalign(alignment, size));
70 }
71 
72 static int get_allocation_granularity(void)
73 {
74     SYSTEM_INFO system_info;
75 
76     GetSystemInfo(&system_info);
77     return system_info.dwAllocationGranularity;
78 }
79 
80 void *qemu_anon_ram_alloc(size_t size, uint64_t *align, bool shared)
81 {
82     void *ptr;
83 
84     ptr = VirtualAlloc(NULL, size, MEM_COMMIT, PAGE_READWRITE);
85     trace_qemu_anon_ram_alloc(size, ptr);
86 
87     if (ptr && align) {
88         *align = MAX(get_allocation_granularity(), getpagesize());
89     }
90     return ptr;
91 }
92 
93 void qemu_vfree(void *ptr)
94 {
95     trace_qemu_vfree(ptr);
96     if (ptr) {
97         VirtualFree(ptr, 0, MEM_RELEASE);
98     }
99 }
100 
101 void qemu_anon_ram_free(void *ptr, size_t size)
102 {
103     trace_qemu_anon_ram_free(ptr, size);
104     if (ptr) {
105         VirtualFree(ptr, 0, MEM_RELEASE);
106     }
107 }
108 
109 #ifndef _POSIX_THREAD_SAFE_FUNCTIONS
110 /* FIXME: add proper locking */
111 struct tm *gmtime_r(const time_t *timep, struct tm *result)
112 {
113     struct tm *p = gmtime(timep);
114     memset(result, 0, sizeof(*result));
115     if (p) {
116         *result = *p;
117         p = result;
118     }
119     return p;
120 }
121 
122 /* FIXME: add proper locking */
123 struct tm *localtime_r(const time_t *timep, struct tm *result)
124 {
125     struct tm *p = localtime(timep);
126     memset(result, 0, sizeof(*result));
127     if (p) {
128         *result = *p;
129         p = result;
130     }
131     return p;
132 }
133 #endif /* _POSIX_THREAD_SAFE_FUNCTIONS */
134 
135 static int socket_error(void)
136 {
137     switch (WSAGetLastError()) {
138     case 0:
139         return 0;
140     case WSAEINTR:
141         return EINTR;
142     case WSAEINVAL:
143         return EINVAL;
144     case WSA_INVALID_HANDLE:
145         return EBADF;
146     case WSA_NOT_ENOUGH_MEMORY:
147         return ENOMEM;
148     case WSA_INVALID_PARAMETER:
149         return EINVAL;
150     case WSAENAMETOOLONG:
151         return ENAMETOOLONG;
152     case WSAENOTEMPTY:
153         return ENOTEMPTY;
154     case WSAEWOULDBLOCK:
155          /* not using EWOULDBLOCK as we don't want code to have
156           * to check both EWOULDBLOCK and EAGAIN */
157         return EAGAIN;
158     case WSAEINPROGRESS:
159         return EINPROGRESS;
160     case WSAEALREADY:
161         return EALREADY;
162     case WSAENOTSOCK:
163         return ENOTSOCK;
164     case WSAEDESTADDRREQ:
165         return EDESTADDRREQ;
166     case WSAEMSGSIZE:
167         return EMSGSIZE;
168     case WSAEPROTOTYPE:
169         return EPROTOTYPE;
170     case WSAENOPROTOOPT:
171         return ENOPROTOOPT;
172     case WSAEPROTONOSUPPORT:
173         return EPROTONOSUPPORT;
174     case WSAEOPNOTSUPP:
175         return EOPNOTSUPP;
176     case WSAEAFNOSUPPORT:
177         return EAFNOSUPPORT;
178     case WSAEADDRINUSE:
179         return EADDRINUSE;
180     case WSAEADDRNOTAVAIL:
181         return EADDRNOTAVAIL;
182     case WSAENETDOWN:
183         return ENETDOWN;
184     case WSAENETUNREACH:
185         return ENETUNREACH;
186     case WSAENETRESET:
187         return ENETRESET;
188     case WSAECONNABORTED:
189         return ECONNABORTED;
190     case WSAECONNRESET:
191         return ECONNRESET;
192     case WSAENOBUFS:
193         return ENOBUFS;
194     case WSAEISCONN:
195         return EISCONN;
196     case WSAENOTCONN:
197         return ENOTCONN;
198     case WSAETIMEDOUT:
199         return ETIMEDOUT;
200     case WSAECONNREFUSED:
201         return ECONNREFUSED;
202     case WSAELOOP:
203         return ELOOP;
204     case WSAEHOSTUNREACH:
205         return EHOSTUNREACH;
206     default:
207         return EIO;
208     }
209 }
210 
211 void qemu_set_block(int fd)
212 {
213     unsigned long opt = 0;
214     WSAEventSelect(fd, NULL, 0);
215     ioctlsocket(fd, FIONBIO, &opt);
216 }
217 
218 int qemu_try_set_nonblock(int fd)
219 {
220     unsigned long opt = 1;
221     if (ioctlsocket(fd, FIONBIO, &opt) != NO_ERROR) {
222         return -socket_error();
223     }
224     qemu_fd_register(fd);
225     return 0;
226 }
227 
228 void qemu_set_nonblock(int fd)
229 {
230     (void)qemu_try_set_nonblock(fd);
231 }
232 
233 int socket_set_fast_reuse(int fd)
234 {
235     /* Enabling the reuse of an endpoint that was used by a socket still in
236      * TIME_WAIT state is usually performed by setting SO_REUSEADDR. On Windows
237      * fast reuse is the default and SO_REUSEADDR does strange things. So we
238      * don't have to do anything here. More info can be found at:
239      * http://msdn.microsoft.com/en-us/library/windows/desktop/ms740621.aspx */
240     return 0;
241 }
242 
243 int inet_aton(const char *cp, struct in_addr *ia)
244 {
245     uint32_t addr = inet_addr(cp);
246     if (addr == 0xffffffff) {
247         return 0;
248     }
249     ia->s_addr = addr;
250     return 1;
251 }
252 
253 void qemu_set_cloexec(int fd)
254 {
255 }
256 
257 /* Offset between 1/1/1601 and 1/1/1970 in 100 nanosec units */
258 #define _W32_FT_OFFSET (116444736000000000ULL)
259 
260 int qemu_gettimeofday(qemu_timeval *tp)
261 {
262   union {
263     unsigned long long ns100; /*time since 1 Jan 1601 in 100ns units */
264     FILETIME ft;
265   }  _now;
266 
267   if(tp) {
268       GetSystemTimeAsFileTime (&_now.ft);
269       tp->tv_usec=(long)((_now.ns100 / 10ULL) % 1000000ULL );
270       tp->tv_sec= (long)((_now.ns100 - _W32_FT_OFFSET) / 10000000ULL);
271   }
272   /* Always return 0 as per Open Group Base Specifications Issue 6.
273      Do not set errno on error.  */
274   return 0;
275 }
276 
277 int qemu_get_thread_id(void)
278 {
279     return GetCurrentThreadId();
280 }
281 
282 char *
283 qemu_get_local_state_pathname(const char *relative_pathname)
284 {
285     HRESULT result;
286     char base_path[MAX_PATH+1] = "";
287 
288     result = SHGetFolderPath(NULL, CSIDL_COMMON_APPDATA, NULL,
289                              /* SHGFP_TYPE_CURRENT */ 0, base_path);
290     if (result != S_OK) {
291         /* misconfigured environment */
292         g_critical("CSIDL_COMMON_APPDATA unavailable: %ld", (long)result);
293         abort();
294     }
295     return g_strdup_printf("%s" G_DIR_SEPARATOR_S "%s", base_path,
296                            relative_pathname);
297 }
298 
299 void qemu_set_tty_echo(int fd, bool echo)
300 {
301     HANDLE handle = (HANDLE)_get_osfhandle(fd);
302     DWORD dwMode = 0;
303 
304     if (handle == INVALID_HANDLE_VALUE) {
305         return;
306     }
307 
308     GetConsoleMode(handle, &dwMode);
309 
310     if (echo) {
311         SetConsoleMode(handle, dwMode | ENABLE_ECHO_INPUT | ENABLE_LINE_INPUT);
312     } else {
313         SetConsoleMode(handle,
314                        dwMode & ~(ENABLE_ECHO_INPUT | ENABLE_LINE_INPUT));
315     }
316 }
317 
318 static const char *exec_dir;
319 
320 void qemu_init_exec_dir(const char *argv0)
321 {
322 
323     char *p;
324     char buf[MAX_PATH];
325     DWORD len;
326 
327     if (exec_dir) {
328         return;
329     }
330 
331     len = GetModuleFileName(NULL, buf, sizeof(buf) - 1);
332     if (len == 0) {
333         return;
334     }
335 
336     buf[len] = 0;
337     p = buf + len - 1;
338     while (p != buf && *p != '\\') {
339         p--;
340     }
341     *p = 0;
342     if (access(buf, R_OK) == 0) {
343         exec_dir = g_strdup(buf);
344     } else {
345         exec_dir = CONFIG_BINDIR;
346     }
347 }
348 
349 const char *qemu_get_exec_dir(void)
350 {
351     return exec_dir;
352 }
353 
354 #if !GLIB_CHECK_VERSION(2, 50, 0)
355 /*
356  * The original implementation of g_poll from glib has a problem on Windows
357  * when using timeouts < 10 ms.
358  *
359  * Whenever g_poll is called with timeout < 10 ms, it does a quick poll instead
360  * of wait. This causes significant performance degradation of QEMU.
361  *
362  * The following code is a copy of the original code from glib/gpoll.c
363  * (glib commit 20f4d1820b8d4d0fc4447188e33efffd6d4a88d8 from 2014-02-19).
364  * Some debug code was removed and the code was reformatted.
365  * All other code modifications are marked with 'QEMU'.
366  */
367 
368 /*
369  * gpoll.c: poll(2) abstraction
370  * Copyright 1998 Owen Taylor
371  * Copyright 2008 Red Hat, Inc.
372  *
373  * This library is free software; you can redistribute it and/or
374  * modify it under the terms of the GNU Lesser General Public
375  * License as published by the Free Software Foundation; either
376  * version 2 of the License, or (at your option) any later version.
377  *
378  * This library is distributed in the hope that it will be useful,
379  * but WITHOUT ANY WARRANTY; without even the implied warranty of
380  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
381  * Lesser General Public License for more details.
382  *
383  * You should have received a copy of the GNU Lesser General Public
384  * License along with this library; if not, see <http://www.gnu.org/licenses/>.
385  */
386 
387 static int poll_rest(gboolean poll_msgs, HANDLE *handles, gint nhandles,
388                      GPollFD *fds, guint nfds, gint timeout)
389 {
390     DWORD ready;
391     GPollFD *f;
392     int recursed_result;
393 
394     if (poll_msgs) {
395         /* Wait for either messages or handles
396          * -> Use MsgWaitForMultipleObjectsEx
397          */
398         ready = MsgWaitForMultipleObjectsEx(nhandles, handles, timeout,
399                                             QS_ALLINPUT, MWMO_ALERTABLE);
400 
401         if (ready == WAIT_FAILED) {
402             gchar *emsg = g_win32_error_message(GetLastError());
403             g_warning("MsgWaitForMultipleObjectsEx failed: %s", emsg);
404             g_free(emsg);
405         }
406     } else if (nhandles == 0) {
407         /* No handles to wait for, just the timeout */
408         if (timeout == INFINITE) {
409             ready = WAIT_FAILED;
410         } else {
411             SleepEx(timeout, TRUE);
412             ready = WAIT_TIMEOUT;
413         }
414     } else {
415         /* Wait for just handles
416          * -> Use WaitForMultipleObjectsEx
417          */
418         ready =
419             WaitForMultipleObjectsEx(nhandles, handles, FALSE, timeout, TRUE);
420         if (ready == WAIT_FAILED) {
421             gchar *emsg = g_win32_error_message(GetLastError());
422             g_warning("WaitForMultipleObjectsEx failed: %s", emsg);
423             g_free(emsg);
424         }
425     }
426 
427     if (ready == WAIT_FAILED) {
428         return -1;
429     } else if (ready == WAIT_TIMEOUT || ready == WAIT_IO_COMPLETION) {
430         return 0;
431     } else if (poll_msgs && ready == WAIT_OBJECT_0 + nhandles) {
432         for (f = fds; f < &fds[nfds]; ++f) {
433             if (f->fd == G_WIN32_MSG_HANDLE && f->events & G_IO_IN) {
434                 f->revents |= G_IO_IN;
435             }
436         }
437 
438         /* If we have a timeout, or no handles to poll, be satisfied
439          * with just noticing we have messages waiting.
440          */
441         if (timeout != 0 || nhandles == 0) {
442             return 1;
443         }
444 
445         /* If no timeout and handles to poll, recurse to poll them,
446          * too.
447          */
448         recursed_result = poll_rest(FALSE, handles, nhandles, fds, nfds, 0);
449         return (recursed_result == -1) ? -1 : 1 + recursed_result;
450     } else if (/* QEMU: removed the following unneeded statement which causes
451                 * a compiler warning: ready >= WAIT_OBJECT_0 && */
452                ready < WAIT_OBJECT_0 + nhandles) {
453         for (f = fds; f < &fds[nfds]; ++f) {
454             if ((HANDLE) f->fd == handles[ready - WAIT_OBJECT_0]) {
455                 f->revents = f->events;
456             }
457         }
458 
459         /* If no timeout and polling several handles, recurse to poll
460          * the rest of them.
461          */
462         if (timeout == 0 && nhandles > 1) {
463             /* Remove the handle that fired */
464             int i;
465             for (i = ready - WAIT_OBJECT_0 + 1; i < nhandles; i++) {
466                 handles[i-1] = handles[i];
467             }
468             nhandles--;
469             recursed_result = poll_rest(FALSE, handles, nhandles, fds, nfds, 0);
470             return (recursed_result == -1) ? -1 : 1 + recursed_result;
471         }
472         return 1;
473     }
474 
475     return 0;
476 }
477 
478 gint g_poll(GPollFD *fds, guint nfds, gint timeout)
479 {
480     HANDLE handles[MAXIMUM_WAIT_OBJECTS];
481     gboolean poll_msgs = FALSE;
482     GPollFD *f;
483     gint nhandles = 0;
484     int retval;
485 
486     for (f = fds; f < &fds[nfds]; ++f) {
487         if (f->fd == G_WIN32_MSG_HANDLE && (f->events & G_IO_IN)) {
488             poll_msgs = TRUE;
489         } else if (f->fd > 0) {
490             /* Don't add the same handle several times into the array, as
491              * docs say that is not allowed, even if it actually does seem
492              * to work.
493              */
494             gint i;
495 
496             for (i = 0; i < nhandles; i++) {
497                 if (handles[i] == (HANDLE) f->fd) {
498                     break;
499                 }
500             }
501 
502             if (i == nhandles) {
503                 if (nhandles == MAXIMUM_WAIT_OBJECTS) {
504                     g_warning("Too many handles to wait for!\n");
505                     break;
506                 } else {
507                     handles[nhandles++] = (HANDLE) f->fd;
508                 }
509             }
510         }
511     }
512 
513     for (f = fds; f < &fds[nfds]; ++f) {
514         f->revents = 0;
515     }
516 
517     if (timeout == -1) {
518         timeout = INFINITE;
519     }
520 
521     /* Polling for several things? */
522     if (nhandles > 1 || (nhandles > 0 && poll_msgs)) {
523         /* First check if one or several of them are immediately
524          * available
525          */
526         retval = poll_rest(poll_msgs, handles, nhandles, fds, nfds, 0);
527 
528         /* If not, and we have a significant timeout, poll again with
529          * timeout then. Note that this will return indication for only
530          * one event, or only for messages. We ignore timeouts less than
531          * ten milliseconds as they are mostly pointless on Windows, the
532          * MsgWaitForMultipleObjectsEx() call will timeout right away
533          * anyway.
534          *
535          * Modification for QEMU: replaced timeout >= 10 by timeout > 0.
536          */
537         if (retval == 0 && (timeout == INFINITE || timeout > 0)) {
538             retval = poll_rest(poll_msgs, handles, nhandles,
539                                fds, nfds, timeout);
540         }
541     } else {
542         /* Just polling for one thing, so no need to check first if
543          * available immediately
544          */
545         retval = poll_rest(poll_msgs, handles, nhandles, fds, nfds, timeout);
546     }
547 
548     if (retval == -1) {
549         for (f = fds; f < &fds[nfds]; ++f) {
550             f->revents = 0;
551         }
552     }
553 
554     return retval;
555 }
556 #endif
557 
558 int getpagesize(void)
559 {
560     SYSTEM_INFO system_info;
561 
562     GetSystemInfo(&system_info);
563     return system_info.dwPageSize;
564 }
565 
566 void os_mem_prealloc(int fd, char *area, size_t memory, int smp_cpus,
567                      Error **errp)
568 {
569     int i;
570     size_t pagesize = qemu_real_host_page_size;
571 
572     memory = (memory + pagesize - 1) & -pagesize;
573     for (i = 0; i < memory / pagesize; i++) {
574         memset(area + pagesize * i, 0, 1);
575     }
576 }
577 
578 char *qemu_get_pid_name(pid_t pid)
579 {
580     /* XXX Implement me */
581     abort();
582 }
583 
584 
585 pid_t qemu_fork(Error **errp)
586 {
587     errno = ENOSYS;
588     error_setg_errno(errp, errno,
589                      "cannot fork child process");
590     return -1;
591 }
592 
593 
594 #undef connect
595 int qemu_connect_wrap(int sockfd, const struct sockaddr *addr,
596                       socklen_t addrlen)
597 {
598     int ret;
599     ret = connect(sockfd, addr, addrlen);
600     if (ret < 0) {
601         if (WSAGetLastError() == WSAEWOULDBLOCK) {
602             errno = EINPROGRESS;
603         } else {
604             errno = socket_error();
605         }
606     }
607     return ret;
608 }
609 
610 
611 #undef listen
612 int qemu_listen_wrap(int sockfd, int backlog)
613 {
614     int ret;
615     ret = listen(sockfd, backlog);
616     if (ret < 0) {
617         errno = socket_error();
618     }
619     return ret;
620 }
621 
622 
623 #undef bind
624 int qemu_bind_wrap(int sockfd, const struct sockaddr *addr,
625                    socklen_t addrlen)
626 {
627     int ret;
628     ret = bind(sockfd, addr, addrlen);
629     if (ret < 0) {
630         errno = socket_error();
631     }
632     return ret;
633 }
634 
635 
636 #undef socket
637 int qemu_socket_wrap(int domain, int type, int protocol)
638 {
639     int ret;
640     ret = socket(domain, type, protocol);
641     if (ret < 0) {
642         errno = socket_error();
643     }
644     return ret;
645 }
646 
647 
648 #undef accept
649 int qemu_accept_wrap(int sockfd, struct sockaddr *addr,
650                      socklen_t *addrlen)
651 {
652     int ret;
653     ret = accept(sockfd, addr, addrlen);
654     if (ret < 0) {
655         errno = socket_error();
656     }
657     return ret;
658 }
659 
660 
661 #undef shutdown
662 int qemu_shutdown_wrap(int sockfd, int how)
663 {
664     int ret;
665     ret = shutdown(sockfd, how);
666     if (ret < 0) {
667         errno = socket_error();
668     }
669     return ret;
670 }
671 
672 
673 #undef ioctlsocket
674 int qemu_ioctlsocket_wrap(int fd, int req, void *val)
675 {
676     int ret;
677     ret = ioctlsocket(fd, req, val);
678     if (ret < 0) {
679         errno = socket_error();
680     }
681     return ret;
682 }
683 
684 
685 #undef closesocket
686 int qemu_closesocket_wrap(int fd)
687 {
688     int ret;
689     ret = closesocket(fd);
690     if (ret < 0) {
691         errno = socket_error();
692     }
693     return ret;
694 }
695 
696 
697 #undef getsockopt
698 int qemu_getsockopt_wrap(int sockfd, int level, int optname,
699                          void *optval, socklen_t *optlen)
700 {
701     int ret;
702     ret = getsockopt(sockfd, level, optname, optval, optlen);
703     if (ret < 0) {
704         errno = socket_error();
705     }
706     return ret;
707 }
708 
709 
710 #undef setsockopt
711 int qemu_setsockopt_wrap(int sockfd, int level, int optname,
712                          const void *optval, socklen_t optlen)
713 {
714     int ret;
715     ret = setsockopt(sockfd, level, optname, optval, optlen);
716     if (ret < 0) {
717         errno = socket_error();
718     }
719     return ret;
720 }
721 
722 
723 #undef getpeername
724 int qemu_getpeername_wrap(int sockfd, struct sockaddr *addr,
725                           socklen_t *addrlen)
726 {
727     int ret;
728     ret = getpeername(sockfd, addr, addrlen);
729     if (ret < 0) {
730         errno = socket_error();
731     }
732     return ret;
733 }
734 
735 
736 #undef getsockname
737 int qemu_getsockname_wrap(int sockfd, struct sockaddr *addr,
738                           socklen_t *addrlen)
739 {
740     int ret;
741     ret = getsockname(sockfd, addr, addrlen);
742     if (ret < 0) {
743         errno = socket_error();
744     }
745     return ret;
746 }
747 
748 
749 #undef send
750 ssize_t qemu_send_wrap(int sockfd, const void *buf, size_t len, int flags)
751 {
752     int ret;
753     ret = send(sockfd, buf, len, flags);
754     if (ret < 0) {
755         errno = socket_error();
756     }
757     return ret;
758 }
759 
760 
761 #undef sendto
762 ssize_t qemu_sendto_wrap(int sockfd, const void *buf, size_t len, int flags,
763                          const struct sockaddr *addr, socklen_t addrlen)
764 {
765     int ret;
766     ret = sendto(sockfd, buf, len, flags, addr, addrlen);
767     if (ret < 0) {
768         errno = socket_error();
769     }
770     return ret;
771 }
772 
773 
774 #undef recv
775 ssize_t qemu_recv_wrap(int sockfd, void *buf, size_t len, int flags)
776 {
777     int ret;
778     ret = recv(sockfd, buf, len, flags);
779     if (ret < 0) {
780         errno = socket_error();
781     }
782     return ret;
783 }
784 
785 
786 #undef recvfrom
787 ssize_t qemu_recvfrom_wrap(int sockfd, void *buf, size_t len, int flags,
788                            struct sockaddr *addr, socklen_t *addrlen)
789 {
790     int ret;
791     ret = recvfrom(sockfd, buf, len, flags, addr, addrlen);
792     if (ret < 0) {
793         errno = socket_error();
794     }
795     return ret;
796 }
797 
798 bool qemu_write_pidfile(const char *filename, Error **errp)
799 {
800     char buffer[128];
801     int len;
802     HANDLE file;
803     OVERLAPPED overlap;
804     BOOL ret;
805     memset(&overlap, 0, sizeof(overlap));
806 
807     file = CreateFile(filename, GENERIC_WRITE, FILE_SHARE_READ, NULL,
808                       OPEN_ALWAYS, FILE_ATTRIBUTE_NORMAL, NULL);
809 
810     if (file == INVALID_HANDLE_VALUE) {
811         error_setg(errp, "Failed to create PID file");
812         return false;
813     }
814     len = snprintf(buffer, sizeof(buffer), FMT_pid "\n", (pid_t)getpid());
815     ret = WriteFile(file, (LPCVOID)buffer, (DWORD)len,
816                     NULL, &overlap);
817     CloseHandle(file);
818     if (ret == 0) {
819         error_setg(errp, "Failed to write PID file");
820         return false;
821     }
822     return true;
823 }
824 
825 char *qemu_get_host_name(Error **errp)
826 {
827     wchar_t tmp[MAX_COMPUTERNAME_LENGTH + 1];
828     DWORD size = G_N_ELEMENTS(tmp);
829 
830     if (GetComputerNameW(tmp, &size) == 0) {
831         error_setg_win32(errp, GetLastError(), "failed close handle");
832         return NULL;
833     }
834 
835     return g_utf16_to_utf8(tmp, size, NULL, NULL, NULL);
836 }
837 
838 size_t qemu_get_host_physmem(void)
839 {
840     MEMORYSTATUSEX statex;
841     statex.dwLength = sizeof(statex);
842 
843     if (GlobalMemoryStatusEx(&statex)) {
844         return statex.ullTotalPhys;
845     }
846     return 0;
847 }
848