mirror of
https://https.git.savannah.gnu.org/git/gnulib.git
synced 2026-09-04 04:31:33 +00:00
sethostname: Port to Windows platforms.
* lib/sethostname.c: Provide an alternate implementation for Windows platforms. * tests/test-sethostname2.c (geteuid): Redefine on Cygwin. (main): Skip the test if sethostname() fails with EPERM. On Windows platforms, don't check the result of gethostname(). 2011-12-04 Bruno Haible <bruno@clisp.org>
This commit is contained in:
@@ -1,3 +1,12 @@
|
||||
2011-12-04 Bruno Haible <bruno@clisp.org>
|
||||
|
||||
sethostname: Port to Windows platforms.
|
||||
* lib/sethostname.c: Provide an alternate implementation for Windows
|
||||
platforms.
|
||||
* tests/test-sethostname2.c (geteuid): Redefine on Cygwin.
|
||||
(main): Skip the test if sethostname() fails with EPERM. On Windows
|
||||
platforms, don't check the result of gethostname().
|
||||
|
||||
2011-12-04 Bruno Haible <bruno@clisp.org>
|
||||
Jim Meyering <meyering@redhat.com>
|
||||
|
||||
|
||||
@@ -19,6 +19,7 @@
|
||||
|
||||
#include <config.h>
|
||||
|
||||
#if !((defined _WIN32 || defined __WIN32__) || defined __CYGWIN__)
|
||||
/* Unix API. */
|
||||
|
||||
/* Specification. */
|
||||
@@ -82,3 +83,80 @@ sethostname (const char *name, size_t len)
|
||||
return -1;
|
||||
#endif
|
||||
}
|
||||
|
||||
#else
|
||||
/* Native Windows API. Also used on Cygwin. */
|
||||
|
||||
/* Ensure that <windows.h> declares SetComputerNameEx. */
|
||||
#undef _WIN32_WINNT
|
||||
#define _WIN32_WINNT 0x500
|
||||
|
||||
#define WIN32_LEAN_AND_MEAN
|
||||
|
||||
/* Specification. */
|
||||
#include <unistd.h>
|
||||
|
||||
#include <errno.h>
|
||||
#include <limits.h>
|
||||
#include <string.h>
|
||||
|
||||
#include <windows.h>
|
||||
/* The mingw header files don't define GetComputerNameEx, SetComputerNameEx. */
|
||||
#ifndef GetComputerNameEx
|
||||
# define GetComputerNameEx GetComputerNameExA
|
||||
#endif
|
||||
#ifndef SetComputerNameEx
|
||||
# define SetComputerNameEx SetComputerNameExA
|
||||
#endif
|
||||
|
||||
/* Set up to LEN chars of NAME as system hostname.
|
||||
Return 0 if ok, set errno and return -1 on error. */
|
||||
|
||||
int
|
||||
sethostname (const char *name, size_t len)
|
||||
{
|
||||
char name_asciz[HOST_NAME_MAX + 1];
|
||||
char old_name[HOST_NAME_MAX + 1];
|
||||
DWORD old_name_len;
|
||||
|
||||
/* Ensure the string isn't too long. glibc does allow setting an
|
||||
empty hostname so no point in enforcing a lower bound. */
|
||||
if (len > HOST_NAME_MAX)
|
||||
{
|
||||
errno = EINVAL;
|
||||
return -1;
|
||||
}
|
||||
|
||||
/* Prepare a NUL-terminated copy of name. */
|
||||
memcpy (name_asciz, name, len);
|
||||
name_asciz[len] = '\0';
|
||||
|
||||
/* Save the old NetBIOS name. */
|
||||
old_name_len = sizeof (old_name) - 1;
|
||||
if (! GetComputerNameEx (ComputerNamePhysicalNetBIOS,
|
||||
old_name, &old_name_len))
|
||||
old_name_len = 0;
|
||||
|
||||
/* Set both the NetBIOS and the first part of the IP / DNS name. */
|
||||
if (! SetComputerNameEx (ComputerNamePhysicalNetBIOS, name_asciz))
|
||||
{
|
||||
errno = (GetLastError () == ERROR_ACCESS_DENIED ? EPERM : EINVAL);
|
||||
return -1;
|
||||
}
|
||||
if (! SetComputerNameEx (ComputerNamePhysicalDnsHostname, name_asciz))
|
||||
{
|
||||
errno = (GetLastError () == ERROR_ACCESS_DENIED ? EPERM : EINVAL);
|
||||
/* Restore the old NetBIOS name. */
|
||||
if (old_name_len > 0)
|
||||
{
|
||||
old_name[old_name_len] = '\0';
|
||||
SetComputerNameEx (ComputerNamePhysicalNetBIOS, old_name);
|
||||
}
|
||||
return -1;
|
||||
}
|
||||
|
||||
/* Note that the new host name becomes effective only after a reboot! */
|
||||
return 0;
|
||||
}
|
||||
|
||||
#endif
|
||||
|
||||
@@ -31,8 +31,10 @@
|
||||
|
||||
#define TESTHOSTNAME "gnulib-hostname"
|
||||
|
||||
/* mingw and MSVC 9 lack geteuid, so setup a dummy value. */
|
||||
#if !HAVE_GETEUID
|
||||
/* mingw and MSVC 9 lack geteuid, so setup a dummy value.
|
||||
On Cygwin, geteuid() may return non-zero even for user accounts with
|
||||
administrator privileges, so use a dummy value as well. */
|
||||
#if !HAVE_GETEUID || defined __CYGWIN__
|
||||
# define geteuid() 0
|
||||
#endif
|
||||
|
||||
@@ -72,6 +74,11 @@ main (int argc, char *argv[] _GL_UNUSED)
|
||||
"Skipping test: sethostname is not really implemented.\n");
|
||||
return 77;
|
||||
}
|
||||
else if (rcs == -1 && errno == EPERM)
|
||||
{
|
||||
fprintf (stderr, "Skipping test: insufficient permissions.\n");
|
||||
return 77;
|
||||
}
|
||||
else
|
||||
{
|
||||
fprintf (stderr, "error setting valid hostname.\n");
|
||||
@@ -82,6 +89,10 @@ main (int argc, char *argv[] _GL_UNUSED)
|
||||
{
|
||||
ASSERT (gethostname (newname, sizeof (newname)) == 0);
|
||||
|
||||
/* On Windows, a hostname change becomes effective only after
|
||||
a reboot. */
|
||||
#if !((defined _WIN32 || defined __WIN32__) || defined __CYGWIN__)
|
||||
|
||||
/* if we don't get back what we put in, there is no need to
|
||||
restore the original name as we will assume it was not
|
||||
properly changed. */
|
||||
@@ -90,6 +101,7 @@ main (int argc, char *argv[] _GL_UNUSED)
|
||||
fprintf (stderr, "set/get comparison failed.\n");
|
||||
return 1;
|
||||
}
|
||||
#endif
|
||||
}
|
||||
|
||||
/* glibc does allow setting a zero length name, so the lower bound
|
||||
|
||||
Reference in New Issue
Block a user