Hash :
f30ed230
Author :
Date :
2021-04-03T16:07:21
xgethostname: reorganize / simplify xgethostname and xgetdomainname were essentially copies long ago, but they’ve diverged. Bring them back together again by implementing the (rarely used) latter in terms of the former. And avoid some unnecessary realloc calls while we’re at it. * lib/xgetdomainname.c: Rewrite from scratch so that it merely includes xgethostname.c with a few preliminaries. * lib/xgethostname.c: Generalize so that it can be included from xgetdomainname.c. (GETANAME, XGETANAME): New macros. (INITIAL_HOSTNAME_LENGTH): Remove. No need for this parameter. Use 100 instead, as few hostnames are longer than that. (XGETANAME): Try getting the hostname into the stack first, as that avoids a malloc call in the usual case. Check for both POSIX-style truncation and SunOS 5.5 bug in a cleaner way, by simply checking string length. Don’t use x2realloc, which wastes time preserving buffer garbage; use xpalloc with NULL instead. Don’t bother shrinking buffer in the very rare case where the hostname is longer than sizeof buf; it’s not worth the aggravation. * modules/xgetdomainname (Depends-on): Remove free-posix, xalloc. Add xgethostname.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72
/* xgethostname.c -- return current hostname with unlimited length
Copyright (C) 1992, 1996, 2000-2001, 2003-2006, 2009-2021 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 <config.h>
#ifndef GETANAME
/* Specification. */
# include "xgethostname.h"
# define GETANAME gethostname
# define XGETANAME xgethostname
#endif
#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 : xmemdup (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);
}
}