1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32#include "qemu/osdep.h"
33#include <windows.h>
34#include "qapi/error.h"
35#include "sysemu/sysemu.h"
36#include "qemu/main-loop.h"
37#include "trace.h"
38#include "qemu/sockets.h"
39#include "qemu/cutils.h"
40
41
42#include <shlobj.h>
43
44void *qemu_oom_check(void *ptr)
45{
46 if (ptr == NULL) {
47 fprintf(stderr, "Failed to allocate memory: %lu\n", GetLastError());
48 abort();
49 }
50 return ptr;
51}
52
53void *qemu_try_memalign(size_t alignment, size_t size)
54{
55 void *ptr;
56
57 if (!size) {
58 abort();
59 }
60 ptr = VirtualAlloc(NULL, size, MEM_COMMIT, PAGE_READWRITE);
61 trace_qemu_memalign(alignment, size, ptr);
62 return ptr;
63}
64
65void *qemu_memalign(size_t alignment, size_t size)
66{
67 return qemu_oom_check(qemu_try_memalign(alignment, size));
68}
69
70static int get_allocation_granularity(void)
71{
72 SYSTEM_INFO system_info;
73
74 GetSystemInfo(&system_info);
75 return system_info.dwAllocationGranularity;
76}
77
78void *qemu_anon_ram_alloc(size_t size, uint64_t *align, bool shared)
79{
80 void *ptr;
81
82 ptr = VirtualAlloc(NULL, size, MEM_COMMIT, PAGE_READWRITE);
83 trace_qemu_anon_ram_alloc(size, ptr);
84
85 if (ptr && align) {
86 *align = MAX(get_allocation_granularity(), getpagesize());
87 }
88 return ptr;
89}
90
91void qemu_vfree(void *ptr)
92{
93 trace_qemu_vfree(ptr);
94 if (ptr) {
95 VirtualFree(ptr, 0, MEM_RELEASE);
96 }
97}
98
99void qemu_anon_ram_free(void *ptr, size_t size)
100{
101 trace_qemu_anon_ram_free(ptr, size);
102 if (ptr) {
103 VirtualFree(ptr, 0, MEM_RELEASE);
104 }
105}
106
107#ifndef CONFIG_LOCALTIME_R
108
109struct tm *gmtime_r(const time_t *timep, struct tm *result)
110{
111 struct tm *p = gmtime(timep);
112 memset(result, 0, sizeof(*result));
113 if (p) {
114 *result = *p;
115 p = result;
116 }
117 return p;
118}
119
120
121struct tm *localtime_r(const time_t *timep, struct tm *result)
122{
123 struct tm *p = localtime(timep);
124 memset(result, 0, sizeof(*result));
125 if (p) {
126 *result = *p;
127 p = result;
128 }
129 return p;
130}
131#endif
132
133void qemu_set_block(int fd)
134{
135 unsigned long opt = 0;
136 WSAEventSelect(fd, NULL, 0);
137 ioctlsocket(fd, FIONBIO, &opt);
138}
139
140void qemu_set_nonblock(int fd)
141{
142 unsigned long opt = 1;
143 ioctlsocket(fd, FIONBIO, &opt);
144 qemu_fd_register(fd);
145}
146
147int socket_set_fast_reuse(int fd)
148{
149
150
151
152
153
154 return 0;
155}
156
157
158static int socket_error(void)
159{
160 switch (WSAGetLastError()) {
161 case 0:
162 return 0;
163 case WSAEINTR:
164 return EINTR;
165 case WSAEINVAL:
166 return EINVAL;
167 case WSA_INVALID_HANDLE:
168 return EBADF;
169 case WSA_NOT_ENOUGH_MEMORY:
170 return ENOMEM;
171 case WSA_INVALID_PARAMETER:
172 return EINVAL;
173 case WSAENAMETOOLONG:
174 return ENAMETOOLONG;
175 case WSAENOTEMPTY:
176 return ENOTEMPTY;
177 case WSAEWOULDBLOCK:
178
179
180 return EAGAIN;
181 case WSAEINPROGRESS:
182 return EINPROGRESS;
183 case WSAEALREADY:
184 return EALREADY;
185 case WSAENOTSOCK:
186 return ENOTSOCK;
187 case WSAEDESTADDRREQ:
188 return EDESTADDRREQ;
189 case WSAEMSGSIZE:
190 return EMSGSIZE;
191 case WSAEPROTOTYPE:
192 return EPROTOTYPE;
193 case WSAENOPROTOOPT:
194 return ENOPROTOOPT;
195 case WSAEPROTONOSUPPORT:
196 return EPROTONOSUPPORT;
197 case WSAEOPNOTSUPP:
198 return EOPNOTSUPP;
199 case WSAEAFNOSUPPORT:
200 return EAFNOSUPPORT;
201 case WSAEADDRINUSE:
202 return EADDRINUSE;
203 case WSAEADDRNOTAVAIL:
204 return EADDRNOTAVAIL;
205 case WSAENETDOWN:
206 return ENETDOWN;
207 case WSAENETUNREACH:
208 return ENETUNREACH;
209 case WSAENETRESET:
210 return ENETRESET;
211 case WSAECONNABORTED:
212 return ECONNABORTED;
213 case WSAECONNRESET:
214 return ECONNRESET;
215 case WSAENOBUFS:
216 return ENOBUFS;
217 case WSAEISCONN:
218 return EISCONN;
219 case WSAENOTCONN:
220 return ENOTCONN;
221 case WSAETIMEDOUT:
222 return ETIMEDOUT;
223 case WSAECONNREFUSED:
224 return ECONNREFUSED;
225 case WSAELOOP:
226 return ELOOP;
227 case WSAEHOSTUNREACH:
228 return EHOSTUNREACH;
229 default:
230 return EIO;
231 }
232}
233
234int inet_aton(const char *cp, struct in_addr *ia)
235{
236 uint32_t addr = inet_addr(cp);
237 if (addr == 0xffffffff) {
238 return 0;
239 }
240 ia->s_addr = addr;
241 return 1;
242}
243
244void qemu_set_cloexec(int fd)
245{
246}
247
248
249#define _W32_FT_OFFSET (116444736000000000ULL)
250
251int qemu_gettimeofday(qemu_timeval *tp)
252{
253 union {
254 unsigned long long ns100;
255 FILETIME ft;
256 } _now;
257
258 if(tp) {
259 GetSystemTimeAsFileTime (&_now.ft);
260 tp->tv_usec=(long)((_now.ns100 / 10ULL) % 1000000ULL );
261 tp->tv_sec= (long)((_now.ns100 - _W32_FT_OFFSET) / 10000000ULL);
262 }
263
264
265 return 0;
266}
267
268int qemu_get_thread_id(void)
269{
270 return GetCurrentThreadId();
271}
272
273char *
274qemu_get_local_state_pathname(const char *relative_pathname)
275{
276 HRESULT result;
277 char base_path[MAX_PATH+1] = "";
278
279 result = SHGetFolderPath(NULL, CSIDL_COMMON_APPDATA, NULL,
280 0, base_path);
281 if (result != S_OK) {
282
283 g_critical("CSIDL_COMMON_APPDATA unavailable: %ld", (long)result);
284 abort();
285 }
286 return g_strdup_printf("%s" G_DIR_SEPARATOR_S "%s", base_path,
287 relative_pathname);
288}
289
290void qemu_set_tty_echo(int fd, bool echo)
291{
292 HANDLE handle = (HANDLE)_get_osfhandle(fd);
293 DWORD dwMode = 0;
294
295 if (handle == INVALID_HANDLE_VALUE) {
296 return;
297 }
298
299 GetConsoleMode(handle, &dwMode);
300
301 if (echo) {
302 SetConsoleMode(handle, dwMode | ENABLE_ECHO_INPUT | ENABLE_LINE_INPUT);
303 } else {
304 SetConsoleMode(handle,
305 dwMode & ~(ENABLE_ECHO_INPUT | ENABLE_LINE_INPUT));
306 }
307}
308
309static char exec_dir[PATH_MAX];
310
311void qemu_init_exec_dir(const char *argv0)
312{
313
314 char *p;
315 char buf[MAX_PATH];
316 DWORD len;
317
318 len = GetModuleFileName(NULL, buf, sizeof(buf) - 1);
319 if (len == 0) {
320 return;
321 }
322
323 buf[len] = 0;
324 p = buf + len - 1;
325 while (p != buf && *p != '\\') {
326 p--;
327 }
328 *p = 0;
329 if (access(buf, R_OK) == 0) {
330 pstrcpy(exec_dir, sizeof(exec_dir), buf);
331 }
332}
333
334char *qemu_get_exec_dir(void)
335{
336 return g_strdup(exec_dir);
337}
338
339#if !GLIB_CHECK_VERSION(2, 50, 0)
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372static int poll_rest(gboolean poll_msgs, HANDLE *handles, gint nhandles,
373 GPollFD *fds, guint nfds, gint timeout)
374{
375 DWORD ready;
376 GPollFD *f;
377 int recursed_result;
378
379 if (poll_msgs) {
380
381
382
383 ready = MsgWaitForMultipleObjectsEx(nhandles, handles, timeout,
384 QS_ALLINPUT, MWMO_ALERTABLE);
385
386 if (ready == WAIT_FAILED) {
387 gchar *emsg = g_win32_error_message(GetLastError());
388 g_warning("MsgWaitForMultipleObjectsEx failed: %s", emsg);
389 g_free(emsg);
390 }
391 } else if (nhandles == 0) {
392
393 if (timeout == INFINITE) {
394 ready = WAIT_FAILED;
395 } else {
396 SleepEx(timeout, TRUE);
397 ready = WAIT_TIMEOUT;
398 }
399 } else {
400
401
402
403 ready =
404 WaitForMultipleObjectsEx(nhandles, handles, FALSE, timeout, TRUE);
405 if (ready == WAIT_FAILED) {
406 gchar *emsg = g_win32_error_message(GetLastError());
407 g_warning("WaitForMultipleObjectsEx failed: %s", emsg);
408 g_free(emsg);
409 }
410 }
411
412 if (ready == WAIT_FAILED) {
413 return -1;
414 } else if (ready == WAIT_TIMEOUT || ready == WAIT_IO_COMPLETION) {
415 return 0;
416 } else if (poll_msgs && ready == WAIT_OBJECT_0 + nhandles) {
417 for (f = fds; f < &fds[nfds]; ++f) {
418 if (f->fd == G_WIN32_MSG_HANDLE && f->events & G_IO_IN) {
419 f->revents |= G_IO_IN;
420 }
421 }
422
423
424
425
426 if (timeout != 0 || nhandles == 0) {
427 return 1;
428 }
429
430
431
432
433 recursed_result = poll_rest(FALSE, handles, nhandles, fds, nfds, 0);
434 return (recursed_result == -1) ? -1 : 1 + recursed_result;
435 } else if (
436
437 ready < WAIT_OBJECT_0 + nhandles) {
438 for (f = fds; f < &fds[nfds]; ++f) {
439 if ((HANDLE) f->fd == handles[ready - WAIT_OBJECT_0]) {
440 f->revents = f->events;
441 }
442 }
443
444
445
446
447 if (timeout == 0 && nhandles > 1) {
448
449 int i;
450 for (i = ready - WAIT_OBJECT_0 + 1; i < nhandles; i++) {
451 handles[i-1] = handles[i];
452 }
453 nhandles--;
454 recursed_result = poll_rest(FALSE, handles, nhandles, fds, nfds, 0);
455 return (recursed_result == -1) ? -1 : 1 + recursed_result;
456 }
457 return 1;
458 }
459
460 return 0;
461}
462
463gint g_poll(GPollFD *fds, guint nfds, gint timeout)
464{
465 HANDLE handles[MAXIMUM_WAIT_OBJECTS];
466 gboolean poll_msgs = FALSE;
467 GPollFD *f;
468 gint nhandles = 0;
469 int retval;
470
471 for (f = fds; f < &fds[nfds]; ++f) {
472 if (f->fd == G_WIN32_MSG_HANDLE && (f->events & G_IO_IN)) {
473 poll_msgs = TRUE;
474 } else if (f->fd > 0) {
475
476
477
478
479 gint i;
480
481 for (i = 0; i < nhandles; i++) {
482 if (handles[i] == (HANDLE) f->fd) {
483 break;
484 }
485 }
486
487 if (i == nhandles) {
488 if (nhandles == MAXIMUM_WAIT_OBJECTS) {
489 g_warning("Too many handles to wait for!\n");
490 break;
491 } else {
492 handles[nhandles++] = (HANDLE) f->fd;
493 }
494 }
495 }
496 }
497
498 for (f = fds; f < &fds[nfds]; ++f) {
499 f->revents = 0;
500 }
501
502 if (timeout == -1) {
503 timeout = INFINITE;
504 }
505
506
507 if (nhandles > 1 || (nhandles > 0 && poll_msgs)) {
508
509
510
511 retval = poll_rest(poll_msgs, handles, nhandles, fds, nfds, 0);
512
513
514
515
516
517
518
519
520
521
522 if (retval == 0 && (timeout == INFINITE || timeout > 0)) {
523 retval = poll_rest(poll_msgs, handles, nhandles,
524 fds, nfds, timeout);
525 }
526 } else {
527
528
529
530 retval = poll_rest(poll_msgs, handles, nhandles, fds, nfds, timeout);
531 }
532
533 if (retval == -1) {
534 for (f = fds; f < &fds[nfds]; ++f) {
535 f->revents = 0;
536 }
537 }
538
539 return retval;
540}
541#endif
542
543int getpagesize(void)
544{
545 SYSTEM_INFO system_info;
546
547 GetSystemInfo(&system_info);
548 return system_info.dwPageSize;
549}
550
551void os_mem_prealloc(int fd, char *area, size_t memory, int smp_cpus,
552 Error **errp)
553{
554 int i;
555 size_t pagesize = getpagesize();
556
557 memory = (memory + pagesize - 1) & -pagesize;
558 for (i = 0; i < memory / pagesize; i++) {
559 memset(area + pagesize * i, 0, 1);
560 }
561}
562
563
564char *qemu_get_pid_name(pid_t pid)
565{
566
567 abort();
568}
569
570
571pid_t qemu_fork(Error **errp)
572{
573 errno = ENOSYS;
574 error_setg_errno(errp, errno,
575 "cannot fork child process");
576 return -1;
577}
578
579
580#undef connect
581int qemu_connect_wrap(int sockfd, const struct sockaddr *addr,
582 socklen_t addrlen)
583{
584 int ret;
585 ret = connect(sockfd, addr, addrlen);
586 if (ret < 0) {
587 errno = socket_error();
588 }
589 return ret;
590}
591
592
593#undef listen
594int qemu_listen_wrap(int sockfd, int backlog)
595{
596 int ret;
597 ret = listen(sockfd, backlog);
598 if (ret < 0) {
599 errno = socket_error();
600 }
601 return ret;
602}
603
604
605#undef bind
606int qemu_bind_wrap(int sockfd, const struct sockaddr *addr,
607 socklen_t addrlen)
608{
609 int ret;
610 ret = bind(sockfd, addr, addrlen);
611 if (ret < 0) {
612 errno = socket_error();
613 }
614 return ret;
615}
616
617
618#undef socket
619int qemu_socket_wrap(int domain, int type, int protocol)
620{
621 int ret;
622 ret = socket(domain, type, protocol);
623 if (ret < 0) {
624 errno = socket_error();
625 }
626 return ret;
627}
628
629
630#undef accept
631int qemu_accept_wrap(int sockfd, struct sockaddr *addr,
632 socklen_t *addrlen)
633{
634 int ret;
635 ret = accept(sockfd, addr, addrlen);
636 if (ret < 0) {
637 errno = socket_error();
638 }
639 return ret;
640}
641
642
643#undef shutdown
644int qemu_shutdown_wrap(int sockfd, int how)
645{
646 int ret;
647 ret = shutdown(sockfd, how);
648 if (ret < 0) {
649 errno = socket_error();
650 }
651 return ret;
652}
653
654
655#undef ioctlsocket
656int qemu_ioctlsocket_wrap(int fd, int req, void *val)
657{
658 int ret;
659 ret = ioctlsocket(fd, req, val);
660 if (ret < 0) {
661 errno = socket_error();
662 }
663 return ret;
664}
665
666
667#undef closesocket
668int qemu_closesocket_wrap(int fd)
669{
670 int ret;
671 ret = closesocket(fd);
672 if (ret < 0) {
673 errno = socket_error();
674 }
675 return ret;
676}
677
678
679#undef getsockopt
680int qemu_getsockopt_wrap(int sockfd, int level, int optname,
681 void *optval, socklen_t *optlen)
682{
683 int ret;
684 ret = getsockopt(sockfd, level, optname, optval, optlen);
685 if (ret < 0) {
686 errno = socket_error();
687 }
688 return ret;
689}
690
691
692#undef setsockopt
693int qemu_setsockopt_wrap(int sockfd, int level, int optname,
694 const void *optval, socklen_t optlen)
695{
696 int ret;
697 ret = setsockopt(sockfd, level, optname, optval, optlen);
698 if (ret < 0) {
699 errno = socket_error();
700 }
701 return ret;
702}
703
704
705#undef getpeername
706int qemu_getpeername_wrap(int sockfd, struct sockaddr *addr,
707 socklen_t *addrlen)
708{
709 int ret;
710 ret = getpeername(sockfd, addr, addrlen);
711 if (ret < 0) {
712 errno = socket_error();
713 }
714 return ret;
715}
716
717
718#undef getsockname
719int qemu_getsockname_wrap(int sockfd, struct sockaddr *addr,
720 socklen_t *addrlen)
721{
722 int ret;
723 ret = getsockname(sockfd, addr, addrlen);
724 if (ret < 0) {
725 errno = socket_error();
726 }
727 return ret;
728}
729
730
731#undef send
732ssize_t qemu_send_wrap(int sockfd, const void *buf, size_t len, int flags)
733{
734 int ret;
735 ret = send(sockfd, buf, len, flags);
736 if (ret < 0) {
737 errno = socket_error();
738 }
739 return ret;
740}
741
742
743#undef sendto
744ssize_t qemu_sendto_wrap(int sockfd, const void *buf, size_t len, int flags,
745 const struct sockaddr *addr, socklen_t addrlen)
746{
747 int ret;
748 ret = sendto(sockfd, buf, len, flags, addr, addrlen);
749 if (ret < 0) {
750 errno = socket_error();
751 }
752 return ret;
753}
754
755
756#undef recv
757ssize_t qemu_recv_wrap(int sockfd, void *buf, size_t len, int flags)
758{
759 int ret;
760 ret = recv(sockfd, buf, len, flags);
761 if (ret < 0) {
762 errno = socket_error();
763 }
764 return ret;
765}
766
767
768#undef recvfrom
769ssize_t qemu_recvfrom_wrap(int sockfd, void *buf, size_t len, int flags,
770 struct sockaddr *addr, socklen_t *addrlen)
771{
772 int ret;
773 ret = recvfrom(sockfd, buf, len, flags, addr, addrlen);
774 if (ret < 0) {
775 errno = socket_error();
776 }
777 return ret;
778}
779
780bool qemu_write_pidfile(const char *filename, Error **errp)
781{
782 char buffer[128];
783 int len;
784 HANDLE file;
785 OVERLAPPED overlap;
786 BOOL ret;
787 memset(&overlap, 0, sizeof(overlap));
788
789 file = CreateFile(filename, GENERIC_WRITE, FILE_SHARE_READ, NULL,
790 OPEN_ALWAYS, FILE_ATTRIBUTE_NORMAL, NULL);
791
792 if (file == INVALID_HANDLE_VALUE) {
793 error_setg(errp, "Failed to create PID file");
794 return false;
795 }
796 len = snprintf(buffer, sizeof(buffer), FMT_pid "\n", (pid_t)getpid());
797 ret = WriteFile(file, (LPCVOID)buffer, (DWORD)len,
798 NULL, &overlap);
799 CloseHandle(file);
800 if (ret == 0) {
801 error_setg(errp, "Failed to write PID file");
802 return false;
803 }
804 return true;
805}
806