[adding bug-gnulib and Paolo as author of rpl_ioctl]
On 03/15/2011 02:29 AM, Matthias Bolte wrote:
Commit 2ed6cc7bec41dd344d41ea1531f6760c93099128 "Expose event
loop
implementation as a public API" turned a failure to initialize the
default event loop into a fatal error in virsh on Windows. Before that
commit such a failure was ignored.
virEventRegisterDefaultImpl calls virEventPollInit that calls
virSetNonBlock that calls ioctl that is replaced by gnulib and calls
ioctlsocket. ioctlsocket fails because the given FD is a pipe but
ioctlsocket expects a socket.
A version that works on pipes on Windows looks like this. Although the
pipe is actually not a named pipe the call to SetNamedPipeHandleState
doesn't fail at least.
int
virSetPipeNonBlock(int fd)
{
DWORD mode = PIPE_NOWAIT;
HANDLE handle = _get_osfhandle(fd)
BOOL result = SetNamedPipeHandleState(handle, &mode, NULL, NULL);
return result ? 0 : -1;
}
So, is the event loop stuff supposed to work on Windows at all and we
should get it fixed? Or do we just put an #ifndef WIN32 around
virEventRegisterDefaultImpl in virsh, because the only event loop user
in virsh is the console command that is disabled on Windows anyway?
Right now, gnulib's rpl_ioctl doesn't do any inspection of the various
requests handed it, nor does it check whether the request makes sense on
a non-socket. Sniffing the FIONBIO request and handling it for pipes as
well as sockets might make sense.
And while gnulib has rpl_fcntl for mingw, it does not yet support
F_SETFL or F_GETFL to inspect/set O_NONBLOCK on non-file fds. I'm not
sure how much effort that would be to add; I suppose that if F_GETFL
doesn't support all possible flags, but does support enough that we
could detect whether a read-modify-write F_GETFL/F_SETFL sequence is
trying to set or clear just O_NONBLOCK, that it would be sufficient for
the task at hand.
But rather than exposing fcntl, maybe the better thing to do is have
gnulib provide a simple wrapper API module that controls whether an fd
is blocking (similar to how the gnulib cloexec module hides
fcntl(F_GETFD/F_SETFD) or a mingw counterpart).
Paolo, any thoughts on the best approach to take? (I know which way I'm
leaning, but want some feedback before I give away my bias).
--
Eric Blake eblake(a)redhat.com +1-801-349-2682
Libvirt virtualization library
http://libvirt.org