From b15e5987b35b61ca6ca447f37c5bc759523b118b Mon Sep 17 00:00:00 2001 From: Peter Hutterer Date: Tue, 22 Oct 2013 11:27:42 +1000 Subject: [PATCH] Reset the struct on set_fd libevdev_set_fd may fail at a number of points. If it does, it errors out but does nothing otherwise. Thus, a client may call set_fd again for the same struct but on a different fd and have it succeed. Depending on when set_fd bailed out the first time, some fields may already be set. Thus, reset the whole struct at set_fd time to make sure we're nulled out appropriately. Signed-off-by: Peter Hutterer Reviewed-by: David Herrmann --- libevdev/libevdev.c | 26 +++++++++++++++++++------- 1 file changed, 19 insertions(+), 7 deletions(-) diff --git a/libevdev/libevdev.c b/libevdev/libevdev.c index 6f203e2..d84e67e 100644 --- a/libevdev/libevdev.c +++ b/libevdev/libevdev.c @@ -110,20 +110,28 @@ log_msg(enum libevdev_log_priority priority, va_end(args); } -LIBEVDEV_EXPORT struct libevdev* -libevdev_new(void) +static void +libevdev_reset(struct libevdev *dev) { - struct libevdev *dev; - - dev = calloc(1, sizeof(*dev)); - if (!dev) - return NULL; + memset(dev, 0, sizeof(*dev)); dev->fd = -1; dev->initialized = false; dev->num_slots = -1; dev->current_slot = -1; dev->grabbed = LIBEVDEV_UNGRAB; dev->sync_state = SYNC_NONE; +} + +LIBEVDEV_EXPORT struct libevdev* +libevdev_new(void) +{ + struct libevdev *dev; + + dev = malloc(sizeof(*dev)); + if (!dev) + return NULL; + + libevdev_reset(dev); return dev; } @@ -212,6 +220,8 @@ libevdev_set_fd(struct libevdev* dev, int fd) } else if (fd < 0) return -EBADF; + libevdev_reset(dev); + rc = ioctl(fd, EVIOCGBIT(0, sizeof(dev->bits)), dev->bits); if (rc < 0) goto out; @@ -360,6 +370,8 @@ libevdev_set_fd(struct libevdev* dev, int fd) dev->initialized = true; out: + if (rc) + libevdev_reset(dev); return rc ? -errno : 0; } -- 2.7.4