]> git.proxmox.com Git - mirror_qemu.git/blob - util/oslib-win32.c
util: Unify implementations of qemu_memalign()
[mirror_qemu.git] / util / oslib-win32.c
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 "qemu/main-loop.h"
38 #include "trace.h"
39 #include "qemu/sockets.h"
40 #include "qemu/cutils.h"
41 #include "qemu/error-report.h"
42 #include <malloc.h>
43
44 /* this must come after including "trace.h" */
45 #include <shlobj.h>
46
47 void *qemu_try_memalign(size_t alignment, size_t size)
48 {
49 void *ptr;
50
51 g_assert(size != 0);
52 if (alignment < sizeof(void *)) {
53 alignment = sizeof(void *);
54 } else {
55 g_assert(is_power_of_2(alignment));
56 }
57 ptr = _aligned_malloc(size, alignment);
58 trace_qemu_memalign(alignment, size, ptr);
59 return ptr;
60 }
61
62 static int get_allocation_granularity(void)
63 {
64 SYSTEM_INFO system_info;
65
66 GetSystemInfo(&system_info);
67 return system_info.dwAllocationGranularity;
68 }
69
70 void *qemu_anon_ram_alloc(size_t size, uint64_t *align, bool shared,
71 bool noreserve)
72 {
73 void *ptr;
74
75 if (noreserve) {
76 /*
77 * We need a MEM_COMMIT before accessing any memory in a MEM_RESERVE
78 * area; we cannot easily mimic POSIX MAP_NORESERVE semantics.
79 */
80 error_report("Skipping reservation of swap space is not supported.");
81 return NULL;
82 }
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 _aligned_free(ptr);
97 }
98
99 void 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 _POSIX_THREAD_SAFE_FUNCTIONS
108 /* FIXME: add proper locking */
109 struct 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 /* FIXME: add proper locking */
121 struct 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 /* _POSIX_THREAD_SAFE_FUNCTIONS */
132
133 static int socket_error(void)
134 {
135 switch (WSAGetLastError()) {
136 case 0:
137 return 0;
138 case WSAEINTR:
139 return EINTR;
140 case WSAEINVAL:
141 return EINVAL;
142 case WSA_INVALID_HANDLE:
143 return EBADF;
144 case WSA_NOT_ENOUGH_MEMORY:
145 return ENOMEM;
146 case WSA_INVALID_PARAMETER:
147 return EINVAL;
148 case WSAENAMETOOLONG:
149 return ENAMETOOLONG;
150 case WSAENOTEMPTY:
151 return ENOTEMPTY;
152 case WSAEWOULDBLOCK:
153 /* not using EWOULDBLOCK as we don't want code to have
154 * to check both EWOULDBLOCK and EAGAIN */
155 return EAGAIN;
156 case WSAEINPROGRESS:
157 return EINPROGRESS;
158 case WSAEALREADY:
159 return EALREADY;
160 case WSAENOTSOCK:
161 return ENOTSOCK;
162 case WSAEDESTADDRREQ:
163 return EDESTADDRREQ;
164 case WSAEMSGSIZE:
165 return EMSGSIZE;
166 case WSAEPROTOTYPE:
167 return EPROTOTYPE;
168 case WSAENOPROTOOPT:
169 return ENOPROTOOPT;
170 case WSAEPROTONOSUPPORT:
171 return EPROTONOSUPPORT;
172 case WSAEOPNOTSUPP:
173 return EOPNOTSUPP;
174 case WSAEAFNOSUPPORT:
175 return EAFNOSUPPORT;
176 case WSAEADDRINUSE:
177 return EADDRINUSE;
178 case WSAEADDRNOTAVAIL:
179 return EADDRNOTAVAIL;
180 case WSAENETDOWN:
181 return ENETDOWN;
182 case WSAENETUNREACH:
183 return ENETUNREACH;
184 case WSAENETRESET:
185 return ENETRESET;
186 case WSAECONNABORTED:
187 return ECONNABORTED;
188 case WSAECONNRESET:
189 return ECONNRESET;
190 case WSAENOBUFS:
191 return ENOBUFS;
192 case WSAEISCONN:
193 return EISCONN;
194 case WSAENOTCONN:
195 return ENOTCONN;
196 case WSAETIMEDOUT:
197 return ETIMEDOUT;
198 case WSAECONNREFUSED:
199 return ECONNREFUSED;
200 case WSAELOOP:
201 return ELOOP;
202 case WSAEHOSTUNREACH:
203 return EHOSTUNREACH;
204 default:
205 return EIO;
206 }
207 }
208
209 void qemu_set_block(int fd)
210 {
211 unsigned long opt = 0;
212 WSAEventSelect(fd, NULL, 0);
213 ioctlsocket(fd, FIONBIO, &opt);
214 }
215
216 int qemu_try_set_nonblock(int fd)
217 {
218 unsigned long opt = 1;
219 if (ioctlsocket(fd, FIONBIO, &opt) != NO_ERROR) {
220 return -socket_error();
221 }
222 return 0;
223 }
224
225 void qemu_set_nonblock(int fd)
226 {
227 (void)qemu_try_set_nonblock(fd);
228 }
229
230 int socket_set_fast_reuse(int fd)
231 {
232 /* Enabling the reuse of an endpoint that was used by a socket still in
233 * TIME_WAIT state is usually performed by setting SO_REUSEADDR. On Windows
234 * fast reuse is the default and SO_REUSEADDR does strange things. So we
235 * don't have to do anything here. More info can be found at:
236 * http://msdn.microsoft.com/en-us/library/windows/desktop/ms740621.aspx */
237 return 0;
238 }
239
240 int inet_aton(const char *cp, struct in_addr *ia)
241 {
242 uint32_t addr = inet_addr(cp);
243 if (addr == 0xffffffff) {
244 return 0;
245 }
246 ia->s_addr = addr;
247 return 1;
248 }
249
250 void qemu_set_cloexec(int fd)
251 {
252 }
253
254 /* Offset between 1/1/1601 and 1/1/1970 in 100 nanosec units */
255 #define _W32_FT_OFFSET (116444736000000000ULL)
256
257 int qemu_gettimeofday(qemu_timeval *tp)
258 {
259 union {
260 unsigned long long ns100; /*time since 1 Jan 1601 in 100ns units */
261 FILETIME ft;
262 } _now;
263
264 if(tp) {
265 GetSystemTimeAsFileTime (&_now.ft);
266 tp->tv_usec=(long)((_now.ns100 / 10ULL) % 1000000ULL );
267 tp->tv_sec= (long)((_now.ns100 - _W32_FT_OFFSET) / 10000000ULL);
268 }
269 /* Always return 0 as per Open Group Base Specifications Issue 6.
270 Do not set errno on error. */
271 return 0;
272 }
273
274 int qemu_get_thread_id(void)
275 {
276 return GetCurrentThreadId();
277 }
278
279 char *
280 qemu_get_local_state_pathname(const char *relative_pathname)
281 {
282 HRESULT result;
283 char base_path[MAX_PATH+1] = "";
284
285 result = SHGetFolderPath(NULL, CSIDL_COMMON_APPDATA, NULL,
286 /* SHGFP_TYPE_CURRENT */ 0, base_path);
287 if (result != S_OK) {
288 /* misconfigured environment */
289 g_critical("CSIDL_COMMON_APPDATA unavailable: %ld", (long)result);
290 abort();
291 }
292 return g_strdup_printf("%s" G_DIR_SEPARATOR_S "%s", base_path,
293 relative_pathname);
294 }
295
296 void qemu_set_tty_echo(int fd, bool echo)
297 {
298 HANDLE handle = (HANDLE)_get_osfhandle(fd);
299 DWORD dwMode = 0;
300
301 if (handle == INVALID_HANDLE_VALUE) {
302 return;
303 }
304
305 GetConsoleMode(handle, &dwMode);
306
307 if (echo) {
308 SetConsoleMode(handle, dwMode | ENABLE_ECHO_INPUT | ENABLE_LINE_INPUT);
309 } else {
310 SetConsoleMode(handle,
311 dwMode & ~(ENABLE_ECHO_INPUT | ENABLE_LINE_INPUT));
312 }
313 }
314
315 static const char *exec_dir;
316
317 void qemu_init_exec_dir(const char *argv0)
318 {
319
320 char *p;
321 char buf[MAX_PATH];
322 DWORD len;
323
324 if (exec_dir) {
325 return;
326 }
327
328 len = GetModuleFileName(NULL, buf, sizeof(buf) - 1);
329 if (len == 0) {
330 return;
331 }
332
333 buf[len] = 0;
334 p = buf + len - 1;
335 while (p != buf && *p != '\\') {
336 p--;
337 }
338 *p = 0;
339 if (access(buf, R_OK) == 0) {
340 exec_dir = g_strdup(buf);
341 } else {
342 exec_dir = CONFIG_BINDIR;
343 }
344 }
345
346 const char *qemu_get_exec_dir(void)
347 {
348 return exec_dir;
349 }
350
351 int getpagesize(void)
352 {
353 SYSTEM_INFO system_info;
354
355 GetSystemInfo(&system_info);
356 return system_info.dwPageSize;
357 }
358
359 void os_mem_prealloc(int fd, char *area, size_t memory, int smp_cpus,
360 Error **errp)
361 {
362 int i;
363 size_t pagesize = qemu_real_host_page_size;
364
365 memory = (memory + pagesize - 1) & -pagesize;
366 for (i = 0; i < memory / pagesize; i++) {
367 memset(area + pagesize * i, 0, 1);
368 }
369 }
370
371 char *qemu_get_pid_name(pid_t pid)
372 {
373 /* XXX Implement me */
374 abort();
375 }
376
377
378 pid_t qemu_fork(Error **errp)
379 {
380 errno = ENOSYS;
381 error_setg_errno(errp, errno,
382 "cannot fork child process");
383 return -1;
384 }
385
386
387 #undef connect
388 int qemu_connect_wrap(int sockfd, const struct sockaddr *addr,
389 socklen_t addrlen)
390 {
391 int ret;
392 ret = connect(sockfd, addr, addrlen);
393 if (ret < 0) {
394 if (WSAGetLastError() == WSAEWOULDBLOCK) {
395 errno = EINPROGRESS;
396 } else {
397 errno = socket_error();
398 }
399 }
400 return ret;
401 }
402
403
404 #undef listen
405 int qemu_listen_wrap(int sockfd, int backlog)
406 {
407 int ret;
408 ret = listen(sockfd, backlog);
409 if (ret < 0) {
410 errno = socket_error();
411 }
412 return ret;
413 }
414
415
416 #undef bind
417 int qemu_bind_wrap(int sockfd, const struct sockaddr *addr,
418 socklen_t addrlen)
419 {
420 int ret;
421 ret = bind(sockfd, addr, addrlen);
422 if (ret < 0) {
423 errno = socket_error();
424 }
425 return ret;
426 }
427
428
429 #undef socket
430 int qemu_socket_wrap(int domain, int type, int protocol)
431 {
432 int ret;
433 ret = socket(domain, type, protocol);
434 if (ret < 0) {
435 errno = socket_error();
436 }
437 return ret;
438 }
439
440
441 #undef accept
442 int qemu_accept_wrap(int sockfd, struct sockaddr *addr,
443 socklen_t *addrlen)
444 {
445 int ret;
446 ret = accept(sockfd, addr, addrlen);
447 if (ret < 0) {
448 errno = socket_error();
449 }
450 return ret;
451 }
452
453
454 #undef shutdown
455 int qemu_shutdown_wrap(int sockfd, int how)
456 {
457 int ret;
458 ret = shutdown(sockfd, how);
459 if (ret < 0) {
460 errno = socket_error();
461 }
462 return ret;
463 }
464
465
466 #undef ioctlsocket
467 int qemu_ioctlsocket_wrap(int fd, int req, void *val)
468 {
469 int ret;
470 ret = ioctlsocket(fd, req, val);
471 if (ret < 0) {
472 errno = socket_error();
473 }
474 return ret;
475 }
476
477
478 #undef closesocket
479 int qemu_closesocket_wrap(int fd)
480 {
481 int ret;
482 ret = closesocket(fd);
483 if (ret < 0) {
484 errno = socket_error();
485 }
486 return ret;
487 }
488
489
490 #undef getsockopt
491 int qemu_getsockopt_wrap(int sockfd, int level, int optname,
492 void *optval, socklen_t *optlen)
493 {
494 int ret;
495 ret = getsockopt(sockfd, level, optname, optval, optlen);
496 if (ret < 0) {
497 errno = socket_error();
498 }
499 return ret;
500 }
501
502
503 #undef setsockopt
504 int qemu_setsockopt_wrap(int sockfd, int level, int optname,
505 const void *optval, socklen_t optlen)
506 {
507 int ret;
508 ret = setsockopt(sockfd, level, optname, optval, optlen);
509 if (ret < 0) {
510 errno = socket_error();
511 }
512 return ret;
513 }
514
515
516 #undef getpeername
517 int qemu_getpeername_wrap(int sockfd, struct sockaddr *addr,
518 socklen_t *addrlen)
519 {
520 int ret;
521 ret = getpeername(sockfd, addr, addrlen);
522 if (ret < 0) {
523 errno = socket_error();
524 }
525 return ret;
526 }
527
528
529 #undef getsockname
530 int qemu_getsockname_wrap(int sockfd, struct sockaddr *addr,
531 socklen_t *addrlen)
532 {
533 int ret;
534 ret = getsockname(sockfd, addr, addrlen);
535 if (ret < 0) {
536 errno = socket_error();
537 }
538 return ret;
539 }
540
541
542 #undef send
543 ssize_t qemu_send_wrap(int sockfd, const void *buf, size_t len, int flags)
544 {
545 int ret;
546 ret = send(sockfd, buf, len, flags);
547 if (ret < 0) {
548 errno = socket_error();
549 }
550 return ret;
551 }
552
553
554 #undef sendto
555 ssize_t qemu_sendto_wrap(int sockfd, const void *buf, size_t len, int flags,
556 const struct sockaddr *addr, socklen_t addrlen)
557 {
558 int ret;
559 ret = sendto(sockfd, buf, len, flags, addr, addrlen);
560 if (ret < 0) {
561 errno = socket_error();
562 }
563 return ret;
564 }
565
566
567 #undef recv
568 ssize_t qemu_recv_wrap(int sockfd, void *buf, size_t len, int flags)
569 {
570 int ret;
571 ret = recv(sockfd, buf, len, flags);
572 if (ret < 0) {
573 errno = socket_error();
574 }
575 return ret;
576 }
577
578
579 #undef recvfrom
580 ssize_t qemu_recvfrom_wrap(int sockfd, void *buf, size_t len, int flags,
581 struct sockaddr *addr, socklen_t *addrlen)
582 {
583 int ret;
584 ret = recvfrom(sockfd, buf, len, flags, addr, addrlen);
585 if (ret < 0) {
586 errno = socket_error();
587 }
588 return ret;
589 }
590
591 bool qemu_write_pidfile(const char *filename, Error **errp)
592 {
593 char buffer[128];
594 int len;
595 HANDLE file;
596 OVERLAPPED overlap;
597 BOOL ret;
598 memset(&overlap, 0, sizeof(overlap));
599
600 file = CreateFile(filename, GENERIC_WRITE, FILE_SHARE_READ, NULL,
601 OPEN_ALWAYS, FILE_ATTRIBUTE_NORMAL, NULL);
602
603 if (file == INVALID_HANDLE_VALUE) {
604 error_setg(errp, "Failed to create PID file");
605 return false;
606 }
607 len = snprintf(buffer, sizeof(buffer), FMT_pid "\n", (pid_t)getpid());
608 ret = WriteFile(file, (LPCVOID)buffer, (DWORD)len,
609 NULL, &overlap);
610 CloseHandle(file);
611 if (ret == 0) {
612 error_setg(errp, "Failed to write PID file");
613 return false;
614 }
615 return true;
616 }
617
618 char *qemu_get_host_name(Error **errp)
619 {
620 wchar_t tmp[MAX_COMPUTERNAME_LENGTH + 1];
621 DWORD size = G_N_ELEMENTS(tmp);
622
623 if (GetComputerNameW(tmp, &size) == 0) {
624 error_setg_win32(errp, GetLastError(), "failed close handle");
625 return NULL;
626 }
627
628 return g_utf16_to_utf8(tmp, size, NULL, NULL, NULL);
629 }
630
631 size_t qemu_get_host_physmem(void)
632 {
633 MEMORYSTATUSEX statex;
634 statex.dwLength = sizeof(statex);
635
636 if (GlobalMemoryStatusEx(&statex)) {
637 return statex.ullTotalPhys;
638 }
639 return 0;
640 }