usleep tests: Avoid failure due to known Cygwin 3.5.3 bug.
[gnulib.git] / tests / test-sethostname2.c
blob25a3ae1857cf5083bfe9385069c754455d588ce0
1 /*
2 * Copyright (C) 2011-2024 Free Software Foundation, Inc.
3 * Written by Ben Walton.
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 #include <config.h>
20 #include <unistd.h>
22 /* for HOST_NAME_MAX */
23 #include <limits.h>
24 /* for strlen */
25 #include <string.h>
27 #include <errno.h>
28 #include <stdio.h>
30 #include "root-uid.h"
32 #include "macros.h"
34 #define TESTHOSTNAME "gnulib-hostname"
36 /* mingw and MSVC 9 lack geteuid, so setup a dummy value.
37 On Cygwin, geteuid() may return non-zero even for user accounts with
38 administrator privileges, so use a dummy value as well. */
39 #if !HAVE_GETEUID || defined __CYGWIN__
40 # define geteuid() ROOT_UID
41 #endif
43 int
44 main (int argc, _GL_UNUSED char *argv[])
46 char origname[HOST_NAME_MAX];
47 char newname[HOST_NAME_MAX];
48 int rcs, i;
50 /* skip the tests if we don't have root privilege. this does not
51 consider things like CAP_SYS_ADMIN (linux) or PRIV_SYS_ADMIN
52 (solaris), etc. systems without a working geteuid (mingw, MSVC
53 9) will always skip this test. */
54 if (geteuid () != ROOT_UID)
56 fprintf (stderr, "Skipping test: insufficient permissions.\n");
57 return 77;
60 /* we want to ensure we can do a get/set/get check to ensure the
61 change is accepted. record the current name so it can be restored
62 later */
63 ASSERT (gethostname (origname, sizeof (origname)) == 0);
65 /* try setting a valid hostname. if it fails -1/ENOSYS, we will
66 skip the test for long names as this is an indication we're using
67 the stub function that doesn't do anything on this platform. */
68 rcs = sethostname (TESTHOSTNAME, strlen (TESTHOSTNAME));
70 if (rcs != 0)
72 if (rcs == -1 && errno == ENOSYS)
74 fprintf (stderr,
75 "Skipping test: sethostname is not really implemented.\n");
76 return 77;
78 else if (rcs == -1
79 && (errno == EPERM
80 || errno == EACCES)) /* Cygwin */
82 fprintf (stderr, "Skipping test: insufficient permissions.\n");
83 return 77;
85 else
87 fprintf (stderr, "error setting valid hostname.\n");
88 return 1;
91 else
93 ASSERT (gethostname (newname, sizeof (newname)) == 0);
95 /* On Windows, a hostname change becomes effective only after
96 a reboot. */
97 #if !(defined _WIN32 || defined __CYGWIN__)
99 /* if we don't get back what we put in, there is no need to
100 restore the original name as we will assume it was not
101 properly changed. */
102 if (strcmp (newname, TESTHOSTNAME) != 0)
104 fprintf (stderr, "set/get comparison failed.\n");
105 return 1;
107 #endif
110 /* Known Cygwin bug:
111 <https://cygwin.com/pipermail/cygwin/2024-May/255986.html> */
112 #if !defined __CYGWIN__
114 char longname[HOST_NAME_MAX + 2];
116 /* glibc does allow setting a zero length name, so the lower bound
117 needs no test. validate that we are constrained by
118 HOST_NAME_MAX */
119 for (i = 0; i < (HOST_NAME_MAX + 1); i++)
120 longname[i] = 'a';
122 longname[i] = '\0';
124 rcs = sethostname (longname, (HOST_NAME_MAX + 1));
126 if (rcs != -1)
128 /* attempt to restore the original name. */
129 ASSERT (sethostname (origname, strlen (origname)) == 0);
130 fprintf (stderr, "setting a too long hostname succeeded.\n");
131 return 1;
134 #endif
136 /* restore the original name. */
137 ASSERT (sethostname (origname, strlen (origname)) == 0);
139 return test_exit_status;