Files
xemu/util/compatfd.c
T

Ignoring revisions in .git-blame-ignore-revs. Click here to bypass and see the normal blame view.

90 lines
1.9 KiB
C
Raw Normal View History

2010-10-11 15:31:15 -03:00
/*
* signalfd/eventfd compatibility
*
* Copyright IBM, Corp. 2008
*
* Authors:
* Anthony Liguori <aliguori@us.ibm.com>
*
* This work is licensed under the terms of the GNU GPL, version 2. See
* the COPYING file in the top-level directory.
*
2012-01-13 17:44:23 +01:00
* Contributions after 2012-01-13 are licensed under the terms of the
* GNU GPL, version 2 or (at your option) any later version.
2010-10-11 15:31:15 -03:00
*/
2016-01-29 17:49:55 +00:00
#include "qemu/osdep.h"
2013-05-02 10:21:18 +02:00
#include "qemu/thread.h"
2010-10-11 15:31:15 -03:00
#if defined(CONFIG_SIGNALFD)
#include <sys/signalfd.h>
#endif
2010-10-11 15:31:15 -03:00
2021-03-15 12:58:13 +02:00
struct sigfd_compat_info {
2010-10-11 15:31:15 -03:00
sigset_t mask;
int fd;
};
static void *sigwait_compat(void *opaque)
{
struct sigfd_compat_info *info = opaque;
2011-02-18 14:17:16 +01:00
while (1) {
int sig;
int err;
2010-10-11 15:31:15 -03:00
2011-02-18 14:17:16 +01:00
err = sigwait(&info->mask, &sig);
if (err != 0) {
if (errno == EINTR) {
continue;
} else {
return NULL;
}
} else {
struct qemu_signalfd_siginfo buffer;
memset(&buffer, 0, sizeof(buffer));
buffer.ssi_signo = sig;
2022-04-20 17:26:18 +04:00
if (qemu_write_full(info->fd, &buffer, sizeof(buffer)) != sizeof(buffer)) {
return NULL;
2010-10-11 15:31:15 -03:00
}
}
2011-02-18 14:17:16 +01:00
}
2010-10-11 15:31:15 -03:00
}
static int qemu_signalfd_compat(const sigset_t *mask)
{
struct sigfd_compat_info *info;
2013-05-02 10:21:18 +02:00
QemuThread thread;
2010-10-11 15:31:15 -03:00
int fds[2];
info = g_malloc(sizeof(*info));
2010-10-11 15:31:15 -03:00
if (!g_unix_open_pipe(fds, FD_CLOEXEC, NULL)) {
g_free(info);
2010-10-11 15:31:15 -03:00
return -1;
}
memcpy(&info->mask, mask, sizeof(*mask));
info->fd = fds[1];
qemu_thread_create(&thread, "signalfd_compat", sigwait_compat, info,
QEMU_THREAD_DETACHED);
2010-10-11 15:31:15 -03:00
return fds[0];
}
int qemu_signalfd(const sigset_t *mask)
{
#if defined(CONFIG_SIGNALFD)
int ret;
ret = signalfd(-1, mask, SFD_CLOEXEC);
2010-10-11 15:31:15 -03:00
if (ret != -1) {
return ret;
}
#endif
return qemu_signalfd_compat(mask);
}