2010/3/20 Eric Blake <ebl...@redhat.com>:
> Since commit 4e86671a, gethostname failed to compile on mingw.
> Gnulib's sys/socket.h includes winsock2.h, which then includes
> unistd.h prior to declaring gethostname.  Therefore, unistd.h
> cannot replace gethostname until winsock2.h is complete, also
> fixing things if a .c includes <unistd.h> (or even <winsock2.h>)
> prior to <sys/socket.h>.
>
> * lib/sys_socket.in.h (includes): Set witness when including
> winsock2.h.
> * lib/unistd.in.h (includes): Likewise, after hoisting <winsock2.h>
> inclusion.  Don't replace anything when included by winsock2.h.
> Reported by Matthias Bolte.
>
> Signed-off-by: Eric Blake <ebl...@redhat.com>
> ---
>
> I think this is more robust, but would appreciate another round
> of testing before I push.
>
>  ChangeLog           |    9 +++++++++
>  lib/sys_socket.in.h |    7 ++++++-
>  lib/unistd.in.h     |   15 +++++++++++++--
>  3 files changed, 28 insertions(+), 3 deletions(-)
>
> diff --git a/ChangeLog b/ChangeLog
> index de054fa..2125639 100644
> --- a/ChangeLog
> +++ b/ChangeLog
> @@ -1,3 +1,12 @@
> +2010-03-19  Eric Blake  <ebl...@redhat.com>
> +
> +       gethostname: fix build on mingw
> +       * lib/sys_socket.in.h (includes): Set witness when including
> +       winsock2.h.
> +       * lib/unistd.in.h (includes): Don't replace anything when included
> +       by winsock2.h.
> +       Reported by Matthias Bolte.
> +
>  2010-02-17  Eric Blake  <e...@byu.net>
>
>        manywarnings: add more warnings
> diff --git a/lib/sys_socket.in.h b/lib/sys_socket.in.h
> index 006a901..b34b506 100644
> --- a/lib/sys_socket.in.h
> +++ b/lib/sys_socket.in.h
> @@ -28,7 +28,10 @@
>    - On Cygwin 1.5.x we have a sequence of nested includes
>      <sys/socket.h> -> <cygwin/socket.h> -> <asm/socket.h> -> <cygwin/if.h>,
>      and the latter includes <sys/socket.h>.  In this situation, the functions
> -     are not yet declared, therefore we cannot provide the C++ aliases.  */
> +     are not yet declared, therefore we cannot provide the C++ aliases.
> +   - On mingw, <sys/socket.h> -> <winsock2.h> -> <unistd.h>, and the latter
> +     includes <winsock2.h>.  In this situation, functions like gethostname
> +     are not yet declared, therefore we must defer.  */
>
> �...@include_next@ @NEXT_SYS_SOCKET_H@
>
> @@ -129,7 +132,9 @@ struct sockaddr_storage
>
>
>  # if @HAVE_WINSOCK2_H@
> +#  define _GL_INCLUDING_WINSOCK2_H
>  #  include <winsock2.h>
> +#  undef _GL_INCLUDING_WINSOCK2_H
>  # endif
>  # if @HAVE_WS2TCPIP_H@
>  #  include <ws2tcpip.h>
> diff --git a/lib/unistd.in.h b/lib/unistd.in.h
> index b74484a..a57ba37 100644
> --- a/lib/unistd.in.h
> +++ b/lib/unistd.in.h
> @@ -26,7 +26,19 @@
>  # @INCLUDE_NEXT@ @NEXT_UNISTD_H@
>  #endif
>
> -#ifndef _GL_UNISTD_H
> +/* On mingw, <winsock2.h> includes <unistd.h> prior to declaring
> +   gethostname, but we want to replace gethostname.  We must ensure
> +   that <winsock2.h> is completely included first.  */
> +#if @GNULIB_GETHOSTNAME@
> +/* Get all possible declarations of gethostname().  */
> +# if @UNISTD_H_HAVE_WINSOCK2_H@
> +#  define _GL_INCLUDING_WINSOCK2_H
> +#  include <winsock2.h>
> +#  undef _GL_INCLUDING_WINSOCK2_H
> +# endif
> +#endif
> +
> +#if !defined _GL_UNISTD_H && !defined _GL_INCLUDING_WINSOCK2_H
>  #define _GL_UNISTD_H
>
>  /* NetBSD 5.0 mis-defines NULL.  Also get size_t.  */
> @@ -76,7 +88,6 @@
>  #if @GNULIB_GETHOSTNAME@
>  /* Get all possible declarations of gethostname().  */
>  # if @UNISTD_H_HAVE_WINSOCK2_H@
> -#  include <winsock2.h>
>  #  if !defined _GL_SYS_SOCKET_H
>  #   undef socket
>  #   define socket               socket_used_without_including_sys_socket_h
> --
> 1.6.6.1
>

