Allow -1 as valid fd in libevdev_change_fd

Add a new flag for "initialized" and separate that from the fd logic. This way,
we can call libevdev_change_fd(dev, -1) to signal that the current fd should be
dropped.

Otherwise libevdev can't be told to release the fd and always keeps a reference
to it.

Signed-off-by: Peter Hutterer <peter.hutterer@who-t.net>
This commit is contained in:
Peter Hutterer 2013-10-08 15:16:32 +10:00
parent fcf80ba371
commit e8920d2fd4
2 changed files with 25 additions and 14 deletions

View file

@ -26,6 +26,7 @@
#include <config.h> #include <config.h>
#include <stdio.h> #include <stdio.h>
#include <stdlib.h> #include <stdlib.h>
#include <stdbool.h>
#include <errno.h> #include <errno.h>
#include "libevdev.h" #include "libevdev.h"
@ -73,6 +74,7 @@ enum SyncState {
struct libevdev { struct libevdev {
int fd; int fd;
bool initialized;
char *name; char *name;
char *phys; char *phys;
char *uniq; char *uniq;

View file

@ -27,6 +27,7 @@
#include <string.h> #include <string.h>
#include <unistd.h> #include <unistd.h>
#include <stdarg.h> #include <stdarg.h>
#include <stdbool.h>
#include "libevdev.h" #include "libevdev.h"
#include "libevdev-int.h" #include "libevdev-int.h"
@ -118,6 +119,7 @@ libevdev_new(void)
if (!dev) if (!dev)
return NULL; return NULL;
dev->fd = -1; dev->fd = -1;
dev->initialized = false;
dev->num_slots = -1; dev->num_slots = -1;
dev->current_slot = -1; dev->current_slot = -1;
dev->grabbed = LIBEVDEV_UNGRAB; dev->grabbed = LIBEVDEV_UNGRAB;
@ -189,7 +191,7 @@ libevdev_get_log_priority(void)
LIBEVDEV_EXPORT int LIBEVDEV_EXPORT int
libevdev_change_fd(struct libevdev *dev, int fd) libevdev_change_fd(struct libevdev *dev, int fd)
{ {
if (dev->fd == -1) { if (!dev->initialized) {
log_bug("device not initialized. call libevdev_set_fd() first\n"); log_bug("device not initialized. call libevdev_set_fd() first\n");
return -1; return -1;
} }
@ -204,7 +206,7 @@ libevdev_set_fd(struct libevdev* dev, int fd)
int i; int i;
char buf[256]; char buf[256];
if (dev->fd != -1) { if (dev->initialized) {
log_bug("device already initialized.\n"); log_bug("device already initialized.\n");
return -EBADF; return -EBADF;
} }
@ -351,6 +353,7 @@ libevdev_set_fd(struct libevdev* dev, int fd)
* Same with the valuators, really, but they may not change. * Same with the valuators, really, but they may not change.
*/ */
dev->initialized = true;
out: out:
return rc ? -errno : 0; return rc ? -errno : 0;
} }
@ -731,10 +734,11 @@ libevdev_next_event(struct libevdev *dev, unsigned int flags, struct input_event
{ {
int rc = LIBEVDEV_READ_STATUS_SUCCESS; int rc = LIBEVDEV_READ_STATUS_SUCCESS;
if (dev->fd < 0) { if (!dev->initialized) {
log_bug("device not initialized. call libevdev_set_fd() first\n"); log_bug("device not initialized. call libevdev_set_fd() first\n");
return -EBADF; return -EBADF;
} } else if (dev->fd < 0)
return -EBADF;
if (!(flags & (LIBEVDEV_READ_FLAG_NORMAL|LIBEVDEV_READ_FLAG_SYNC|LIBEVDEV_READ_FLAG_FORCE_SYNC))) { if (!(flags & (LIBEVDEV_READ_FLAG_NORMAL|LIBEVDEV_READ_FLAG_SYNC|LIBEVDEV_READ_FLAG_FORCE_SYNC))) {
log_bug("invalid flags %#x\n.\n", flags); log_bug("invalid flags %#x\n.\n", flags);
@ -821,10 +825,11 @@ libevdev_has_event_pending(struct libevdev *dev)
struct pollfd fds = { dev->fd, POLLIN, 0 }; struct pollfd fds = { dev->fd, POLLIN, 0 };
int rc; int rc;
if (dev->fd < 0) { if (!dev->initialized) {
log_bug("device not initialized. call libevdev_set_fd() first\n"); log_bug("device not initialized. call libevdev_set_fd() first\n");
return -EBADF; return -EBADF;
} } else if (dev->fd < 0)
return -EBADF;
if (queue_num_elements(dev) != 0) if (queue_num_elements(dev) != 0)
return 1; return 1;
@ -1205,10 +1210,11 @@ libevdev_kernel_set_abs_info(struct libevdev *dev, unsigned int code, const stru
{ {
int rc; int rc;
if (dev->fd < 0) { if (!dev->initialized) {
log_bug("device not initialized. call libevdev_set_fd() first\n"); log_bug("device not initialized. call libevdev_set_fd() first\n");
return -EBADF; return -EBADF;
} } else if (dev->fd < 0)
return -EBADF;
if (code > ABS_MAX) if (code > ABS_MAX)
return -EINVAL; return -EINVAL;
@ -1227,10 +1233,11 @@ libevdev_grab(struct libevdev *dev, enum libevdev_grab_mode grab)
{ {
int rc = 0; int rc = 0;
if (dev->fd < 0) { if (!dev->initialized) {
log_bug("device not initialized. call libevdev_set_fd() first\n"); log_bug("device not initialized. call libevdev_set_fd() first\n");
return -EBADF; return -EBADF;
} } else if (dev->fd < 0)
return -EBADF;
if (grab != LIBEVDEV_GRAB && grab != LIBEVDEV_UNGRAB) { if (grab != LIBEVDEV_GRAB && grab != LIBEVDEV_UNGRAB) {
log_bug("invalid grab parameter %#x\n", grab); log_bug("invalid grab parameter %#x\n", grab);
@ -1372,10 +1379,11 @@ libevdev_kernel_set_led_values(struct libevdev *dev, ...)
int rc = 0; int rc = 0;
size_t nleds = 0; size_t nleds = 0;
if (dev->fd < 0) { if (!dev->initialized) {
log_bug("device not initialized. call libevdev_set_fd() first\n"); log_bug("device not initialized. call libevdev_set_fd() first\n");
return -EBADF; return -EBADF;
} } else if (dev->fd < 0)
return -EBADF;
memset(ev, 0, sizeof(ev)); memset(ev, 0, sizeof(ev));
@ -1427,10 +1435,11 @@ libevdev_kernel_set_led_values(struct libevdev *dev, ...)
LIBEVDEV_EXPORT int LIBEVDEV_EXPORT int
libevdev_set_clock_id(struct libevdev *dev, int clockid) libevdev_set_clock_id(struct libevdev *dev, int clockid)
{ {
if (dev->fd < 0) { if (!dev->initialized) {
log_bug("device not initialized. call libevdev_set_fd() first\n"); log_bug("device not initialized. call libevdev_set_fd() first\n");
return -EBADF; return -EBADF;
} } else if (dev->fd < 0)
return -EBADF;
return ioctl(dev->fd, EVIOCSCLOCKID, &clockid) ? -errno : 0; return ioctl(dev->fd, EVIOCSCLOCKID, &clockid) ? -errno : 0;
} }