]> git.proxmox.com Git - qemu.git/blobdiff - os-win32.c
qdev-properties-system.c: Allow vlan or netdev for -device, not both
[qemu.git] / os-win32.c
index 5a464cc88a648f8072950c4b562443aec7f373f3..50b7f6f8859a70ef159c62a483f3dc59eec43c37 100644 (file)
@@ -23,6 +23,7 @@
  * THE SOFTWARE.
  */
 #include <windows.h>
+#include <mmsystem.h>
 #include <unistd.h>
 #include <fcntl.h>
 #include <signal.h>
 #include <errno.h>
 #include <sys/time.h>
 #include "config-host.h"
-#include "sysemu.h"
+#include "sysemu/sysemu.h"
+#include "qemu-options.h"
 
 /***********************************************************/
-/* Polling handling */
+/* Functions missing in mingw */
 
-typedef struct PollingEntry {
-    PollingFunc *func;
-    void *opaque;
-    struct PollingEntry *next;
-} PollingEntry;
+int setenv(const char *name, const char *value, int overwrite)
+{
+    int result = 0;
+    if (overwrite || !getenv(name)) {
+        size_t length = strlen(name) + strlen(value) + 2;
+        char *string = g_malloc(length);
+        snprintf(string, length, "%s=%s", name, value);
+        result = putenv(string);
 
-static PollingEntry *first_polling_entry;
+        /* Windows takes a copy and does not continue to use our string.
+         * Therefore it can be safely freed on this platform.  POSIX code
+         * typically has to leak the string because according to the spec it
+         * becomes part of the environment.
+         */
+        g_free(string);
+    }
+    return result;
+}
 
-int qemu_add_polling_cb(PollingFunc *func, void *opaque)
+static BOOL WINAPI qemu_ctrl_handler(DWORD type)
 {
-    PollingEntry **ppe, *pe;
-    pe = qemu_mallocz(sizeof(PollingEntry));
-    pe->func = func;
-    pe->opaque = opaque;
-    for(ppe = &first_polling_entry; *ppe != NULL; ppe = &(*ppe)->next);
-    *ppe = pe;
-    return 0;
+    qemu_system_shutdown_request();
+    /* Windows 7 kills application when the function returns.
+       Sleep here to give QEMU a try for closing.
+       Sleep period is 10000ms because Windows kills the program
+       after 10 seconds anyway. */
+    Sleep(10000);
+
+    return TRUE;
 }
 
-void qemu_del_polling_cb(PollingFunc *func, void *opaque)
+static TIMECAPS mm_tc;
+
+static void os_undo_timer_resolution(void)
 {
-    PollingEntry **ppe, *pe;
-    for(ppe = &first_polling_entry; *ppe != NULL; ppe = &(*ppe)->next) {
-        pe = *ppe;
-        if (pe->func == func && pe->opaque == opaque) {
-            *ppe = pe->next;
-            qemu_free(pe);
-            break;
-        }
-    }
+    timeEndPeriod(mm_tc.wPeriodMin);
 }
 
-/***********************************************************/
-/* Wait objects support */
-typedef struct WaitObjects {
-    int num;
-    HANDLE events[MAXIMUM_WAIT_OBJECTS + 1];
-    WaitObjectFunc *func[MAXIMUM_WAIT_OBJECTS + 1];
-    void *opaque[MAXIMUM_WAIT_OBJECTS + 1];
-} WaitObjects;
+void os_setup_early_signal_handling(void)
+{
+    SetConsoleCtrlHandler(qemu_ctrl_handler, TRUE);
+    timeGetDevCaps(&mm_tc, sizeof(mm_tc));
+    timeBeginPeriod(mm_tc.wPeriodMin);
+    atexit(os_undo_timer_resolution);
+}
+
+/* Look for support files in the same directory as the executable.  */
+char *os_find_datadir(const char *argv0)
+{
+    char *p;
+    char buf[MAX_PATH];
+    DWORD len;
 
-static WaitObjects wait_objects = {0};
+    len = GetModuleFileName(NULL, buf, sizeof(buf) - 1);
+    if (len == 0) {
+        return NULL;
+    }
+
+    buf[len] = 0;
+    p = buf + len - 1;
+    while (p != buf && *p != '\\')
+        p--;
+    *p = 0;
+    if (access(buf, R_OK) == 0) {
+        return g_strdup(buf);
+    }
+    return NULL;
+}
 
-int qemu_add_wait_object(HANDLE handle, WaitObjectFunc *func, void *opaque)
+void os_set_line_buffering(void)
 {
-    WaitObjects *w = &wait_objects;
+    setbuf(stdout, NULL);
+    setbuf(stderr, NULL);
+}
 
-    if (w->num >= MAXIMUM_WAIT_OBJECTS)
-        return -1;
-    w->events[w->num] = handle;
-    w->func[w->num] = func;
-    w->opaque[w->num] = opaque;
-    w->num++;
-    return 0;
+/*
+ * Parse OS specific command line options.
+ * return 0 if option handled, -1 otherwise
+ */
+void os_parse_cmd_args(int index, const char *optarg)
+{
+    return;
 }
 
-void qemu_del_wait_object(HANDLE handle, WaitObjectFunc *func, void *opaque)
+void os_pidfile_error(void)
 {
-    int i, found;
-    WaitObjects *w = &wait_objects;
-
-    found = 0;
-    for (i = 0; i < w->num; i++) {
-        if (w->events[i] == handle)
-            found = 1;
-        if (found) {
-            w->events[i] = w->events[i + 1];
-            w->func[i] = w->func[i + 1];
-            w->opaque[i] = w->opaque[i + 1];
-        }
+    fprintf(stderr, "Could not acquire pid file: %s\n", strerror(errno));
+}
+
+int qemu_create_pidfile(const char *filename)
+{
+    char buffer[128];
+    int len;
+    HANDLE file;
+    OVERLAPPED overlap;
+    BOOL ret;
+    memset(&overlap, 0, sizeof(overlap));
+
+    file = CreateFile(filename, GENERIC_WRITE, FILE_SHARE_READ, NULL,
+                      OPEN_ALWAYS, FILE_ATTRIBUTE_NORMAL, NULL);
+
+    if (file == INVALID_HANDLE_VALUE) {
+        return -1;
     }
-    if (found)
-        w->num--;
+    len = snprintf(buffer, sizeof(buffer), "%d\n", getpid());
+    ret = WriteFile(file, (LPCVOID)buffer, (DWORD)len,
+                    NULL, &overlap);
+    CloseHandle(file);
+    if (ret == 0) {
+        return -1;
+    }
+    return 0;
 }