Re: hidraw: Bug in select/poll for writing
From: David Herrmann <hidden>
Date: 2013-02-11 16:01:28
Hi Tim On Tue, Feb 5, 2013 at 12:47 AM, Tim Peterson [off-list ref] wrote:
Hi all,
I have found that when one uses select() on /dev/hidraw0, it will
never report that it is writable, even though a write will succeed at
any time.
As a demonstration, the command
socat -v - /dev/hidraw0 >/dev/null
will log every time data is read or written from the device. With any
other device, I can type at the keyboard and see that the data has
been written. With hidraw, reading works but writing never occurs,
because socat never finds out that the file is ready for writing.
I believe this is a result of hidraw_poll() never returning POLLOUT:
static unsigned int hidraw_poll(struct file *file, poll_table *wait)
{
struct hidraw_list *list = file->private_data;
poll_wait(file, &list->hidraw->wait, wait);
if (list->head != list->tail)
return POLLIN | POLLRDNORM;
if (!list->hidraw->exist)
return POLLERR | POLLHUP;
return 0;
}
I am not familiar with how these drivers work, so I'm not sure how to
proceed. Is it safe to always add POLLOUT | POLLWRNORM to the return
value, or is there a case in which it would not be writable?Ah, yeah, that's a bit ugly. The problem is we don't support nonblocking writes there. Instead, the hidraw driver simply calls a blocking backend function. Therefore, POLLOUT hasn't been reported so far. But POLLOUT might be useful even without O_NONBLOCK so I think it is safe to add POLLOUT to the flags unconditionally. If we want to support O_NONBLOCK we would have to change a lot more, anyway. But you might also simply write to the device without waiting for POLLOUT. This only breaks generic commands like socat, so a patch would be appreciated. Regards David