diff options
author | Mattias Andrée <maandree@kth.se> | 2022-07-28 20:31:28 +0200 |
---|---|---|
committer | Mattias Andrée <maandree@kth.se> | 2022-07-28 20:37:42 +0200 |
commit | 402bf1269c59db4b3a78077ab095a84181181808 (patch) | |
tree | b9f445318d9f1e09a5af77ac39b23dc8e50c7a52 /libgamepad_drain__.c | |
parent | Minor code improvement (diff) | |
download | libgamepad-402bf1269c59db4b3a78077ab095a84181181808.tar.gz libgamepad-402bf1269c59db4b3a78077ab095a84181181808.tar.bz2 libgamepad-402bf1269c59db4b3a78077ab095a84181181808.tar.xz |
Remove dependency on libevdev (mostly complete) + minor fixes
Signed-off-by: Mattias Andrée <maandree@kth.se>
Diffstat (limited to '')
-rw-r--r-- | libgamepad_drain__.c | 55 |
1 files changed, 55 insertions, 0 deletions
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; +} |