[Top][All Lists]
[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]
Re: gethostname on mingw, LIBS
From: |
Bruno Haible |
Subject: |
Re: gethostname on mingw, LIBS |
Date: |
Thu, 23 Oct 2008 13:45:29 +0200 |
User-agent: |
KMail/1.5.4 |
Hi Simon,
> > Note that this does not resolve the issue with mingw. On mingw, <winsock2.h>
> > declares gethostname() also - but it requires linking with -lws2_32,
> > right?
>
> Yes.
>
> Win32 also has GetComputerName that does not need -lws2_32. It would be
> easier to use, but which one is right semantically I don't know.
It's easy to google for "site:msdn.microsoft.com gethostname" and
"site:msdn.microsoft.com GetComputerName". Just did that, and found that
- GetComputerName is not the right thing, but GetComputerNameEx is.
- While gethostname requires to link with -lws2_32, GetComputerNameEx
does not.
> > 2. Should this be done through immediate linking, or dynamic linking?
>
> getaddrinfo.m4 adds -lws2_32 to LIBS automatically now.
Please don't do that. A project builds several applications in general.
In gettext, just because I have one program which needs select() and another
program which does network requests, I don't want all programs, from 'msgfmt'
to 'xgettext', to link with unneeded libraries.
> It may be cleaner to define a MINGW_LIBS variable instead, and ask
> developers to add $(MINGW_LIBS) to automake LIBADD variables for
> executables that need it. sockets.m4 has been fixed in this way
> already.
MINGW_LIBS is not specific enough. How could a developer know on which
programs he needs it or not. IMO all library requirements must be attached
to particular modules with a particular purpose. Like $(LIBSOCKET),
$(LIBICONV), $(LIBTHREAD).
> Possibly the -lws2_32/LIBSOCKET/MINGW_LIBS handling should be put in a
> separate module? Then getaddrinfo and sockets can depend on it,
> rather than duplicating it.
Yes, you're welcome to do this. But call it LIBSOCKET, please.
> gethostname.c could also use GetModuleHandle, similar to how
> getaddrinfo.c works, to avoid the -lws2_32 requirement. If the
> application would not otherwise link to -lws2_32 this approach may be
> nicer. But if applications are linked to -lws2_32 because of other
> gnulib modules anyway, it doesn't make much sense.
Yes, when you need the host name, usually it's in the context of network
accesses.
> The GetModuleHandle approach, together with a fallback replacement
> function, results in better portability generally. Some Windows
> releases does not have getaddrinfo, and if the application is linked
> against -lws2_32 that has it, and the binary is transferred to an old
> system, it won't work.
For my part, I drop portability requirements to Windows98/ME, and assume
Windows 2000 at least. Reason: The documentation on msdn.microsoft.com
does not even mention any more which functions were defined in Windows98/ME
or not.
> Maybe the same approach cannot be used for gethostname: ...
>
> I'm not sure. It seems pretty clear that MINGW_LIBS and GetModuleHandle
> are two approaches that can solve this problem.
And with GetComputerNameEx, there is no link requirement at all.
I propose this, together with some WINVER tricks to make it work.
--- lib/gethostname.c.orig 2008-10-23 13:45:02.000000000 +0200
+++ lib/gethostname.c 2008-10-23 13:44:03.000000000 +0200
@@ -22,8 +22,10 @@
/* Specification. */
#include <unistd.h>
-#ifdef HAVE_UNAME
+#if HAVE_UNAME
# include <sys/utsname.h>
+#elif (defined _WIN32 || defined __WIN32__) && ! defined __CYGWIN__
+# include <windows.h>
#endif
#include <string.h>
@@ -37,7 +39,7 @@
int
gethostname (char *name, size_t len)
{
-#ifdef HAVE_UNAME
+#if HAVE_UNAME
struct utsname uts;
if (uname (&uts) == -1)
@@ -49,6 +51,14 @@
len = sizeof (uts.nodename);
}
strncpy (name, uts.nodename, len);
+#elif (defined _WIN32 || defined __WIN32__) && ! defined __CYGWIN__
+ /* GetComputerName is not the right thing. gethostname from <winsock2.h>
+ would be right, but requires linking with -lws2_32. So we use
+ GetComputerNameEx. */
+ DWORD size = (len <= (DWORD)~0 ? len : (DWORD)~0);
+
+ if (!GetComputerNameEx (ComputerNameDnsHostname, name, &size))
+ return -1;
#else
strcpy (name, ""); /* Hardcode your system name if you want. */
#endif