Is it OK to poll() a device file descriptor
Try to open /dev/null, and then to poll the file descriptor. Neither in the man page nor in the standard I see anything preventing you to poll on /dev/null, yet, it does not work on Mac OS X. You get a POLLNVAL. Run the following: https://gist.github.com/elazarl/5805848 #include stdio.h #include poll.h #include fcntl.h int main() { int fd = open(/dev/null, O_WRONLY); struct pollfd pollfds = { fd, POLLOUT, 0 }; if (fd 0) { perror(open); return 1; } if (poll(pollfds, 1, -1) 0) { perror(poll); return 2; } if (pollfds.revents == POLLNVAL) { puts(huh? why poll({/dev/null, POLLOUT, 0}, 1) returns POLLNVAL?); } if (pollfds.revents == POLLOUT) { puts(working as expected); } return 0; } Is there anything I'm missing? Or is it a real vaguely implemented corner of the standard. If it is, I'll be glad to see a list of supported/unsupported platforms, as well as list of other corner cases (for instance, POLLHUP may or may be received on EOF). ___ Linux-il mailing list Linux-il@cs.huji.ac.il http://mailman.cs.huji.ac.il/mailman/listinfo/linux-il
Re: Is it OK to poll() a device file descriptor
Elazar Leibovich elaz...@gmail.com writes: Try to open /dev/null, and then to poll the file descriptor. Neither in the man page nor in the standard I see anything preventing you to poll on /dev/null, yet, it does not work on Mac OS X. You get a POLLNVAL. From http://developer.apple.com/library/mac/#documentation/Darwin/Reference/ManPages/man2/poll.2.html: BUGS The poll() system call currently does not support devices. Your code works fine on Linux, but I suppose you know that. -- Oleg Goldshmidt | p...@goldshmidt.org ___ Linux-il mailing list Linux-il@cs.huji.ac.il http://mailman.cs.huji.ac.il/mailman/listinfo/linux-il
Re: Is it OK to poll() a device file descriptor
On 18/06/13 17:43, Elazar Leibovich wrote: Try to open /dev/null, and then to poll the file descriptor. Neither in the man page nor in the standard I see anything preventing you to poll on /dev/null, yet, it does not work on Mac OS X. You get a POLLNVAL. Under Linux, whether you can poll (epoll, select) a character device depends on the device's implementation. If the device implements it, then you can. If not, you can't. Under Linux, the device driver's implementer implements one callback, and the kernel uses that to allow select, poll and epoll (plus the p variants of the above) all at once. On Mac OS X, however, the BUGS line Oleg pointed to does not appear in the select syscall interface, which means that it might be possible to select a device file descriptor. Our of curiosity, however, why would you want to poll /dev/null? Shachar Run the following: https://gist.github.com/elazarl/5805848 #include stdio.h #include poll.h #include fcntl.h int main() { int fd = open(/dev/null, O_WRONLY); struct pollfd pollfds = { fd, POLLOUT, 0 }; if (fd 0) { perror(open); return 1; } if (poll(pollfds, 1, -1) 0) { perror(poll); return 2; } if (pollfds.revents == POLLNVAL) { puts(huh? why poll({/dev/null, POLLOUT, 0}, 1) returns POLLNVAL?); } if (pollfds.revents == POLLOUT) { puts(working as expected); } return 0; } Is there anything I'm missing? Or is it a real vaguely implemented corner of the standard. If it is, I'll be glad to see a list of supported/unsupported platforms, as well as list of other corner cases (for instance, POLLHUP may or may be received on EOF). ___ Linux-il mailing list Linux-il@cs.huji.ac.il http://mailman.cs.huji.ac.il/mailman/listinfo/linux-il ___ Linux-il mailing list Linux-il@cs.huji.ac.il http://mailman.cs.huji.ac.il/mailman/listinfo/linux-il
Re: Is it OK to poll() a device file descriptor
Damn I missed that. To my defense, this bug should be also mentioned in the POLLNVAL section. As it stands now, it looks like the only reason for POLLNVAL is a closed file descriptor. Sorry and thanks. On Tue, Jun 18, 2013 at 6:09 PM, Oleg Goldshmidt p...@goldshmidt.org wrote: Elazar Leibovich elaz...@gmail.com writes: Try to open /dev/null, and then to poll the file descriptor. Neither in the man page nor in the standard I see anything preventing you to poll on /dev/null, yet, it does not work on Mac OS X. You get a POLLNVAL. From http://developer.apple.com/library/mac/#documentation/Darwin/Reference/ManPages/man2/poll.2.html : BUGS The poll() system call currently does not support devices. Your code works fine on Linux, but I suppose you know that. -- Oleg Goldshmidt | p...@goldshmidt.org ___ Linux-il mailing list Linux-il@cs.huji.ac.il http://mailman.cs.huji.ac.il/mailman/listinfo/linux-il
Re: Is it OK to poll() a device file descriptor
I'm using it as a fake always non-blocking file descriptor. My main libevent-like poll loop looks like: poll(fds) for fd in fds: if fd.revents | POLLIN: fd.read_callback() if fd.revents | POLLOUT: fd.write_callback() Now let's say I want a fake filedescriptor that always reads 'z's (a sleepy fd). A simple way to implement that is to have a callback function associated with /dev/zero (so that poll will always say it's available to read from), and in the write callback we'll simply ignore the filedescriptor and write 'z's to the given buffer. Something like: register_with_poll(devzero, write_z_cb); int write_z_cb(int fd, char *buf, int len) { memset(buf, 'z', len); return len; } I can still do that with non-blocking pipe I'll never write to (and since its buffer is empty it'll never block), but somehow I found /dev/zero to be more elegant. On Tue, Jun 18, 2013 at 8:42 PM, Shachar Shemesh shac...@shemesh.bizwrote: On 18/06/13 17:43, Elazar Leibovich wrote: Try to open /dev/null, and then to poll the file descriptor. Neither in the man page nor in the standard I see anything preventing you to poll on /dev/null, yet, it does not work on Mac OS X. You get a POLLNVAL. Under Linux, whether you can poll (epoll, select) a character device depends on the device's implementation. If the device implements it, then you can. If not, you can't. Under Linux, the device driver's implementer implements one callback, and the kernel uses that to allow select, poll and epoll (plus the p variants of the above) all at once. On Mac OS X, however, the BUGS line Oleg pointed to does not appear in the select syscall interface, which means that it might be possible to select a device file descriptor. Our of curiosity, however, why would you want to poll /dev/null? Shachar Run the following: https://gist.github.com/elazarl/5805848 #include stdio.h #include poll.h #include fcntl.h int main() { int fd = open(/dev/null, O_WRONLY); struct pollfd pollfds = { fd, POLLOUT, 0 }; if (fd 0) { perror(open); return 1; } if (poll(pollfds, 1, -1) 0) { perror(poll); return 2; } if (pollfds.revents == POLLNVAL) { puts(huh? why poll({/dev/null, POLLOUT, 0}, 1) returns POLLNVAL?); } if (pollfds.revents == POLLOUT) { puts(working as expected); } return 0; } Is there anything I'm missing? Or is it a real vaguely implemented corner of the standard. If it is, I'll be glad to see a list of supported/unsupported platforms, as well as list of other corner cases (for instance, POLLHUP may or may be received on EOF). ___ Linux-il mailing listlinux...@cs.huji.ac.ilhttp://mailman.cs.huji.ac.il/mailman/listinfo/linux-il ___ Linux-il mailing list Linux-il@cs.huji.ac.il http://mailman.cs.huji.ac.il/mailman/listinfo/linux-il
Re: Is it OK to poll() a device file descriptor
On 18/06/13 22:16, Elazar Leibovich wrote: I'm using it as a fake always non-blocking file descriptor. My main libevent-like poll loop looks like: poll(fds) for fd in fds: if fd.revents | POLLIN: fd.read_callback() if fd.revents | POLLOUT: fd.write_callback() Now let's say I want a fake filedescriptor that always reads 'z's (a sleepy fd). Why? What you just did was to turn the whole thing into a non-sleeping loop. If that's the case, simply call poll with a zero timeout, so it won't sleep, and call your callback at the end of each loop. No need to artificially introduce another file descriptor into the mix. Mind you, I still don't understand WHY you'd want such a thing. This code will, by definition, consume 100% CPU all the time. Shachar ___ Linux-il mailing list Linux-il@cs.huji.ac.il http://mailman.cs.huji.ac.il/mailman/listinfo/linux-il