Is it OK to poll() a device file descriptor

2013-06-18 Thread Elazar Leibovich
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

2013-06-18 Thread Oleg Goldshmidt
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

2013-06-18 Thread Shachar Shemesh
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

2013-06-18 Thread Elazar Leibovich
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

2013-06-18 Thread Elazar Leibovich
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

2013-06-18 Thread Shachar Shemesh
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