bug-gnulib
[Top][All Lists]
Advanced

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

Re: (x)gethostname


From: Simon Josefsson
Subject: Re: (x)gethostname
Date: Thu, 24 Jan 2008 18:00:15 +0100
User-agent: Gnus/5.110007 (No Gnus v0.7) Emacs/22.1 (gnu/linux)

Here is an updated patch to get gethostname working under MinGW.  It
uses the recent new gnulib module 'sockets'.

The module works like this: If the gethostname function is not found on
the system, it pulls in gethostname.c into the gnulib library, and
defines gethostname to rpl_gethostname.  rpl_gethostname calls the
gl_socket_* functions to initialize and shutdown Windows sockets, calls
the real Windows gethostname function.  It then converts from the
Windows error codes to errno, and then shut downs Windows sockets.

What do people think about the approach chosen here?

There are many choices which are open for discussion:

1) Should we convert from WSA* errors to errno codes?  Alternatively, we
could return WSA* errors in the errno variable, since the integer values
do not seem to overlap, and enhance strerror to be able to print the
Windows socket error strings.  This may cause problems for code
comparing errno values though, which is why I chose not to do this.

2) Should conversion of WSA* error codes happen inside the gethostname.c
file, or should it be moved to (e.g.) sockets.{c,h}?  It is not clear to
me if there is a 1-1 mapping of all relevant error codes.  Maybe some
Windows function return Windows socket error X which is appropriate to
map to errno value Y, while at the same time another Windows function
return Windows socket error X which is appropriate (in that context) to
map to errno value Z.

3) Is there any chance that the #define gethostname rpl_gethostname and
replacement prototype of gethostname in gnulib's unistd.h will cause
problems?  Consider that gethostname in winsock2.h is declared with
PASCAL calling conventions, so the prototype is not the same as the one
that gnulib uses.  That may cause problems in some weird situations, but
I can't see them right now.  The self test works fine.

4) Is calling WSAStartup/WSACleanup in each gnulib replacement module a
good idea?  I could easily argue that it is simpler for everyone if
gnulib simply say that if you care about Windows portability, you need
to call WSAStartup+WSACleanup yourself.  The gnulib module 'sockets'
could be used for this, and then the 'gethostname' module may not need
to depend directly on the 'sockets' module.

5) Does this result in the right thing on cygwin?  I suppose it should
detect that gethostname is present and not do anything beyond that.

Thanks,
/Simon

diff --git a/lib/gethostname.c b/lib/gethostname.c
index 169dd4e..767afe6 100644
--- a/lib/gethostname.c
+++ b/lib/gethostname.c
@@ -15,14 +15,24 @@
    You should have received a copy of the GNU General Public License
    along with this program.  If not, see <http://www.gnu.org/licenses/>.  */
 
-/* David MacKenzie <address@hidden> */
+/* David MacKenzie <address@hidden>,
+   MinGW port by Simon Josefsson <address@hidden> */
 
 #include <config.h>
+#undef gethostname
 
 #ifdef HAVE_UNAME
 # include <sys/utsname.h>
 #endif
 
+#ifdef WINDOWS_SOCKETS
+# include <errno.h>
+# include "sockets.h"
+# ifdef HAVE_WINSOCK2_H
+#  include <winsock2.h>
+# endif
+#endif
+
 #include <string.h>
 
 /* Put up to LEN chars of the host name into NAME.
@@ -32,7 +42,7 @@
 #include <stddef.h>
 
 int
-gethostname (char *name, size_t len)
+rpl_gethostname (char *name, size_t len)
 {
 #ifdef HAVE_UNAME
   struct utsname uts;
@@ -46,6 +56,37 @@ gethostname (char *name, size_t len)
       len = sizeof (uts.nodename);
     }
   strncpy (name, uts.nodename, len);
+#elif WINDOWS_SOCKETS
+  int err;
+
+  if (gl_sockets_startup (SOCKETS_1_1))
+    {
+      errno = ENOSYS;
+      return -1;
+    }
+
+  err = gethostname (name, len);
+  if (err < 0)
+    {
+      switch (WSAGetLastError())
+       {
+       case WSAEFAULT:
+         errno = EFAULT;
+         break;
+
+       default:
+         errno = ENOSYS;
+         break;
+       }
+    }
+
+  if (gl_sockets_cleanup ())
+    {
+      errno = ENOSYS;
+      return -1;
+    }
+
+  return err;
 #else
   strcpy (name, "");           /* Hardcode your system name if you want.  */
 #endif
