]> Git Repo - qemu.git/blobdiff - compatfd.c
pl031: switch clock base to rtc_clock
[qemu.git] / compatfd.c
index 46b0ae7ab7f8df7f8a5c522e6921b633db6cadb1..42f81cafe49e83abbf2f4ea6991f5d519bd855de 100644 (file)
@@ -9,6 +9,8 @@
  * This work is licensed under the terms of the GNU GPL, version 2.  See
  * the COPYING file in the top-level directory.
  *
+ * Contributions after 2012-01-13 are licensed under the terms of the
+ * GNU GPL, version 2 or (at your option) any later version.
  */
 
 #include "qemu-common.h"
@@ -26,45 +28,45 @@ struct sigfd_compat_info
 static void *sigwait_compat(void *opaque)
 {
     struct sigfd_compat_info *info = opaque;
-    int err;
     sigset_t all;
 
     sigfillset(&all);
-    sigprocmask(SIG_BLOCK, &all, NULL);
-
-    do {
-       siginfo_t siginfo;
-
-       err = sigwaitinfo(&info->mask, &siginfo);
-       if (err == -1 && errno == EINTR) {
-            err = 0;
-            continue;
+    pthread_sigmask(SIG_BLOCK, &all, NULL);
+
+    while (1) {
+        int sig;
+        int err;
+
+        err = sigwait(&info->mask, &sig);
+        if (err != 0) {
+            if (errno == EINTR) {
+                continue;
+            } else {
+                return NULL;
+            }
+        } else {
+            struct qemu_signalfd_siginfo buffer;
+            size_t offset = 0;
+
+            memset(&buffer, 0, sizeof(buffer));
+            buffer.ssi_signo = sig;
+
+            while (offset < sizeof(buffer)) {
+                ssize_t len;
+
+                len = write(info->fd, (char *)&buffer + offset,
+                            sizeof(buffer) - offset);
+                if (len == -1 && errno == EINTR)
+                    continue;
+
+                if (len <= 0) {
+                    return NULL;
+                }
+
+                offset += len;
+            }
         }
-
-       if (err > 0) {
-           char buffer[128];
-           size_t offset = 0;
-
-           memcpy(buffer, &err, sizeof(err));
-           while (offset < sizeof(buffer)) {
-               ssize_t len;
-
-               len = write(info->fd, buffer + offset,
-                           sizeof(buffer) - offset);
-               if (len == -1 && errno == EINTR)
-                   continue;
-
-               if (len <= 0) {
-                   err = -1;
-                   break;
-               }
-
-               offset += len;
-           }
-       }
-    } while (err >= 0);
-
-    return NULL;
+    }
 }
 
 static int qemu_signalfd_compat(const sigset_t *mask)
@@ -76,15 +78,18 @@ static int qemu_signalfd_compat(const sigset_t *mask)
 
     info = malloc(sizeof(*info));
     if (info == NULL) {
-       errno = ENOMEM;
-       return -1;
+        errno = ENOMEM;
+        return -1;
     }
 
     if (pipe(fds) == -1) {
-       free(info);
-       return -1;
+        free(info);
+        return -1;
     }
 
+    qemu_set_cloexec(fds[0]);
+    qemu_set_cloexec(fds[1]);
+
     memcpy(&info->mask, mask, sizeof(*mask));
     info->fd = fds[1];
 
@@ -100,29 +105,34 @@ static int qemu_signalfd_compat(const sigset_t *mask)
 
 int qemu_signalfd(const sigset_t *mask)
 {
-#if defined(SYS_signalfd)
+#if defined(CONFIG_SIGNALFD)
     int ret;
 
     ret = syscall(SYS_signalfd, -1, mask, _NSIG / 8);
-    if (!(ret == -1 && errno == ENOSYS))
-       return ret;
+    if (ret != -1) {
+        qemu_set_cloexec(ret);
+        return ret;
+    }
 #endif
 
     return qemu_signalfd_compat(mask);
 }
 
-int qemu_eventfd(int *fds)
+bool qemu_signalfd_available(void)
 {
-#if defined(SYS_eventfd)
-    int ret;
-
-    ret = syscall(SYS_eventfd, 0);
-    if (ret >= 0) {
-       fds[0] = fds[1] = ret;
-       return 0;
-    } else if (!(ret == -1 && errno == ENOSYS))
-       return ret;
+#ifdef CONFIG_SIGNALFD
+    sigset_t mask;
+    int fd;
+    bool ok;
+    sigemptyset(&mask);
+    errno = 0;
+    fd = syscall(SYS_signalfd, -1, &mask, _NSIG / 8);
+    ok = (errno != ENOSYS);
+    if (fd >= 0) {
+        close(fd);
+    }
+    return ok;
+#else
+    return false;
 #endif
-
-    return pipe(fds);
 }
This page took 0.028065 seconds and 4 git commands to generate.