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>
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;
}
} else if (fd < 0)
return -EBADF;
+ libevdev_reset(dev);
+
rc = ioctl(fd, EVIOCGBIT(0, sizeof(dev->bits)), dev->bits);
if (rc < 0)
goto out;
dev->initialized = true;
out:
+ if (rc)
+ libevdev_reset(dev);
return rc ? -errno : 0;
}