Reset the struct on set_fd
authorPeter Hutterer <peter.hutterer@who-t.net>
Tue, 22 Oct 2013 01:27:42 +0000 (11:27 +1000)
committerPeter Hutterer <peter.hutterer@who-t.net>
Tue, 22 Oct 2013 23:04:41 +0000 (09:04 +1000)
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>
libevdev/libevdev.c

index 6f203e22cf1889088f82557e9de7f38a81dece47..d84e67eb2277ad425ea873afa92db0752ef67e53 100644 (file)
@@ -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;
 }