Summary: | [PATCH] Evdev ioctls EVIOCGRAB and EVIOCREVOKE don't work together with cuse | ||||||
---|---|---|---|---|---|---|---|
Product: | Base System | Reporter: | Jan Kokemüller <jan.kokemueller> | ||||
Component: | kern | Assignee: | freebsd-bugs (Nobody) <bugs> | ||||
Status: | Closed Works As Intended | ||||||
Severity: | Affects Only Me | CC: | gonzo, wulf | ||||
Priority: | --- | Keywords: | patch | ||||
Version: | CURRENT | ||||||
Hardware: | Any | ||||||
OS: | Any | ||||||
Attachments: |
|
Description
Jan Kokemüller
2017-04-13 10:45:01 UTC
Notify committer of original file. (In reply to Jan Kokemüller from comment #0) > Cuse, however, only passes along the value of the data > pointer when the length of the ioctl is 0 Hopefully, this have been fixed with r302381 https://svnweb.freebsd.org/base?view=revision&revision=302381 (In reply to Vladimir Kondratyev from comment #2) This doesn't fix the issue, sadly. With the current definition of EVIOCGRAB, when you do something like this on a cuse-based Evdev device: ioctl(dev->fd, EVIOCGRAB, (void *)1); /* grab device */ ioctl(dev->fd, EVIOCGRAB, (void *)0); /* ungrab device */ ...both times you get 10000 (CUSE_BUF_MIN_PTR) inside the ioctl handler. So you cannot ungrab a device again. The value 10000 comes from here: https://github.com/freebsd/freebsd/blob/master/sys/fs/cuse/cuse.c#L1676 I don't know if this is cuse specific behavior, or if FreeBSD in general behaves like this. (In reply to Jan Kokemüller from comment #3) > I don't know if this is cuse specific behavior, > or if FreeBSD in general behaves like this. IOWINT ioctl passes int value in internal buffer and provide pointer to that buffer to handler exactly like IOW(NNN, ###, int) Following is IOWINT->IO convertor from webcamd internals, AFAIR, it is working: /* * Copy in the _IOWINT parameter and pass it as arg pointer * similar to what Linux is doing: */ if ((cmd & IOC_DIRMASK) == IOC_VOID && IOCPARM_LEN(cmd) == sizeof(int)) { if (copy_from_user(&iowint, arg, sizeof(iowint)) != 0) { retval = -EFAULT; goto done; } arg = (void *)(intptr_t)iowint; } Great, this works! Thank you for the hint. |