Commit bcdf9b4d169f6d6735a817c4d9e57a5490843041

Authored by aliguori
1 parent baf35cb9

Add missing files from previous commit.



git-svn-id: svn://svn.savannah.nongnu.org/qemu/trunk@5188 c046a42c-6fe2-441c-8c8c-71466251a162
Showing 2 changed files with 160 additions and 0 deletions
compatfd.c 0 → 100644
  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 + */
  13 +
  14 +#include "qemu-common.h"
  15 +#include "compatfd.h"
  16 +
  17 +#include <sys/syscall.h>
  18 +#include <pthread.h>
  19 +
  20 +struct sigfd_compat_info
  21 +{
  22 + sigset_t mask;
  23 + int fd;
  24 +};
  25 +
  26 +static void *sigwait_compat(void *opaque)
  27 +{
  28 + struct sigfd_compat_info *info = opaque;
  29 + int err;
  30 + sigset_t all;
  31 +
  32 + sigfillset(&all);
  33 + sigprocmask(SIG_BLOCK, &all, NULL);
  34 +
  35 + do {
  36 + siginfo_t siginfo;
  37 +
  38 + err = sigwaitinfo(&info->mask, &siginfo);
  39 + if (err == -1 && errno == EINTR) {
  40 + err = 0;
  41 + continue;
  42 + }
  43 +
  44 + if (err > 0) {
  45 + char buffer[128];
  46 + size_t offset = 0;
  47 +
  48 + memcpy(buffer, &err, sizeof(err));
  49 + while (offset < sizeof(buffer)) {
  50 + ssize_t len;
  51 +
  52 + len = write(info->fd, buffer + offset,
  53 + sizeof(buffer) - offset);
  54 + if (len == -1 && errno == EINTR)
  55 + continue;
  56 +
  57 + if (len <= 0) {
  58 + err = -1;
  59 + break;
  60 + }
  61 +
  62 + offset += len;
  63 + }
  64 + }
  65 + } while (err >= 0);
  66 +
  67 + return NULL;
  68 +}
  69 +
  70 +static int qemu_signalfd_compat(const sigset_t *mask)
  71 +{
  72 + pthread_attr_t attr;
  73 + pthread_t tid;
  74 + struct sigfd_compat_info *info;
  75 + int fds[2];
  76 +
  77 + info = malloc(sizeof(*info));
  78 + if (info == NULL) {
  79 + errno = ENOMEM;
  80 + return -1;
  81 + }
  82 +
  83 + if (pipe(fds) == -1) {
  84 + free(info);
  85 + return -1;
  86 + }
  87 +
  88 + memcpy(&info->mask, mask, sizeof(*mask));
  89 + info->fd = fds[1];
  90 +
  91 + pthread_attr_init(&attr);
  92 + pthread_attr_setdetachstate(&attr, PTHREAD_CREATE_DETACHED);
  93 +
  94 + pthread_create(&tid, &attr, sigwait_compat, info);
  95 +
  96 + pthread_attr_destroy(&attr);
  97 +
  98 + return fds[0];
  99 +}
  100 +
  101 +int qemu_signalfd(const sigset_t *mask)
  102 +{
  103 +#if defined(SYS_signalfd)
  104 + int ret;
  105 +
  106 + ret = syscall(SYS_signalfd, -1, mask, _NSIG / 8);
  107 + if (!(ret == -1 && errno == ENOSYS))
  108 + return ret;
  109 +#endif
  110 +
  111 + return qemu_signalfd_compat(mask);
  112 +}
  113 +
  114 +int qemu_eventfd(int *fds)
  115 +{
  116 +#if defined(SYS_eventfd)
  117 + int ret;
  118 +
  119 + ret = syscall(SYS_eventfd, 0);
  120 + if (ret >= 0) {
  121 + fds[0] = fds[1] = ret;
  122 + return 0;
  123 + } else if (!(ret == -1 && errno == ENOSYS))
  124 + return ret;
  125 +#endif
  126 +
  127 + return pipe(fds);
  128 +}
... ...
compatfd.h 0 → 100644
  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 + */
  13 +
  14 +#ifndef QEMU_COMPATFD_H
  15 +#define QEMU_COMPATFD_H
  16 +
  17 +#include <signal.h>
  18 +
  19 +#if defined(__linux__) && !defined(SYS_signalfd)
  20 +struct signalfd_siginfo {
  21 + uint32_t ssi_signo;
  22 + uint8_t pad[124];
  23 +};
  24 +#else
  25 +#include <linux/signalfd.h>
  26 +#endif
  27 +
  28 +int qemu_signalfd(const sigset_t *mask);
  29 +
  30 +int qemu_eventfd(int *fds);
  31 +
  32 +#endif
... ...