qemu

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

compatfd.c (1903B)


      1 /*
      2  * signalfd/eventfd compatibility
      3  *
      4  * Copyright IBM, Corp. 2008
      5  *
      6  * Authors:
      7  *  Anthony Liguori   <aliguori@us.ibm.com>
      8  *
      9  * This work is licensed under the terms of the GNU GPL, version 2.  See
     10  * the COPYING file in the top-level directory.
     11  *
     12  * Contributions after 2012-01-13 are licensed under the terms of the
     13  * GNU GPL, version 2 or (at your option) any later version.
     14  */
     15 
     16 #include "qemu/osdep.h"
     17 #include "qemu/thread.h"
     18 
     19 #if defined(CONFIG_SIGNALFD)
     20 #include <sys/signalfd.h>
     21 #endif
     22 
     23 struct sigfd_compat_info {
     24     sigset_t mask;
     25     int fd;
     26 };
     27 
     28 static void *sigwait_compat(void *opaque)
     29 {
     30     struct sigfd_compat_info *info = opaque;
     31 
     32     while (1) {
     33         int sig;
     34         int err;
     35 
     36         err = sigwait(&info->mask, &sig);
     37         if (err != 0) {
     38             if (errno == EINTR) {
     39                 continue;
     40             } else {
     41                 return NULL;
     42             }
     43         } else {
     44             struct qemu_signalfd_siginfo buffer;
     45             memset(&buffer, 0, sizeof(buffer));
     46             buffer.ssi_signo = sig;
     47 
     48             if (qemu_write_full(info->fd, &buffer, sizeof(buffer)) != sizeof(buffer)) {
     49                 return NULL;
     50             }
     51         }
     52     }
     53 }
     54 
     55 static int qemu_signalfd_compat(const sigset_t *mask)
     56 {
     57     struct sigfd_compat_info *info;
     58     QemuThread thread;
     59     int fds[2];
     60 
     61     info = g_malloc(sizeof(*info));
     62 
     63     if (!g_unix_open_pipe(fds, FD_CLOEXEC, NULL)) {
     64         g_free(info);
     65         return -1;
     66     }
     67 
     68     memcpy(&info->mask, mask, sizeof(*mask));
     69     info->fd = fds[1];
     70 
     71     qemu_thread_create(&thread, "signalfd_compat", sigwait_compat, info,
     72                        QEMU_THREAD_DETACHED);
     73 
     74     return fds[0];
     75 }
     76 
     77 int qemu_signalfd(const sigset_t *mask)
     78 {
     79 #if defined(CONFIG_SIGNALFD)
     80     int ret;
     81 
     82     ret = signalfd(-1, mask, SFD_CLOEXEC);
     83     if (ret != -1) {
     84         return ret;
     85     }
     86 #endif
     87 
     88     return qemu_signalfd_compat(mask);
     89 }