From e49c3f3e66b4337859af7c1be013b076eb4de136 Mon Sep 17 00:00:00 2001 From: David 'Digit' Turner Date: Wed, 11 May 2011 01:48:28 +0200 Subject: compatfd.c: minor integrate Change-Id: I93f921bfb2778bb592c9a4ce1e8c26ff5a5b6a97 --- compatfd.c | 101 +++++++++++++++++++++++++++---------------------------------- compatfd.h | 23 +++++++++++--- 2 files changed, 64 insertions(+), 60 deletions(-) diff --git a/compatfd.c b/compatfd.c index 46b0ae7..bd377c4 100644 --- a/compatfd.c +++ b/compatfd.c @@ -26,45 +26,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; + 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 +76,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 +103,15 @@ 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) -{ -#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; -#endif - - return pipe(fds); -} diff --git a/compatfd.h b/compatfd.h index 55a111a..fc37915 100644 --- a/compatfd.h +++ b/compatfd.h @@ -17,12 +17,27 @@ #include struct qemu_signalfd_siginfo { - uint32_t ssi_signo; - uint8_t pad[124]; + uint32_t ssi_signo; /* Signal number */ + int32_t ssi_errno; /* Error number (unused) */ + int32_t ssi_code; /* Signal code */ + uint32_t ssi_pid; /* PID of sender */ + uint32_t ssi_uid; /* Real UID of sender */ + int32_t ssi_fd; /* File descriptor (SIGIO) */ + uint32_t ssi_tid; /* Kernel timer ID (POSIX timers) */ + uint32_t ssi_band; /* Band event (SIGIO) */ + uint32_t ssi_overrun; /* POSIX timer overrun count */ + uint32_t ssi_trapno; /* Trap number that caused signal */ + int32_t ssi_status; /* Exit status or signal (SIGCHLD) */ + int32_t ssi_int; /* Integer sent by sigqueue(2) */ + uint64_t ssi_ptr; /* Pointer sent by sigqueue(2) */ + uint64_t ssi_utime; /* User CPU time consumed (SIGCHLD) */ + uint64_t ssi_stime; /* System CPU time consumed (SIGCHLD) */ + uint64_t ssi_addr; /* Address that generated signal + (for hardware-generated signals) */ + uint8_t pad[48]; /* Pad size to 128 bytes (allow for + additional fields in the future) */ }; int qemu_signalfd(const sigset_t *mask); -int qemu_eventfd(int *fds); - #endif -- cgit v1.1