Uma explicação definitiva que você pode pelo menos encontrar nos fontes do kernel, mais especificamente 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);
[…]
}
[…]
}
Pelo que entendi, tudo o que é avaliado como "false" ( 0
) levará a evdev_ungrab
( (void*)0
, 0
,…), tudo que é "verdadeiro" (não 0
) causará um evdev_grab
( (void*)1
, 1
, 0xDEADBEEF
…).
Uma coisa que vale a pena mencionar é que seu primeiro exemplo,
int grab = 1;
ioctl(fd, EVIOCGRAB, &grab);
..
ioctl(fd, EVIOCGRAB, NULL);
funciona apenas de forma não intencional. Não é o valor dentro de grab
, mas o fato de que &grab
é diferente de zero (você poderia ter adivinhado isso, já que a caixa não é grab = 0; ioctl(…, &grab);
mas ioctl(…, NULL);
Engraçado.:)