If I apply the attached diff on top of this patch the problem is
fixed. It compiles without errors, I can include <unistd.h> before
<sys/socket.h> and I can include <winsock2.h> before <sys/socket.h> as
long as the <winsock2.h> include is wrapped in #define/#undef
_GL_INCLUDING_WINSOCK2_H.

The important part is

-# if @UNISTD_H_HAVE_WINSOCK2_H@
+# if @UNISTD_H_HAVE_WINSOCK2_H@ && !defined _GL_INCLUDING_WINSOCK2_H

This stops the <winsock2.h>-includes-<unistd.h>-case from undefining
_GL_INCLUDING_WINSOCK2_H too early.

Matthias
diff --git a/lib/poll.c b/lib/poll.c
index 90d99d9..024ffa9 100644
--- a/lib/poll.c
+++ b/lib/poll.c
@@ -35,7 +35,9 @@
 
 #if (defined _WIN32 || defined __WIN32__) && ! defined __CYGWIN__
 # define WIN32_NATIVE
-# include <winsock2.h>
+# define _GL_INCLUDING_WINSOCK2_H
+#  include <winsock2.h>
+# undef _GL_INCLUDING_WINSOCK2_H
 # include <windows.h>
 # include <io.h>
 # include <stdio.h>
diff --git a/lib/select.c b/lib/select.c
index 3564566..66468bf 100644
--- a/lib/select.c
+++ b/lib/select.c
@@ -31,7 +31,9 @@
 #include <errno.h>
 #include <limits.h>
 
-#include <winsock2.h>
+#define _GL_INCLUDING_WINSOCK2_H
+# include <winsock2.h>
+#undef _GL_INCLUDING_WINSOCK2_H
 #include <windows.h>
 #include <io.h>
 #include <stdio.h>
diff --git a/lib/strerror.c b/lib/strerror.c
index b0df778..c13aa1c 100644
--- a/lib/strerror.c
+++ b/lib/strerror.c
@@ -26,7 +26,9 @@
 
 # if GNULIB_defined_ESOCK /* native Windows platforms */
 #  if HAVE_WINSOCK2_H
-#   include <winsock2.h>
+#   define _GL_INCLUDING_WINSOCK2_H
+#    include <winsock2.h>
+#   undef _GL_INCLUDING_WINSOCK2_H
 #  endif
 # endif
 
diff --git a/lib/unistd.in.h b/lib/unistd.in.h
index 7c7ecd8..13bdda5 100644
--- a/lib/unistd.in.h
+++ b/lib/unistd.in.h
@@ -31,7 +31,7 @@
    that <winsock2.h> is completely included first.  */
 #if @GNULIB_GETHOSTNAME@
 /* Get all possible declarations of gethostname().  */
-# if @UNISTD_H_HAVE_WINSOCK2_H@
+# if @UNISTD_H_HAVE_WINSOCK2_H@ && !defined _GL_INCLUDING_WINSOCK2_H
 #  define _GL_INCLUDING_WINSOCK2_H
 #  include <winsock2.h>
 #  undef _GL_INCLUDING_WINSOCK2_H

Reply via email to