diff --git a/lib/unistd.in.h b/lib/unistd.in.h
index 5400c86..b67e288 100644
--- a/lib/unistd.in.h
+++ b/lib/unistd.in.h
@@ -1,5 +1,5 @@
 /* Substitute for and wrapper around <unistd.h>.
-   Copyright (C) 2004-2007 Free Software Foundation, Inc.
+   Copyright (C) 2004-2008 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
@@ -156,6 +156,18 @@ extern char * getcwd (char *buf, size_t size);
      getcwd (b, s))
 #endif
 
+#if @GNULIB_GETHOSTNAME@
+# if address@hidden@
+#  include <stddef.h>
+  extern int gethostname (char *name, size_t size);
+# endif
+#elif defined GNULIB_POSIXCHECK
+# undef gethostname
+# define gethostname(n,s)                          \
+  (GL_LINK_WARNING ("gethostname is unportable - "                    \
+                   "use gnulib module gethostname for portability"),   \
+   gethostname (n, s))
+#endif
 
 #if @GNULIB_GETLOGIN_R@
 /* Copies the user's login name to NAME.
diff --git a/m4/gethostname.m4 b/m4/gethostname.m4
index 1e9749d..e272e48 100644
--- a/m4/gethostname.m4
+++ b/m4/gethostname.m4
@@ -1,18 +1,39 @@
-# gethostname.m4 serial 2
-dnl Copyright (C) 2002 Free Software Foundation, Inc.
+# gethostname.m4 serial 3
+dnl Copyright (C) 2002, 2008 Free Software Foundation, Inc.
 dnl This file is free software; the Free Software Foundation
 dnl gives unlimited permission to copy and/or distribute it,
 dnl with or without modifications, as long as this notice is preserved.
 
 AC_DEFUN([gl_FUNC_GETHOSTNAME],
 [
-  AC_REPLACE_FUNCS(gethostname)
-  if test $ac_cv_func_gethostname = no; then
+  AC_REQUIRE([gl_SOCKETS])dnl for HAVE_SYS_SOCKET_H, HAVE_WINSOCK2_H, -lws2_32
+
+  AC_CACHE_CHECK([for gethostname], [gl_cv_func_gethostname], [
+    AC_TRY_LINK([
+#include <sys/types.h>
+#ifdef HAVE_SYS_SOCKET_H
+#include <sys/socket.h>
+#endif
+#include <stddef.h>
+], [gethostname("", 0);],
+      [gl_cv_func_gethostname=yes],
+      [gl_cv_func_gethostname=no])])
+
+  if test "$gl_cv_func_gethostname" = no; then
+    AC_LIBOBJ(gethostname)
+    AC_DEFINE(gethostname, rpl_gethostname,
+      [Define to rpl_gethostname if the replacement function should be used.])
     gl_PREREQ_GETHOSTNAME
+    if test $ac_cv_have_decl_gethostname = yes; then
+      HAVE_DECL_GETHOSTNAME=1
+    else
+      HAVE_DECL_GETHOSTNAME=0
+    fi
   fi
 ])
 
 # Prerequisites of lib/gethostname.c.
 AC_DEFUN([gl_PREREQ_GETHOSTNAME], [
   AC_CHECK_FUNCS(uname)
+  AC_CHECK_DECLS_ONCE([gethostname])
 ])
diff --git a/m4/unistd_h.m4 b/m4/unistd_h.m4
index 4b8857c..daf7677 100644
--- a/m4/unistd_h.m4
+++ b/m4/unistd_h.m4
@@ -1,5 +1,5 @@
 # unistd_h.m4 serial 10
-dnl Copyright (C) 2006-2007 Free Software Foundation, Inc.
+dnl Copyright (C) 2006-2008 Free Software Foundation, Inc.
 dnl This file is free software; the Free Software Foundation
 dnl gives unlimited permission to copy and/or distribute it,
 dnl with or without modifications, as long as this notice is preserved.
@@ -37,6 +37,7 @@ AC_DEFUN([gl_UNISTD_H_DEFAULTS],
   GNULIB_FCHDIR=0;        AC_SUBST([GNULIB_FCHDIR])
   GNULIB_FTRUNCATE=0;     AC_SUBST([GNULIB_FTRUNCATE])
   GNULIB_GETCWD=0;        AC_SUBST([GNULIB_GETCWD])
+  GNULIB_GETHOSTNAME=0;   AC_SUBST([GNULIB_GETHOSTNAME])
   GNULIB_GETLOGIN_R=0;    AC_SUBST([GNULIB_GETLOGIN_R])
   GNULIB_GETPAGESIZE=0;   AC_SUBST([GNULIB_GETPAGESIZE])
   GNULIB_LCHOWN=0;        AC_SUBST([GNULIB_LCHOWN])
@@ -49,6 +50,7 @@ AC_DEFUN([gl_UNISTD_H_DEFAULTS],
   HAVE_GETPAGESIZE=1;     AC_SUBST([HAVE_GETPAGESIZE])
   HAVE_READLINK=1;        AC_SUBST([HAVE_READLINK])
   HAVE_SLEEP=1;           AC_SUBST([HAVE_SLEEP])
+  HAVE_DECL_GETHOSTNAME=1;AC_SUBST([HAVE_DECL_GETHOSTNAME])
   HAVE_DECL_GETLOGIN_R=1; AC_SUBST([HAVE_DECL_GETLOGIN_R])
   HAVE_OS_H=0;            AC_SUBST([HAVE_OS_H])
   HAVE_SYS_PARAM_H=0;     AC_SUBST([HAVE_SYS_PARAM_H])
diff --git a/modules/gethostname b/modules/gethostname
index 7c13807..9cb1c23 100644
--- a/modules/gethostname
+++ b/modules/gethostname
@@ -6,13 +6,17 @@ lib/gethostname.c
 m4/gethostname.m4
 
 Depends-on:
+sockets
+unistd
 
 configure.ac:
 gl_FUNC_GETHOSTNAME
+gl_UNISTD_MODULE_INDICATOR([gethostname])
 
 Makefile.am:
 
 Include:
+<unistd.h>
 
 License:
 LGPL
diff --git a/modules/unistd b/modules/unistd
index 4d16cf3..a47e94b 100644
--- a/modules/unistd
+++ b/modules/unistd
@@ -28,6 +28,7 @@ unistd.h: unistd.in.h
              -e 's|@''GNULIB_FCHDIR''@|$(GNULIB_FCHDIR)|g' \
              -e 's|@''GNULIB_FTRUNCATE''@|$(GNULIB_FTRUNCATE)|g' \
              -e 's|@''GNULIB_GETCWD''@|$(GNULIB_GETCWD)|g' \
+             -e 's|@''GNULIB_GETHOSTNAME''@|$(GNULIB_GETHOSTNAME)|g' \
              -e 's|@''GNULIB_GETLOGIN_R''@|$(GNULIB_GETLOGIN_R)|g' \
              -e 's|@''GNULIB_GETPAGESIZE''@|$(GNULIB_GETPAGESIZE)|g' \
              -e 's|@''GNULIB_LCHOWN''@|$(GNULIB_LCHOWN)|g' \
@@ -39,6 +40,7 @@ unistd.h: unistd.in.h
              -e 's|@''HAVE_GETPAGESIZE''@|$(HAVE_GETPAGESIZE)|g' \
              -e 's|@''HAVE_READLINK''@|$(HAVE_READLINK)|g' \
              -e 's|@''HAVE_SLEEP''@|$(HAVE_SLEEP)|g' \
+             -e 's|@''HAVE_DECL_GETHOSTNAME''@|$(HAVE_DECL_GETHOSTNAME)|g' \
              -e 's|@''HAVE_DECL_GETLOGIN_R''@|$(HAVE_DECL_GETLOGIN_R)|g' \
              -e 's|@''HAVE_OS_H''@|$(HAVE_OS_H)|g' \
              -e 's|@''HAVE_SYS_PARAM_H''@|$(HAVE_SYS_PARAM_H)|g' \




reply via email to

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