bug-gnulib
[Top][All Lists]
Advanced

[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




reply via email to

[Prev in Thread] Current Thread [Next in Thread]