]> Git Repo - qemu.git/blobdiff - tests/libqtest.c
tests/qapi-schema: Cover union types with base
[qemu.git] / tests / libqtest.c
index 83424c3c6b69975c702bb9a5a5241035b41f57c0..f587d36176ed388c69ab9ca48743f6b0f95c95c1 100644 (file)
@@ -43,9 +43,8 @@ struct QTestState
     int qmp_fd;
     bool irq_level[MAX_IRQ];
     GString *rx;
-    gchar *pid_file; /* QEMU PID file */
-    int child_pid;   /* Child process created to execute QEMU */
-    char *socket_path, *qmp_socket_path;
+    pid_t qemu_pid;  /* our child QEMU process */
+    struct sigaction sigact_old; /* restored on exit */
 };
 
 #define g_assert_no_errno(ret) do { \
@@ -90,53 +89,58 @@ static int socket_accept(int sock)
     return ret;
 }
 
-static pid_t qtest_qemu_pid(QTestState *s)
+static void kill_qemu(QTestState *s)
 {
-    FILE *f;
-    char buffer[1024];
-    pid_t pid = -1;
-
-    f = fopen(s->pid_file, "r");
-    if (f) {
-        if (fgets(buffer, sizeof(buffer), f)) {
-            pid = atoi(buffer);
-        }
-        fclose(f);
+    if (s->qemu_pid != -1) {
+        kill(s->qemu_pid, SIGTERM);
+        waitpid(s->qemu_pid, NULL, 0);
     }
-    return pid;
+}
+
+static void sigabrt_handler(int signo)
+{
+    kill_qemu(global_qtest);
 }
 
 QTestState *qtest_init(const char *extra_args)
 {
     QTestState *s;
     int sock, qmpsock, i;
-    gchar *pid_file;
+    gchar *socket_path;
+    gchar *qmp_socket_path;
     gchar *command;
     const char *qemu_binary;
-    pid_t pid;
+    struct sigaction sigact;
 
     qemu_binary = getenv("QTEST_QEMU_BINARY");
     g_assert(qemu_binary != NULL);
 
     s = g_malloc(sizeof(*s));
 
-    s->socket_path = g_strdup_printf("/tmp/qtest-%d.sock", getpid());
-    s->qmp_socket_path = g_strdup_printf("/tmp/qtest-%d.qmp", getpid());
-    pid_file = g_strdup_printf("/tmp/qtest-%d.pid", getpid());
+    socket_path = g_strdup_printf("/tmp/qtest-%d.sock", getpid());
+    qmp_socket_path = g_strdup_printf("/tmp/qtest-%d.qmp", getpid());
+
+    sock = init_socket(socket_path);
+    qmpsock = init_socket(qmp_socket_path);
 
-    sock = init_socket(s->socket_path);
-    qmpsock = init_socket(s->qmp_socket_path);
+    /* Catch SIGABRT to clean up on g_assert() failure */
+    sigact = (struct sigaction){
+        .sa_handler = sigabrt_handler,
+        .sa_flags = SA_RESETHAND,
+    };
+    sigemptyset(&sigact.sa_mask);
+    sigaction(SIGABRT, &sigact, &s->sigact_old);
 
-    pid = fork();
-    if (pid == 0) {
-        command = g_strdup_printf("%s "
+    s->qemu_pid = fork();
+    if (s->qemu_pid == 0) {
+        command = g_strdup_printf("exec %s "
                                   "-qtest unix:%s,nowait "
                                   "-qtest-log /dev/null "
                                   "-qmp unix:%s,nowait "
-                                  "-pidfile %s "
                                   "-machine accel=qtest "
-                                  "%s", qemu_binary, s->socket_path,
-                                  s->qmp_socket_path, pid_file,
+                                  "-display none "
+                                  "%s", qemu_binary, socket_path,
+                                  qmp_socket_path,
                                   extra_args ?: "");
         execlp("/bin/sh", "sh", "-c", command, NULL);
         exit(1);
@@ -144,10 +148,12 @@ QTestState *qtest_init(const char *extra_args)
 
     s->fd = socket_accept(sock);
     s->qmp_fd = socket_accept(qmpsock);
+    unlink(socket_path);
+    unlink(qmp_socket_path);
+    g_free(socket_path);
+    g_free(qmp_socket_path);
 
     s->rx = g_string_new("");
-    s->pid_file = pid_file;
-    s->child_pid = pid;
     for (i = 0; i < MAX_IRQ; i++) {
         s->irq_level[i] = false;
     }
@@ -157,7 +163,7 @@ QTestState *qtest_init(const char *extra_args)
     qtest_qmp_discard_response(s, "{ 'execute': 'qmp_capabilities' }");
 
     if (getenv("QTEST_STOP")) {
-        kill(qtest_qemu_pid(s), SIGSTOP);
+        kill(s->qemu_pid, SIGSTOP);
     }
 
     return s;
@@ -165,23 +171,12 @@ QTestState *qtest_init(const char *extra_args)
 
 void qtest_quit(QTestState *s)
 {
-    int status;
-
-    pid_t pid = qtest_qemu_pid(s);
-    if (pid != -1) {
-        kill(pid, SIGTERM);
-        waitpid(pid, &status, 0);
-    }
+    sigaction(SIGABRT, &s->sigact_old, NULL);
 
+    kill_qemu(s);
     close(s->fd);
     close(s->qmp_fd);
     g_string_free(s->rx, true);
-    unlink(s->pid_file);
-    unlink(s->socket_path);
-    unlink(s->qmp_socket_path);
-    g_free(s->pid_file);
-    g_free(s->socket_path);
-    g_free(s->qmp_socket_path);
     g_free(s);
 }
 
This page took 0.026218 seconds and 4 git commands to generate.