Author: Samuel WilliamsWhen: Thursday, 02 April 2009
I've had quite a few issues with poll and kqueue on Mac OS X/Darwin. When trying to poll for events using fileno(stdin) or STDIN_FILENO, it gives errors such as Operation not supported (kqueue) or POLLNVAL (poll).
On Darwin (at least up until Mac OS X 10.5.5), stdin, stdout and stderr are actually devices! Not pipes like one might expect. Also, poll is implemented on top of kqueue, therefore problems with kqueue also affect poll.
Because of this, polling stdin won't work. Here is an example which fails on Mac OS X 10.5.5:
A hackity solution
This code uses boost threads. What it does is create three pipes, one for stdin, one for stdout and one for stderr. The originals are moved to different fds and then we spawn three threads to process data between the original devices and the newly created pipes. The result of this is that STDIN_FILENO, as an example, now refers to the write end of a pipe. The other end of this pipe is being read by the thread, and any data is written out to the original stdin device.
In this case, I've fixed all three standard fds. However, it is probably only useful in most cases to fix stdin - this is likely to be the only device you would want to poll. I've included support for all three as an example of how it would be done.
Poll specifically is a bit different across different platforms. Therefore, you need to be aware of the differences.