]> Savannah Git Hosting - gnulib.git/commitdiff
xgethostname: reorganize / simplify
authorPaul Eggert <eggert@cs.ucla.edu>
Sat, 3 Apr 2021 23:07:21 +0000 (16:07 -0700)
committerPaul Eggert <eggert@cs.ucla.edu>
Sat, 3 Apr 2021 23:07:38 +0000 (16:07 -0700)
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
lib/xgetdomainname.c
lib/xgethostname.c
modules/xgetdomainname

index 956f6dd57a0494d1f669f5f5e9ac506e0864984d..804e228972c883c5340ce242282211b60d744c97 100644 (file)
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,3 +1,28 @@
+2021-04-03  Paul Eggert  <eggert@cs.ucla.edu>
+
+       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  <bruno@clisp.org>
 
        *-list tests: Add more tests.
index d77c9b7040a71ed3f6d0621dde955462d4b32a14..3c0aefd1db20734a53f56eeb10010fcdfee2f1c2 100644 (file)
@@ -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 <https://www.gnu.org/licenses/>.  */
-
-/* Based on xgethostname.c, written by Jim Meyering.  */
-
-#include <config.h>
-
-/* Specification.  */
+/* Return the NIS domain name, without size limitations.  */
 #include "xgetdomainname.h"
-
-/* Get getdomainname.  */
-#include <unistd.h>
-
-/* Get errno.  */
-#include <errno.h>
-
-/* Get strlen.  */
-#include <string.h>
-
-/* Get free.  */
-#include <stdlib.h>
-
-#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"
index 10e13de1d277686343c1a78a5409ea694b38d558..87ae6dce8776103690f45e35c392e900bd628ecc 100644 (file)
    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 */
+/* written by Jim Meyering and Paul Eggert */
 
 #include <config.h>
 
+#ifndef GETANAME
 /* Specification.  */
-#include "xgethostname.h"
+# include "xgethostname.h"
+# define GETANAME gethostname
+# define XGETANAME xgethostname
+#endif
 
 #include <stdlib.h>
 #include <errno.h>
 
 #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;
 }
index d1c9f24594b40bb35c5568b8c402c47d138f9e1d..c1417c8ef6fc97fc4b75ae28490bcc6ff232873a 100644 (file)
@@ -6,9 +6,8 @@ lib/xgetdomainname.h
 lib/xgetdomainname.c
 
 Depends-on:
-free-posix
 getdomainname
-xalloc
+xgethostname
 
 configure.ac: