summaryrefslogtreecommitdiffstats
path: root/lib/xgetaname-impl.h
diff options
context:
space:
mode:
Diffstat (limited to 'lib/xgetaname-impl.h')
-rw-r--r--lib/xgetaname-impl.h63
1 files changed, 63 insertions, 0 deletions
diff --git a/lib/xgetaname-impl.h b/lib/xgetaname-impl.h
new file mode 100644
index 0000000..8366166
--- /dev/null
+++ b/lib/xgetaname-impl.h
@@ -0,0 +1,63 @@
+/* xgetaname-impl.c -- common implementation of xgethostname and xgetdomainname
+
+ Copyright (C) 1992, 1996, 2000-2001, 2003-2006, 2009-2022 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
+ the Free Software Foundation, either version 3 of the License, or
+ (at your option) any later version.
+
+ This program is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program. If not, see <https://www.gnu.org/licenses/>. */
+
+/* written by Jim Meyering and Paul Eggert */
+
+#include <stdlib.h>
+#include <errno.h>
+#include <string.h>
+#include <unistd.h>
+
+#include "xalloc.h"
+
+/* Return the current host or domain name in malloc'd storage.
+ If malloc fails, exit.
+ Upon any other failure, return NULL and set errno. */
+char *
+XGETANAME (void)
+{
+ char buf[100];
+ idx_t size = sizeof buf;
+ char *name = buf;
+ char *alloc = NULL;
+
+ while (1)
+ {
+ /* Use SIZE_1 here rather than SIZE to work around the bug in
+ SunOS 5.5's gethostname whereby it NUL-terminates HOSTNAME
+ even when the name is as long as the supplied buffer. */
+ idx_t size_1 = size - 1;
+ name[size_1] = '\0';
+ errno = 0;
+ if (GETANAME (name, size_1) == 0)
+ {
+ /* Check whether the name was possibly truncated; POSIX does not
+ specify whether a truncated name is null-terminated. */
+ idx_t actual_size = strlen (name) + 1;
+ if (actual_size < size_1)
+ return alloc ? alloc : ximemdup (name, actual_size);
+ errno = 0;
+ }
+ free (alloc);
+ if (errno != 0 && errno != ENAMETOOLONG && errno != EINVAL
+ /* macOS/Darwin does this when SIZE_1 is too small. */
+ && errno != ENOMEM)
+ return NULL;
+ name = alloc = xpalloc (NULL, &size, 1, -1, 1);
+ }
+}