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