>From 635076e47c7a000a11b3c2d173d5ef047fcf9af2 Mon Sep 17 00:00:00 2001 From: Paul Eggert Date: Sat, 3 Apr 2021 16:07:21 -0700 Subject: [PATCH] xgethostname: reorganize / simplify MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit 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. --- ChangeLog | 25 ++++++++++++ lib/xgetdomainname.c | 92 ++---------------------------------------- lib/xgethostname.c | 66 +++++++++++++----------------- modules/xgetdomainname | 3 +- 4 files changed, 57 insertions(+), 129 deletions(-) diff --git a/ChangeLog b/ChangeLog index 956f6dd57..804e22897 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,28 @@ +2021-04-03 Paul Eggert + + 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. + 2021-04-03 Bruno Haible *-list tests: Add more tests. diff --git a/lib/xgetdomainname.c b/lib/xgetdomainname.c index d77c9b704..3c0aefd1d 100644 --- a/lib/xgetdomainname.c +++ b/lib/xgetdomainname.c @@ -1,89 +1,5 @@ -/* xgetdomainname.c -- Return the NIS domain name, without size limitations. - Copyright (C) 1992, 1996, 2000-2001, 2003-2004, 2006, 2008-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 . */ - -/* Based on xgethostname.c, written by Jim Meyering. */ - -#include - -/* Specification. */ +/* Return the NIS domain name, without size limitations. */ #include "xgetdomainname.h" - -/* Get getdomainname. */ -#include - -/* Get errno. */ -#include - -/* Get strlen. */ -#include - -/* Get free. */ -#include - -#include "xalloc.h" - -#ifndef INITIAL_DOMAINNAME_LENGTH -# define INITIAL_DOMAINNAME_LENGTH 34 -#endif - -/* Return the NIS domain name of the machine, in malloc'd storage. - WARNING! The NIS domain name is unrelated to the fully qualified host name - of the machine. It is also unrelated to email addresses. - WARNING! The NIS domain name is usually the empty string or "(none)" when - not using NIS. - If malloc fails, exit. - Upon any other failure, set errno and return NULL. */ -char * -xgetdomainname (void) -{ - char *domainname; - size_t size; - - size = INITIAL_DOMAINNAME_LENGTH; - domainname = xmalloc (size); - while (1) - { - int k = size - 1; - int err; - - errno = 0; - domainname[k] = '\0'; - err = getdomainname (domainname, size); - if (err >= 0 && domainname[k] == '\0') - break; - else if (err < 0 && errno != EINVAL) - { - free (domainname); - return NULL; - } - size *= 2; - domainname = xrealloc (domainname, size); - } - - /* Shrink DOMAINNAME before returning it. */ - { - size_t actual_size = strlen (domainname) + 1; - if (actual_size < size) - { - char *shrinked_domainname = realloc (domainname, actual_size); - if (shrinked_domainname != NULL) - domainname = shrinked_domainname; - } - } - - return domainname; -} +#define GETANAME getdomainname +#define XGETANAME xgetdomainname +#include "xgethostname.c" diff --git a/lib/xgethostname.c b/lib/xgethostname.c index 10e13de1d..87ae6dce8 100644 --- a/lib/xgethostname.c +++ b/lib/xgethostname.c @@ -16,12 +16,16 @@ You should have received a copy of the GNU General Public License along with this program. If not, see . */ -/* written by Jim Meyering */ +/* written by Jim Meyering and Paul Eggert */ #include +#ifndef GETANAME /* Specification. */ -#include "xgethostname.h" +# include "xgethostname.h" +# define GETANAME gethostname +# define XGETANAME xgethostname +#endif #include #include @@ -30,55 +34,39 @@ #include "xalloc.h" -#ifndef INITIAL_HOSTNAME_LENGTH -# define INITIAL_HOSTNAME_LENGTH 34 -#endif - -/* Return the current hostname in malloc'd storage. +/* 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 * -xgethostname (void) +XGETANAME (void) { - char *hostname = NULL; - size_t size = INITIAL_HOSTNAME_LENGTH; + 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. */ - size_t size_1; - - hostname = x2realloc (hostname, &size); - size_1 = size - 1; - hostname[size_1 - 1] = '\0'; + idx_t size_1 = size - 1; + name[size_1] = '\0'; errno = 0; - - if (gethostname (hostname, size_1) == 0) + if (GETANAME (name, size_1) == 0) { - if (! hostname[size_1 - 1]) - break; - } - else if (errno != 0 && errno != ENAMETOOLONG && errno != EINVAL - /* OSX/Darwin does this when the buffer is not large enough */ - && errno != ENOMEM) - { - free (hostname); - return NULL; + /* 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); } - - /* Shrink HOSTNAME before returning it. */ - { - size_t actual_size = strlen (hostname) + 1; - if (actual_size < size) - { - char *shrinked_hostname = realloc (hostname, actual_size); - if (shrinked_hostname != NULL) - hostname = shrinked_hostname; - } - } - - return hostname; } diff --git a/modules/xgetdomainname b/modules/xgetdomainname index d1c9f2459..c1417c8ef 100644 --- a/modules/xgetdomainname +++ b/modules/xgetdomainname @@ -6,9 +6,8 @@ lib/xgetdomainname.h lib/xgetdomainname.c Depends-on: -free-posix getdomainname -xalloc +xgethostname configure.ac: -- 2.27.0