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 "qapi/error.h" 36 #include "qemu/main-loop.h" 37 #include "trace.h" 38 #include "qemu/sockets.h" 39 #include "qemu/cutils.h" 40 #include "qemu/error-report.h" 41 #include <malloc.h> 42 43 static int get_allocation_granularity(void) 44 { 45 SYSTEM_INFO system_info; 46 47 GetSystemInfo(&system_info); 48 return system_info.dwAllocationGranularity; 49 } 50 51 void *qemu_anon_ram_alloc(size_t size, uint64_t *align, bool shared, 52 bool noreserve) 53 { 54 void *ptr; 55 56 if (noreserve) { 57 /* 58 * We need a MEM_COMMIT before accessing any memory in a MEM_RESERVE 59 * area; we cannot easily mimic POSIX MAP_NORESERVE semantics. 60 */ 61 error_report("Skipping reservation of swap space is not supported."); 62 return NULL; 63 } 64 65 ptr = VirtualAlloc(NULL, size, MEM_COMMIT, PAGE_READWRITE); 66 trace_qemu_anon_ram_alloc(size, ptr); 67 68 if (ptr && align) { 69 *align = MAX(get_allocation_granularity(), getpagesize()); 70 } 71 return ptr; 72 } 73 74 void qemu_anon_ram_free(void *ptr, size_t size) 75 { 76 trace_qemu_anon_ram_free(ptr, size); 77 if (ptr) { 78 VirtualFree(ptr, 0, MEM_RELEASE); 79 } 80 } 81 82 #ifndef _POSIX_THREAD_SAFE_FUNCTIONS 83 /* FIXME: add proper locking */ 84 struct tm *gmtime_r(const time_t *timep, struct tm *result) 85 { 86 struct tm *p = gmtime(timep); 87 memset(result, 0, sizeof(*result)); 88 if (p) { 89 *result = *p; 90 p = result; 91 } 92 return p; 93 } 94 95 /* FIXME: add proper locking */ 96 struct tm *localtime_r(const time_t *timep, struct tm *result) 97 { 98 struct tm *p = localtime(timep); 99 memset(result, 0, sizeof(*result)); 100 if (p) { 101 *result = *p; 102 p = result; 103 } 104 return p; 105 } 106 #endif /* _POSIX_THREAD_SAFE_FUNCTIONS */ 107 108 static int socket_error(void) 109 { 110 switch (WSAGetLastError()) { 111 case 0: 112 return 0; 113 case WSAEINTR: 114 return EINTR; 115 case WSAEINVAL: 116 return EINVAL; 117 case WSA_INVALID_HANDLE: 118 return EBADF; 119 case WSA_NOT_ENOUGH_MEMORY: 120 return ENOMEM; 121 case WSA_INVALID_PARAMETER: 122 return EINVAL; 123 case WSAENAMETOOLONG: 124 return ENAMETOOLONG; 125 case WSAENOTEMPTY: 126 return ENOTEMPTY; 127 case WSAEWOULDBLOCK: 128 /* not using EWOULDBLOCK as we don't want code to have 129 * to check both EWOULDBLOCK and EAGAIN */ 130 return EAGAIN; 131 case WSAEINPROGRESS: 132 return EINPROGRESS; 133 case WSAEALREADY: 134 return EALREADY; 135 case WSAENOTSOCK: 136 return ENOTSOCK; 137 case WSAEDESTADDRREQ: 138 return EDESTADDRREQ; 139 case WSAEMSGSIZE: 140 return EMSGSIZE; 141 case WSAEPROTOTYPE: 142 return EPROTOTYPE; 143 case WSAENOPROTOOPT: 144 return ENOPROTOOPT; 145 case WSAEPROTONOSUPPORT: 146 return EPROTONOSUPPORT; 147 case WSAEOPNOTSUPP: 148 return EOPNOTSUPP; 149 case WSAEAFNOSUPPORT: 150 return EAFNOSUPPORT; 151 case WSAEADDRINUSE: 152 return EADDRINUSE; 153 case WSAEADDRNOTAVAIL: 154 return EADDRNOTAVAIL; 155 case WSAENETDOWN: 156 return ENETDOWN; 157 case WSAENETUNREACH: 158 return ENETUNREACH; 159 case WSAENETRESET: 160 return ENETRESET; 161 case WSAECONNABORTED: 162 return ECONNABORTED; 163 case WSAECONNRESET: 164 return ECONNRESET; 165 case WSAENOBUFS: 166 return ENOBUFS; 167 case WSAEISCONN: 168 return EISCONN; 169 case WSAENOTCONN: 170 return ENOTCONN; 171 case WSAETIMEDOUT: 172 return ETIMEDOUT; 173 case WSAECONNREFUSED: 174 return ECONNREFUSED; 175 case WSAELOOP: 176 return ELOOP; 177 case WSAEHOSTUNREACH: 178 return EHOSTUNREACH; 179 default: 180 return EIO; 181 } 182 } 183 184 void qemu_socket_set_block(int fd) 185 { 186 unsigned long opt = 0; 187 WSAEventSelect(fd, NULL, 0); 188 ioctlsocket(fd, FIONBIO, &opt); 189 } 190 191 int qemu_socket_try_set_nonblock(int fd) 192 { 193 unsigned long opt = 1; 194 if (ioctlsocket(fd, FIONBIO, &opt) != NO_ERROR) { 195 return -socket_error(); 196 } 197 return 0; 198 } 199 200 void qemu_socket_set_nonblock(int fd) 201 { 202 (void)qemu_socket_try_set_nonblock(fd); 203 } 204 205 int socket_set_fast_reuse(int fd) 206 { 207 /* Enabling the reuse of an endpoint that was used by a socket still in 208 * TIME_WAIT state is usually performed by setting SO_REUSEADDR. On Windows 209 * fast reuse is the default and SO_REUSEADDR does strange things. So we 210 * don't have to do anything here. More info can be found at: 211 * http://msdn.microsoft.com/en-us/library/windows/desktop/ms740621.aspx */ 212 return 0; 213 } 214 215 int inet_aton(const char *cp, struct in_addr *ia) 216 { 217 uint32_t addr = inet_addr(cp); 218 if (addr == 0xffffffff) { 219 return 0; 220 } 221 ia->s_addr = addr; 222 return 1; 223 } 224 225 void qemu_set_cloexec(int fd) 226 { 227 } 228 229 int qemu_get_thread_id(void) 230 { 231 return GetCurrentThreadId(); 232 } 233 234 char * 235 qemu_get_local_state_dir(void) 236 { 237 const char * const *data_dirs = g_get_system_data_dirs(); 238 239 g_assert(data_dirs && data_dirs[0]); 240 241 return g_strdup(data_dirs[0]); 242 } 243 244 void qemu_set_tty_echo(int fd, bool echo) 245 { 246 HANDLE handle = (HANDLE)_get_osfhandle(fd); 247 DWORD dwMode = 0; 248 249 if (handle == INVALID_HANDLE_VALUE) { 250 return; 251 } 252 253 GetConsoleMode(handle, &dwMode); 254 255 if (echo) { 256 SetConsoleMode(handle, dwMode | ENABLE_ECHO_INPUT | ENABLE_LINE_INPUT); 257 } else { 258 SetConsoleMode(handle, 259 dwMode & ~(ENABLE_ECHO_INPUT | ENABLE_LINE_INPUT)); 260 } 261 } 262 263 int getpagesize(void) 264 { 265 SYSTEM_INFO system_info; 266 267 GetSystemInfo(&system_info); 268 return system_info.dwPageSize; 269 } 270 271 void qemu_prealloc_mem(int fd, char *area, size_t sz, int max_threads, 272 ThreadContext *tc, Error **errp) 273 { 274 int i; 275 size_t pagesize = qemu_real_host_page_size(); 276 277 sz = (sz + pagesize - 1) & -pagesize; 278 for (i = 0; i < sz / pagesize; i++) { 279 memset(area + pagesize * i, 0, 1); 280 } 281 } 282 283 char *qemu_get_pid_name(pid_t pid) 284 { 285 /* XXX Implement me */ 286 abort(); 287 } 288 289 290 pid_t qemu_fork(Error **errp) 291 { 292 errno = ENOSYS; 293 error_setg_errno(errp, errno, 294 "cannot fork child process"); 295 return -1; 296 } 297 298 299 #undef connect 300 int qemu_connect_wrap(int sockfd, const struct sockaddr *addr, 301 socklen_t addrlen) 302 { 303 int ret; 304 ret = connect(sockfd, addr, addrlen); 305 if (ret < 0) { 306 if (WSAGetLastError() == WSAEWOULDBLOCK) { 307 errno = EINPROGRESS; 308 } else { 309 errno = socket_error(); 310 } 311 } 312 return ret; 313 } 314 315 316 #undef listen 317 int qemu_listen_wrap(int sockfd, int backlog) 318 { 319 int ret; 320 ret = listen(sockfd, backlog); 321 if (ret < 0) { 322 errno = socket_error(); 323 } 324 return ret; 325 } 326 327 328 #undef bind 329 int qemu_bind_wrap(int sockfd, const struct sockaddr *addr, 330 socklen_t addrlen) 331 { 332 int ret; 333 ret = bind(sockfd, addr, addrlen); 334 if (ret < 0) { 335 errno = socket_error(); 336 } 337 return ret; 338 } 339 340 341 #undef socket 342 int qemu_socket_wrap(int domain, int type, int protocol) 343 { 344 int ret; 345 ret = socket(domain, type, protocol); 346 if (ret < 0) { 347 errno = socket_error(); 348 } 349 return ret; 350 } 351 352 353 #undef accept 354 int qemu_accept_wrap(int sockfd, struct sockaddr *addr, 355 socklen_t *addrlen) 356 { 357 int ret; 358 ret = accept(sockfd, addr, addrlen); 359 if (ret < 0) { 360 errno = socket_error(); 361 } 362 return ret; 363 } 364 365 366 #undef shutdown 367 int qemu_shutdown_wrap(int sockfd, int how) 368 { 369 int ret; 370 ret = shutdown(sockfd, how); 371 if (ret < 0) { 372 errno = socket_error(); 373 } 374 return ret; 375 } 376 377 378 #undef ioctlsocket 379 int qemu_ioctlsocket_wrap(int fd, int req, void *val) 380 { 381 int ret; 382 ret = ioctlsocket(fd, req, val); 383 if (ret < 0) { 384 errno = socket_error(); 385 } 386 return ret; 387 } 388 389 390 #undef closesocket 391 int qemu_closesocket_wrap(int fd) 392 { 393 int ret; 394 ret = closesocket(fd); 395 if (ret < 0) { 396 errno = socket_error(); 397 } 398 return ret; 399 } 400 401 402 #undef getsockopt 403 int qemu_getsockopt_wrap(int sockfd, int level, int optname, 404 void *optval, socklen_t *optlen) 405 { 406 int ret; 407 ret = getsockopt(sockfd, level, optname, optval, optlen); 408 if (ret < 0) { 409 errno = socket_error(); 410 } 411 return ret; 412 } 413 414 415 #undef setsockopt 416 int qemu_setsockopt_wrap(int sockfd, int level, int optname, 417 const void *optval, socklen_t optlen) 418 { 419 int ret; 420 ret = setsockopt(sockfd, level, optname, optval, optlen); 421 if (ret < 0) { 422 errno = socket_error(); 423 } 424 return ret; 425 } 426 427 428 #undef getpeername 429 int qemu_getpeername_wrap(int sockfd, struct sockaddr *addr, 430 socklen_t *addrlen) 431 { 432 int ret; 433 ret = getpeername(sockfd, addr, addrlen); 434 if (ret < 0) { 435 errno = socket_error(); 436 } 437 return ret; 438 } 439 440 441 #undef getsockname 442 int qemu_getsockname_wrap(int sockfd, struct sockaddr *addr, 443 socklen_t *addrlen) 444 { 445 int ret; 446 ret = getsockname(sockfd, addr, addrlen); 447 if (ret < 0) { 448 errno = socket_error(); 449 } 450 return ret; 451 } 452 453 454 #undef send 455 ssize_t qemu_send_wrap(int sockfd, const void *buf, size_t len, int flags) 456 { 457 int ret; 458 ret = send(sockfd, buf, len, flags); 459 if (ret < 0) { 460 errno = socket_error(); 461 } 462 return ret; 463 } 464 465 466 #undef sendto 467 ssize_t qemu_sendto_wrap(int sockfd, const void *buf, size_t len, int flags, 468 const struct sockaddr *addr, socklen_t addrlen) 469 { 470 int ret; 471 ret = sendto(sockfd, buf, len, flags, addr, addrlen); 472 if (ret < 0) { 473 errno = socket_error(); 474 } 475 return ret; 476 } 477 478 479 #undef recv 480 ssize_t qemu_recv_wrap(int sockfd, void *buf, size_t len, int flags) 481 { 482 int ret; 483 ret = recv(sockfd, buf, len, flags); 484 if (ret < 0) { 485 errno = socket_error(); 486 } 487 return ret; 488 } 489 490 491 #undef recvfrom 492 ssize_t qemu_recvfrom_wrap(int sockfd, void *buf, size_t len, int flags, 493 struct sockaddr *addr, socklen_t *addrlen) 494 { 495 int ret; 496 ret = recvfrom(sockfd, buf, len, flags, addr, addrlen); 497 if (ret < 0) { 498 errno = socket_error(); 499 } 500 return ret; 501 } 502 503 bool qemu_write_pidfile(const char *filename, Error **errp) 504 { 505 char buffer[128]; 506 int len; 507 HANDLE file; 508 OVERLAPPED overlap; 509 BOOL ret; 510 memset(&overlap, 0, sizeof(overlap)); 511 512 file = CreateFile(filename, GENERIC_WRITE, FILE_SHARE_READ, NULL, 513 OPEN_ALWAYS, FILE_ATTRIBUTE_NORMAL, NULL); 514 515 if (file == INVALID_HANDLE_VALUE) { 516 error_setg(errp, "Failed to create PID file"); 517 return false; 518 } 519 len = snprintf(buffer, sizeof(buffer), FMT_pid "\n", (pid_t)getpid()); 520 ret = WriteFile(file, (LPCVOID)buffer, (DWORD)len, 521 NULL, &overlap); 522 CloseHandle(file); 523 if (ret == 0) { 524 error_setg(errp, "Failed to write PID file"); 525 return false; 526 } 527 return true; 528 } 529 530 size_t qemu_get_host_physmem(void) 531 { 532 MEMORYSTATUSEX statex; 533 statex.dwLength = sizeof(statex); 534 535 if (GlobalMemoryStatusEx(&statex)) { 536 return statex.ullTotalPhys; 537 } 538 return 0; 539 } 540 541 int qemu_msync(void *addr, size_t length, int fd) 542 { 543 /** 544 * Perform the sync based on the file descriptor 545 * The sync range will most probably be wider than the one 546 * requested - but it will still get the job done 547 */ 548 return qemu_fdatasync(fd); 549 } 550