Ticket #4782 (closed Bugs: fixed)
ioctl constants are sign extended on 64 bit builds
|Reported by:||arvid@…||Owned by:||chris_kohlhoff|
Sometime between boost 1.40 and 1.44 asio started to keep track of whether or not the user had set the FIONBIO ioctl (non blocking I/O). On a 64 bit build this test fails, and asio believes that the socket is still in blocking mode. The reason why it fails is because the constants defined are unsigned ints, in asio's io control wrapper template, the "name" is returned as an int. This is later cast to a long and then compared to the system constants.
The problem is that the system constants, although they fit in a 32 bit value, have the most significant bit set, so the cast from int -> long causes sign extension, and the comparison to the FIONBIO constant always fails.
The fix for this is quite simple; in the file boost/asio/detail/io_control.hpp, just change the return value of non_blocking_io::name() to be a long instead of an int.
asio seems to be using longs in the socket_ops.hpp for its ioctl() wrapper, so this seems like the most appropriate solution. This goes for all classes implementing the IoControlCommand? concept.
I marked this as a regression, but it might make sense to consider it a show-stopper, because it means any application that relies on non-blocking operations will freeze. On Mac OS X, 64 bit builds are defaults, so all mac applications are affected.
I tried to post this to the mailing list with a few more details a few weeks ago, but I don't think it made it through.