5

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?

3

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. :)

  • 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 Apr 29 '14 at 11:05

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.