Hi Neil, > I'd like to contribute a gnulib module to handle the fact that, on > MinGW, you have to use recv() to read data from a socket, instead of > read(). > > Similarly, for writing, send() is needed instead of write().
Gnulib already solves this problem, by wrapping the Win32 SOCKET in a file descriptor. It was contributed by Paolo Bonzini: <http://lists.gnu.org/archive/html/bug-gnulib/2008-09/msg00090.html> <http://lists.gnu.org/archive/html/bug-gnulib/2008-09/msg00102.html> > Conceptually this is extremely simple, and I've found that gnulib > already contains useful bits like SOCKET_TO_FD, FD_TO_SOCKET, and the > code for determining if an arbitrary fd is a socket - which is all > great. Yes, and the read() and write() functions don't need to make this distinction, because they call ReadFile and WriteFile, which work equally fine with HANDLEs and SOCKETs. > But what's the > preferred way to write the test to see if this is needed? Checking for > __MINGW32__, or (WIN32 && !CYGWIN), or HAVE_WINSOCK2_H, or a feature > test that tries read() on a socket and determines if it worked? Here you have a feature that is specific to the MSVC runtime library. No need for a test like read() on a socket - this is overkill when a simple (WIN32 && !CYGWIN) can do it as well. Also, you want to exclude Cygwin, since Cygwin has working Unix-like sockets. __MINGW32__ is not the right condition here, because it evaluates to false in a MSVC environment. HAVE_WINSOCK2_H because it is also true on Cygwin, depending on compiler options. ((defined _WIN32 || defined __WIN32__) && !defined __CYGWIN__) is the solution. (HAVE_WINSOCK2_H && !defined __CYGWIN__) would be equivalent. > - m4/write.m4 tests gl_SIGNAL_SIGPIPE, which just tests (IIUC) whether > SIGPIPE is defined -- but then lib/write.c only implements rpl_write() > #if (defined _WIN32 || defined __WIN32__) && ! defined __CYGWIN__. > Does this mean that there is an implicit assumption here that those > two conditions are equivalent? Yes: All Unix platforms have SIGPIPE. Mingw doesn't. And Gnulib is currently not interested in other platforms than Unix and Windows. > - The lib/write.c code includes > > /* Try to raise signal SIGPIPE. */ > raise (SIGPIPE); > > How can that work given that we've already determined that SIGPIPE is > not defined? This code is only compiled when GNULIB_SIGPIPE is defined. This is a module indicator: It is defined if and only if gnulib's 'sigpipe' module is present in a package. The module 'sigpipe' depends on 'signal' and defines GNULIB_SIGNAL_H_SIGPIPE to 1. The module 'signal', when GNULIB_SIGNAL_H_SIGPIPE is 1, defines SIGPIPE to a replacement value (see lib/signal.in.h). This way, the lib/write.c code can use SIGPIPE. Bruno