[PATCH libevdev] Reset the struct on set_fd
Peter Hutterer
peter.hutterer at who-t.net
Tue Oct 22 16:26:11 PDT 2013
On Tue, Oct 22, 2013 at 05:14:59PM +0200, David Herrmann wrote:
> Hi Peter
>
> On Tue, Oct 22, 2013 at 5:11 AM, Peter Hutterer
> <peter.hutterer at who-t.net> wrote:
> > libevdev_set_fd may fail at a number of points. If it does, it errors out
> > but does not unset previously set fields. 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 at who-t.net>
> > ---
> > libevdev/libevdev.c | 24 +++++++++++++++++-------
> > 1 file changed, 17 insertions(+), 7 deletions(-)
> >
> > diff --git a/libevdev/libevdev.c b/libevdev/libevdev.c
> > index 6f203e2..4c1f089 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);
> > +
>
> I think we should call libevdev_reset() in the error-path, too.
added locally:
@@ -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;
}
> Otherwise, the state might be initialized with partial values and
> *_get_*() functions will return partial results. But it's a nit-pick
> as we don't guarantee anything about the state after a failed
> set_fd().
there's probably some argument that it would allow peeking at info from a
device that fails setup. Not sure how you'd exploit this tbh but resetting
on error is simple enough.
> So I'm fine with either way:
>
> Reviewed-by: David Herrmann <dh.herrmann at gmail.com>
thanks for the reviews.
Cheers,
Peter
> > rc = ioctl(fd, EVIOCGBIT(0, sizeof(dev->bits)), dev->bits);
> > if (rc < 0)
> > goto out;
> > --
> > 1.8.3.1
> >
More information about the Input-tools
mailing list