1 /* sethostname emulation for glibc compliance.
3 Copyright (C) 2011-2020 Free Software Foundation, Inc.
5 This program is free software: you can redistribute it and/or modify
6 it under the terms of the GNU General Public License as published by
7 the Free Software Foundation; either version 3 of the License, or
8 (at your option) any later version.
10 This program is distributed in the hope that it will be useful,
11 but WITHOUT ANY WARRANTY; without even the implied warranty of
12 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13 GNU General Public License for more details.
15 You should have received a copy of the GNU General Public License
16 along with this program. If not, see <https://www.gnu.org/licenses/>. */
18 /* Ben Walton <bwalton@artsci.utoronto.ca> */
22 #if !(defined _WIN32 || defined __CYGWIN__)
32 /* Set up to LEN chars of NAME as system hostname.
33 Return 0 if ok, set errno and return -1 on error. */
36 sethostname (const char *name
, size_t len
)
38 /* Ensure the string isn't too long. glibc does allow setting an
39 empty hostname so no point in enforcing a lower bound. */
40 if (len
> HOST_NAME_MAX
)
46 # ifdef __minix /* Minix */
51 /* glibc returns EFAULT, EINVAL, and EPERM on error. None of
52 these are appropriate for us to set, even if they may match the
53 situation, during failed open/write/close operations, so we
54 leave errno alone and rely on what the system sets up. */
55 hostf
= fopen ("/etc/hostname.file", "we");
60 fprintf (hostf
, "%.*s\n", (int) len
, name
);
63 /* Close hostf, preserving the errno from the fprintf call. */
64 int saved_errno
= errno
;
72 /* fclose sets errno on failure. */
80 /* For platforms that we don't have a better option for, simply bail
88 /* Native Windows API. Also used on Cygwin. */
90 /* Ensure that <windows.h> declares SetComputerNameEx. */
91 # if !defined _WIN32_WINNT || (_WIN32_WINNT < _WIN32_WINNT_WIN2K)
93 # define _WIN32_WINNT _WIN32_WINNT_WIN2K
96 # define WIN32_LEAN_AND_MEAN
105 # include <windows.h>
107 /* Don't assume that UNICODE is not defined. */
108 # undef GetComputerNameEx
109 # define GetComputerNameEx GetComputerNameExA
110 # undef SetComputerNameEx
111 # define SetComputerNameEx SetComputerNameExA
113 /* Set up to LEN chars of NAME as system hostname.
114 Return 0 if ok, set errno and return -1 on error. */
117 sethostname (const char *name
, size_t len
)
119 char name_asciz
[HOST_NAME_MAX
+ 1];
120 char old_name
[HOST_NAME_MAX
+ 1];
123 /* Ensure the string isn't too long. glibc does allow setting an
124 empty hostname so no point in enforcing a lower bound. */
125 if (len
> HOST_NAME_MAX
)
131 /* Prepare a NUL-terminated copy of name. */
132 memcpy (name_asciz
, name
, len
);
133 name_asciz
[len
] = '\0';
135 /* Save the old NetBIOS name. */
136 old_name_len
= sizeof (old_name
) - 1;
137 if (! GetComputerNameEx (ComputerNamePhysicalNetBIOS
,
138 old_name
, &old_name_len
))
141 /* Set both the NetBIOS and the first part of the IP / DNS name. */
142 if (! SetComputerNameEx (ComputerNamePhysicalNetBIOS
, name_asciz
))
144 errno
= (GetLastError () == ERROR_ACCESS_DENIED
? EPERM
: EINVAL
);
147 if (! SetComputerNameEx (ComputerNamePhysicalDnsHostname
, name_asciz
))
149 errno
= (GetLastError () == ERROR_ACCESS_DENIED
? EPERM
: EINVAL
);
150 /* Restore the old NetBIOS name. */
151 if (old_name_len
> 0)
153 old_name
[old_name_len
] = '\0';
154 SetComputerNameEx (ComputerNamePhysicalNetBIOS
, old_name
);
159 /* Note that the new host name becomes effective only after a reboot! */