From 402bf1269c59db4b3a78077ab095a84181181808 Mon Sep 17 00:00:00 2001 From: Mattias Andrée Date: Thu, 28 Jul 2022 20:31:28 +0200 Subject: Remove dependency on libevdev (mostly complete) + minor fixes MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Signed-off-by: Mattias Andrée --- libgamepad_drain__.c | 55 ++++++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 55 insertions(+) create mode 100644 libgamepad_drain__.c (limited to 'libgamepad_drain__.c') diff --git a/libgamepad_drain__.c b/libgamepad_drain__.c new file mode 100644 index 0000000..38e898e --- /dev/null +++ b/libgamepad_drain__.c @@ -0,0 +1,55 @@ +/* See LICENSE file for copyright and license details. */ +#include "common.h" + +#define DEFER_EINTR(ERROR_CONDITION)\ + DEFER_EINTR_(device, ERROR_CONDITION, fail) + + +int +libgamepad_drain__(struct libgamepad_device *device) +{ + struct input_event buf[4 * 8]; + int flags, saved_errno = errno; + ssize_t r; + + if (device->internals->deferred_error) { + errno = device->internals->deferred_error; + device->internals->deferred_error = 0; + return -1; + } + + flags = fcntl(device->fd, F_GETFL); + if (flags < 0) + return -1; + + if (!(flags & O_NONBLOCK)) + if (fcntl(device->fd, F_GETFL, flags | O_NONBLOCK) < 0) + goto fail; + + for (;;) { + r = read(device->fd, buf, sizeof(buf)); + if (r < (ssize_t)sizeof(buf)) { + if (r > 0) + break; + else if (!r) + goto nodev; + else if (errno == EAGAIN) + break; + else if (errno == EINTR) + device->internals->deferred_error = EINTR; + else + goto fail; + } + } + + if (!(flags & O_NONBLOCK)) + DEFER_EINTR(fcntl(device->fd, F_SETFL, flags) < 0); + + errno = saved_errno; + return 0; + +nodev: + errno = ENODEV; +fail: + return -1; +} -- cgit v1.2.3-70-g09d2