blob: 38e898eefe82279550d4095f3d550a701baa4a2b (
plain) (
blame)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
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;
}
|