7

I want to use the ioctl EVIOCGRAB function in a C based program, and from googling around I have found various bits of example source code that use the function, but I am struggling to find explicit documentation that correctly describes how to correctly use it.

I see that from ioctl(2), ioctl function is defined as

int ioctl(int d, unsigned long request, …);

And that:

   The third argument is an untyped pointer to memory.  It's traditionally char
   *argp (from the days before void * was valid C), and will be so named
   for this discussion.

And I hoped to find EVIOCGRAB listed in ioctl_list(2), but it wasn't.

So I don't know what the third argument should be for the EVIOCGRAB function. After seeing various bits of example code all I can do is assume that a non-zero value grabs the device and that a zero value releases it.

Which I got from random code examples like

int grab = 1;
ioctl(fd, EVIOCGRAB, &grab);
..
ioctl(fd, EVIOCGRAB, NULL); 

or

ioctl(fd, EVIOCGRAB, (void*)1);
..
ioctl(fd, EVIOCGRAB, (void*)0); 

or

ioctl(fd, EVIOCGRAB, 1);
..
ioctl(fd, EVIOCGRAB, 0); 

(Which seems to smell a bit of cargo cult programming.)

So where can I find a definitive explanation of the EVIOCGRAB control parameter?

1 Answer 1

4

A definitive explanation you can at least find in the kernel sources, more specifically drivers/input/evdev.c:

 static long evdev_do_ioctl(struct file *file, unsigned int cmd,
                            void __user *p, int compat_mode)
 {
 […]
     switch (cmd) {
     […]
     case EVIOCGRAB:
         if (p)
             return evdev_grab(evdev, client);
         else
             return evdev_ungrab(evdev, client);
     […]
     }
 […]
 }

As I understand, everything that evaluates to »false« (0) will lead to evdev_ungrab ((void*)0, 0, …), everything that's »true« (not 0) will cause an evdev_grab ((void*)1, 1, 0xDEADBEEF…).

One thing worth mentioning is that your first example,

int grab = 1;
ioctl(fd, EVIOCGRAB, &grab);
..
ioctl(fd, EVIOCGRAB, NULL); 

only works unintentionally. It's not the value inside of grab, but the fact that &grab is non-zero (you could have guessed this, since the counter-case isn't grab = 0; ioctl(…, &grab); but ioctl(…, NULL);. Funny. :)

1
  • Thank you for that. Yep the source is definitive (assuming that is the source being used on my system!), but documentation somewhere would have been nice. As for that &grab example (which I knew was fishy and is not my code), I have seen that in multiple locations - including in a selected answer on stackoverflow.com
    – Peter M
    Commented Apr 29, 2014 at 11:05

You must log in to answer this question.

Not the answer you're looking for? Browse other questions tagged .