qemu

FORK: QEMU emulator
git clone https://git.neptards.moe/neptards/qemu.git
Log | Files | Refs | Submodules | LICENSE

oslib-win32.c (12748B)


      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 }