[Top][All Lists]
[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]
Re: read() and write() for MinGW
From: |
Bruno Haible |
Subject: |
Re: read() and write() for MinGW |
Date: |
Sun, 28 Mar 2010 23:40:09 +0100 |
User-agent: |
KMail/1.9.9 |
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