summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorPeter Hutterer <peter.hutterer@who-t.net>2013-10-22 11:27:42 +1000
committerPeter Hutterer <peter.hutterer@who-t.net>2013-11-01 08:25:17 +1000
commitf7e3bbbb242db55bfb7ea4a2fd072245df885566 (patch)
tree01d03840c3cc2e29c89b41da4f39a8fdc73a9fe7
parent6801ad683293d5a31c46d91029d982f916039096 (diff)
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 <peter.hutterer@who-t.net> Reviewed-by: David Herrmann <dh.herrmann@gmail.com> (cherry picked from commit b15e5987b35b61ca6ca447f37c5bc759523b118b)
-rw-r--r--libevdev/libevdev.c24
1 files changed, 18 insertions, 6 deletions
diff --git a/libevdev/libevdev.c b/libevdev/libevdev.c
index dd8ab14..d2a078b 100644
--- a/libevdev/libevdev.c
+++ b/libevdev/libevdev.c
@@ -109,19 +109,27 @@ log_msg(enum libevdev_log_priority priority,
va_end(args);
}
+static void
+libevdev_reset(struct libevdev *dev)
+{
+ memset(dev, 0, sizeof(*dev));
+ dev->fd = -1;
+ 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 = calloc(1, sizeof(*dev));
+ dev = malloc(sizeof(*dev));
if (!dev)
return NULL;
- dev->fd = -1;
- dev->num_slots = -1;
- dev->current_slot = -1;
- dev->grabbed = LIBEVDEV_UNGRAB;
- dev->sync_state = SYNC_NONE;
+
+ libevdev_reset(dev);
return dev;
}
@@ -209,6 +217,8 @@ libevdev_set_fd(struct libevdev* dev, int fd)
return -EBADF;
}
+ libevdev_reset(dev);
+
rc = ioctl(fd, EVIOCGBIT(0, sizeof(dev->bits)), dev->bits);
if (rc < 0)
goto out;
@@ -352,6 +362,8 @@ libevdev_set_fd(struct libevdev* dev, int fd)
*/
out:
+ if (rc)
+ libevdev_reset(dev);
return rc ? -errno : 0;
}