Home | History | Annotate | Download | only in qemu
      1 /*
      2  * os-win32.c
      3  *
      4  * Copyright (c) 2003-2008 Fabrice Bellard
      5  * Copyright (c) 2010 Red Hat, Inc.
      6  *
      7  * Permission is hereby granted, free of charge, to any person obtaining a copy
      8  * of this software and associated documentation files (the "Software"), to deal
      9  * in the Software without restriction, including without limitation the rights
     10  * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
     11  * copies of the Software, and to permit persons to whom the Software is
     12  * furnished to do so, subject to the following conditions:
     13  *
     14  * The above copyright notice and this permission notice shall be included in
     15  * all copies or substantial portions of the Software.
     16  *
     17  * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
     18  * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
     19  * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
     20  * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
     21  * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
     22  * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
     23  * THE SOFTWARE.
     24  */
     25 #include <windows.h>
     26 #include <unistd.h>
     27 #include <fcntl.h>
     28 #include <signal.h>
     29 #include <time.h>
     30 #include <errno.h>
     31 #include <sys/time.h>
     32 #include "config-host.h"
     33 #include "sysemu/sysemu.h"
     34 #include "qemu-options.h"
     35 
     36 /***********************************************************/
     37 /* Functions missing in mingw */
     38 
     39 int setenv(const char *name, const char *value, int overwrite)
     40 {
     41     int result = 0;
     42     if (overwrite || !getenv(name)) {
     43         size_t length = strlen(name) + strlen(value) + 2;
     44         char *string = g_malloc(length);
     45         snprintf(string, length, "%s=%s", name, value);
     46         result = putenv(string);
     47     }
     48     return result;
     49 }
     50 
     51 static BOOL WINAPI qemu_ctrl_handler(DWORD type)
     52 {
     53     exit(STATUS_CONTROL_C_EXIT);
     54     return TRUE;
     55 }
     56 
     57 void os_setup_early_signal_handling(void)
     58 {
     59     /* Note: cpu_interrupt() is currently not SMP safe, so we force
     60        QEMU to run on a single CPU */
     61     HANDLE h;
     62     DWORD_PTR mask, smask;
     63     int i;
     64 
     65     SetConsoleCtrlHandler(qemu_ctrl_handler, TRUE);
     66 
     67     h = GetCurrentProcess();
     68     if (GetProcessAffinityMask(h, &mask, &smask)) {
     69         for(i = 0; i < 32; i++) {
     70             if (mask & (1 << i))
     71                 break;
     72         }
     73         if (i != 32) {
     74             mask = 1 << i;
     75             SetProcessAffinityMask(h, mask);
     76         }
     77     }
     78 }
     79 
     80 /* Look for support files in the same directory as the executable.  */
     81 char *os_find_datadir(const char *argv0)
     82 {
     83     char *p;
     84     char buf[MAX_PATH];
     85     DWORD len;
     86 
     87     len = GetModuleFileName(NULL, buf, sizeof(buf) - 1);
     88     if (len == 0) {
     89         return NULL;
     90     }
     91 
     92     buf[len] = 0;
     93     p = buf + len - 1;
     94     while (p != buf && *p != '\\')
     95         p--;
     96     *p = 0;
     97     if (access(buf, R_OK) == 0) {
     98         return g_strdup(buf);
     99     }
    100     return NULL;
    101 }
    102 
    103 void os_set_line_buffering(void)
    104 {
    105     setbuf(stdout, NULL);
    106     setbuf(stderr, NULL);
    107 }
    108 
    109 /*
    110  * Parse OS specific command line options.
    111  * return 0 if option handled, -1 otherwise
    112  */
    113 void os_parse_cmd_args(int index, const char *optarg)
    114 {
    115     return;
    116 }
    117 
    118 void os_pidfile_error(void)
    119 {
    120     fprintf(stderr, "Could not acquire pid file: %s\n", strerror(errno));
    121 }
    122 
    123 int qemu_create_pidfile(const char *filename)
    124 {
    125     char buffer[128];
    126     int len;
    127     HANDLE file;
    128     OVERLAPPED overlap;
    129     BOOL ret;
    130     memset(&overlap, 0, sizeof(overlap));
    131 
    132     file = CreateFile(filename, GENERIC_WRITE, FILE_SHARE_READ, NULL,
    133 		      OPEN_ALWAYS, FILE_ATTRIBUTE_NORMAL, NULL);
    134 
    135     if (file == INVALID_HANDLE_VALUE) {
    136         return -1;
    137     }
    138     len = snprintf(buffer, sizeof(buffer), "%ld\n", (long)getpid());
    139     ret = WriteFileEx(file, (LPCVOID)buffer, (DWORD)len,
    140 		      &overlap, NULL);
    141     if (ret == 0) {
    142         return -1;
    143     }
    144     return 0;
    145 }
    146