On Tue, Mar 29, 2011 at 6:34 PM, Bastien ROUCARIES <[email protected]> wrote: > On Tue, Mar 29, 2011 at 5:16 PM, Bruno Haible <[email protected]> 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. Note that the getter function cannot >> be implemented: How to determine whether a Woe32 socket is non-blocking? > > according to crappy doc: > The WSAEventSelect function automatically sets a socket to nonblocking > mode. If WSAEventSelect has been issued on a socket, then any attempt > to use ioctlsocket to set the socket back to blocking mode will fail > with WSAEINVAL. > > To set the socket back to blocking mode, an application must first > disable WSAEventSelect by calling WSAEventSelect with the > lNetworkEvents parameter equal to zero. > > Using this trick will allow to ask the socket (but not thread safe :S)
I am stupid It will not work Bastien > > Bastien > >> >> >> ================================ nonblocking.h >> ================================ >> /* Non-blocking I/O for pipe or socket descriptors. >> Copyright (C) 2011 Free Software Foundation, Inc. >> >> This program is free software: you can redistribute it and/or modify >> it under the terms of the GNU General Public License as published by >> the Free Software Foundation; either version 3 of the License, or >> (at your option) any later version. >> >> This program is distributed in the hope that it will be useful, >> but WITHOUT ANY WARRANTY; without even the implied warranty of >> MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the >> GNU General Public License for more details. >> >> You should have received a copy of the GNU General Public License >> along with this program. If not, see <http://www.gnu.org/licenses/>. */ >> >> #ifndef _NONBLOCKING_H >> #define _NONBLOCKING_H >> >> #include <stdbool.h> >> >> /* 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: >> - use select() or poll() followed by read() or write() if the descriptor >> is ready, >> - call read() or write() in separate threads. */ >> >> >> #ifdef __cplusplus >> extern "C" { >> #endif >> >> >> #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 >> >> /* 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); >> >> >> #ifdef __cplusplus >> } >> #endif >> >> #endif /* _NONBLOCKING_H */ >> ================================ nonblocking.c >> ================================ >> /* Non-blocking I/O for pipe or socket descriptors. >> Copyright (C) 2011 Free Software Foundation, Inc. >> >> This program is free software: you can redistribute it and/or modify >> it under the terms of the GNU General Public License as published by >> the Free Software Foundation; either version 3 of the License, or >> (at your option) any later version. >> >> This program is distributed in the hope that it will be useful, >> but WITHOUT ANY WARRANTY; without even the implied warranty of >> MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the >> GNU General Public License for more details. >> >> You should have received a copy of the GNU General Public License >> along with this program. If not, see <http://www.gnu.org/licenses/>. */ >> >> #include <config.h> >> >> /* Specification. */ >> #include "nonblocking.h" >> >> #include <errno.h> >> >> #if (defined _WIN32 || defined __WIN32__) && ! defined __CYGWIN__ >> /* Native Woe32 API. */ >> >> # if 0 >> bool >> get_nonblocking_flag (int desc) >> { >> HANDLE h = (HANDLE) _get_osfhandle (desc); >> if (GetFileType (h) == FILE_TYPE_PIPE) >> { >> /* h is a pipe or socket. */ >> DWORD state; >> if (GetNamedPipeHandleState (h, &state, NULL, NULL, NULL, NULL, 0)) >> /* h is a pipe. */ >> return (state & PIPE_NOWAIT) != 0; >> else >> /* h is a socket. */ >> ?? How can this be implemented ?? >> } >> else >> return false; >> } >> # endif >> >> int >> set_nonblocking_flag (int desc, bool value) >> { >> HANDLE h = (HANDLE) _get_osfhandle (desc); >> if (GetFileType (h) == FILE_TYPE_PIPE) >> { >> /* h is a pipe or socket. */ >> DWORD state; >> if (GetNamedPipeHandleState (h, &state, NULL, NULL, NULL, NULL, 0)) >> { >> /* h is a pipe. */ >> if ((state & PIPE_NOWAIT) != 0) >> { >> if (value) >> return 0; >> state &= ~PIPE_NOWAIT; >> } >> else >> { >> if (!value) >> return 0; >> state |= PIPE_NOWAIT; >> } >> if (SetNamedPipeHandleState (h, &state, NULL, NULL)) >> return 0; >> errno = EINVAL; >> return -1; >> } >> else >> { >> /* h is a socket. */ >> int v = value; >> return ioctl ((SOCKET) h, FIONBIO, &v); >> } >> } >> else >> { >> /* Win32 does not support non-blocking on regular files. */ >> errno = ENOTSUP; >> return -1; >> } >> } >> >> #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; >> 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); >> } >> >> #endif >> =============================================================================== >> --- lib/ioctl.c.orig Tue Mar 29 17:15:16 2011 >> +++ lib/ioctl.c Tue Mar 29 16:08:53 2011 >> @@ -63,6 +63,10 @@ >> buf = va_arg (args, void *); >> va_end (args); >> >> + /* We don't support FIONBIO on pipes here. If you want to make pipe fds >> + non-blocking, use the gnulib 'nonblocking' module, until gnulib >> implements >> + fcntl F_GETFL / F_SETFL with O_NONBLOCK. */ >> + >> sock = FD_TO_SOCKET (fd); >> r = ioctlsocket (sock, req, buf); >> if (r < 0) >> >> -- >> In memoriam Rachel Levy <http://en.wikipedia.org/wiki/Rachel_Levy> >> >> >
