On 03/29/2011 09:16 AM, Bruno Haible wrote:
> Paolo Bonzini wrote:
>> Without guessing what your bias is, I also :) prefer to implement
>> {g,s}et_nonblock_flag functions. It would use either
>> SetNamedPipeHandleState or ioctlsocket (using the socket detection trick
>> in sockets.c to detect sockets, and then GetFileType to detect pipes if
>> it fails).
>
> Here's proposed code to that effect.
Let's get it checked in.
> Note that the getter function cannot
> be implemented: How to determine whether a Woe32 socket is non-blocking?
I don't know.
> /* Non-blocking I/O is an I/O mode by which read(), write() calls avoid
> blocking the current thread. When non-blocking is enabled:
> - A read() call returns -1 with errno set to EAGAIN when no data or EOF
> information is immediately available.
> - A write() call returns -1 with errno set to EAGAIN when it cannot
> transport the requested amount of data (but at most one pipe buffer)
> without blocking.
>
> There are two modern alternatives to non-blocking I/O:
three
> - use select() or poll() followed by read() or write() if the descriptor
> is ready,
> - call read() or write() in separate threads. */
- use aio_*, although that is not as widely portable
>
> #if 0 /* cannot be portably implemented */
> /* Return true if I/O to the descriptor DESC is currently non-blocking,
> or false if it is blocking. */
> extern bool get_nonblocking_flag (int desc);
> #endif
Should we make this tri-state?
-1 for unable to determine (such as mingw sockets for now), 0 for
blocking (such as mingw regular files, or Unix platforms where
fcntl(F_GETFL) works), 1 for non-blocking.
> /* Specify the non-blocking flag for the descriptor DESC.
> Return 0 upon success, or -1 with errno set upon failure.
> The default depends on the presence of the O_NONBLOCK flag for files
> or pipes opened with open() or on the presence of the SOCK_NONBLOCK
> flag for pipes. */
> extern int set_nonblocking_flag (int desc, bool value);
Should we document this function's behavior on fd's exempt by POSIX?
For regular files and directories, non-blocking has no effect, but it is
implementation-defined whether fcntl(F_SETFL) can modify the O_NONBLOCK
flag or whether the flag is silently ignored. Having consistent
behavior (such as making this function always return -1 EBADF on a
non-pipe non-socket, rather than triggering implementation-defined
behavior with subtle differences across platforms) might be worth the
extra effort of an fstat(). I'm not sure whether block and character
special devices can usefully be set non-blocking, or whether that is a
per-device setting.
> #else
> /* Unix API. */
>
> # include <fcntl.h>
>
> /* We don't need the gnulib replacement of fcntl() here. */
> # undef fcntl
>
> # if 0
> bool
> get_nonblocking_flag (int desc)
> {
> int fcntl_flags;
>
> fcntl_flags = fcntl (desc, F_GETFL, 0);
> if (fcntl_flags < 0)
> return false;
This would be a case for returning -1 in a tri-state implementation.
> return (fcntl_flags & O_NONBLOCK) != 0;
> }
> # endif
>
> int
> set_nonblocking_flag (int desc, bool value)
> {
> int fcntl_flags;
>
> fcntl_flags = fcntl (desc, F_GETFL, 0);
> if (fcntl_flags < 0)
> return -1;
> if ((O_NONBLOCK & ~fcntl_flags) == 0)
> return 0;
> return fcntl (desc, F_SETFL, fcntl_flags | O_NONBLOCK);
This doesn't honor the 'value' parameter, but blindly assumes it was
true. Sometimes it is also desirable to clear non-blocking, by passing
false.
--
Eric Blake [email protected] +1-801-349-2682
Libvirt virtualization library http://libvirt.org
signature.asc
Description: OpenPGP digital signature
