+2004-11-16 Paul Eggert <eggert@cs.ucla.edu>
+
+ * modules/canon-host (Depends-on): Add strdup.
+
2004-11-16 Jim Meyering <jim@meyering.net>
* modules/closeout (Depends-on): Add fpending.
2004-11-16 Paul Eggert <eggert@cs.ucla.edu>
+ * canon-host.c: Include "strdup.h".
+ (canon_host): Use getaddrinfo if available, so that IPv6 works.
+ Use strdup instead of malloc/strcpy to duplicate strings.
+
Further getopt changes to make it more likely that glibc will
buy the changes back.
* getopt.c (POSIXLY_CORRECT): New constant.
/* Host name canonicalization
- Copyright (C) 1995, 1999, 2000, 2002, 2003 Free Software Foundation, Inc.
+ Copyright (C) 1995, 1999, 2000, 2002, 2003, 2004 Free Software
+ Foundation, Inc.
Written by Miles Bader <miles@gnu.ai.mit.edu>
# include <arpa/inet.h>
#endif
+#include "strdup.h"
+
/* Returns the canonical hostname associated with HOST (allocated in a static
- buffer), or 0 if it can't be determined. */
+ buffer), or NULL if it can't be determined. */
char *
-canon_host (const char *host)
+canon_host (char const *host)
{
-#ifdef HAVE_GETHOSTBYNAME
- struct hostent *he = gethostbyname (host);
+ char *h_addr_copy = NULL;
- if (he)
- {
+#if HAVE_GETADDRINFO
+ {
+ struct addrinfo hint = { 0 };
+ struct addrinfo *res = NULL;
+ hint.ai_flags = AI_CANONNAME;
+ if (getaddrinfo (host, NULL, &hint, &res) == 0)
+ {
+ h_addr_copy = strdup (res->ai_canonname);
+ freeaddrinfo (res);
+ }
+ }
+#elif HAVE_GETHOSTBYNAME
+ {
+ struct hostent *he = gethostbyname (host);
+
+ if (he)
+ {
# ifdef HAVE_GETHOSTBYADDR
- char *addr = 0;
+ char *addr = NULL;
- /* Try and get an ascii version of the numeric host address. */
- switch (he->h_addrtype)
- {
+ /* Try and get an ascii version of the numeric host address. */
+ switch (he->h_addrtype)
+ {
# ifdef HAVE_INET_NTOA
- case AF_INET:
- addr = inet_ntoa (*(struct in_addr *) he->h_addr);
- break;
+ case AF_INET:
+ addr = inet_ntoa (*(struct in_addr *) he->h_addr);
+ break;
# endif /* HAVE_INET_NTOA */
- }
-
- if (addr && strcmp (he->h_name, addr) == 0)
- {
- /* gethostbyname has returned a string representation of the IP
- address, for example, "127.0.0.1". So now, look up the host
- name via the address. Although it may seem reasonable to look
- up the host name via the address, we must not pass `he->h_addr'
- directly to gethostbyaddr because on some systems he->h_addr
- is located in a static library buffer that is reused in the
- gethostbyaddr call. Make a copy and use that instead. */
- char *h_addr_copy = (char *) malloc (he->h_length);
- if (h_addr_copy == NULL)
- he = NULL;
- else
- {
- memcpy (h_addr_copy, he->h_addr, he->h_length);
- he = gethostbyaddr (h_addr_copy, he->h_length, he->h_addrtype);
- free (h_addr_copy);
- }
- }
+ }
+
+ if (addr && strcmp (he->h_name, addr) == 0)
+ {
+ /* gethostbyname has returned a string representation of the IP
+ address, for example, "127.0.0.1". So now, look up the host
+ name via the address. Although it may seem reasonable to look
+ up the host name via the address, we must not pass `he->h_addr'
+ directly to gethostbyaddr because on some systems he->h_addr
+ is located in a static library buffer that is reused in the
+ gethostbyaddr call. Make a copy and use that instead. */
+ h_addr_copy = (char *) malloc (he->h_length);
+ if (h_addr_copy == NULL)
+ he = NULL;
+ else
+ {
+ memcpy (h_addr_copy, he->h_addr, he->h_length);
+ he = gethostbyaddr (h_addr_copy, he->h_length, he->h_addrtype);
+ free (h_addr_copy);
+ }
+ }
# endif /* HAVE_GETHOSTBYADDR */
- if (he)
- return (char *) (he->h_name);
- }
+ if (he)
+ h_addr_copy = strdup (he->h_name);
+ }
+ }
#endif /* HAVE_GETHOSTBYNAME */
- return 0;
+
+ return h_addr_copy;
}
#ifdef TEST_CANON_HOST
so on. Numbers smaller than the power aren't modified.
human_autoscale is normally used together with human_SI.
+ If (OPTS & human_space_before_unit), use a space to separate the
+ number from any suffix that is appended as described below.
+
If (OPTS & human_SI), append an SI prefix indicating which power is
being used. If in addition (OPTS & human_B), append "B" (if base
1000) or "iB" (if base 1024) to the SI prefix. When ((OPTS &
break;
}
+ if ((exponent | (opts & human_B)) && (opts & human_space_before_unit))
+ *psuffix++ = ' ';
+
if (exponent)
*psuffix++ = (! (opts & human_base_1024) && exponent == 1
? 'k'
302 / 1000 is ceil (log10 (2.0)). Add 1 for integer division truncation.
Also, the output can have a thousands separator between every digit,
so multiply by MB_LEN_MAX + 1 and then subtract MB_LEN_MAX.
+ Append 1 for a space before the suffix.
Finally, append 3, the maximum length of a suffix. */
# define LONGEST_HUMAN_READABLE \
((2 * sizeof (uintmax_t) * CHAR_BIT * 302 / 1000 + 1) * (MB_LEN_MAX + 1) \
- - MB_LEN_MAX + 3)
+ - MB_LEN_MAX + 1 + 3)
/* Options for human_readable. */
enum
/* Prefer base 1024 to base 1000. */
human_base_1024 = 32,
+ /* Prepend " " before unit symbol. */
+ human_space_before_unit = 64,
+
/* Append SI prefix, e.g. "k" or "M". */
- human_SI = 64,
+ human_SI = 128,
/* Append "B" (if base 1000) or "iB" (if base 1024) to SI prefix. */
- human_B = 128
+ human_B = 256
};
char *human_readable (uintmax_t, char *, int, uintmax_t, uintmax_t);
# include <config.h>
#endif
+#include <limits.h>
#include <stdio.h>
#include <errno.h>
#include <sys/types.h>
return cwd;
#else
+ int saved_errno;
+
/* The initial buffer size for the working directory. A power of 2
detects arithmetic overflow earlier, but is not required. */
# ifndef INITIAL_BUFFER_SIZE
{
char *buf = xmalloc (buf_size);
char *cwd = getcwd (buf, buf_size);
- int saved_errno;
if (cwd)
return cwd;
saved_errno = errno;
free (buf);
if (saved_errno != ERANGE)
- return NULL;
+ break;
+
+#ifdef PATH_MAX
+ if (PATH_MAX / 2 < buf_size)
+ {
+ if (PATH_MAX <= buf_size)
+ break;
+ buf_size = PATH_MAX;
+ continue;
+ }
+#endif
+
buf_size *= 2;
if (buf_size == 0)
xalloc_die ();
}
+
+ errno = saved_errno;
+ return NULL;
#endif
}
+2004-11-16 Paul Eggert <eggert@cs.ucla.edu>
+
+ * canon-host.m4 (gl_CANON_HOST): Check for getaddrinfo.
+
+2004-11-13 Jim Meyering <jim@meyering.net>
+
+ * jm-macros.m4: Do require gl_FUNC_FPENDING.
+
2004-11-11 Paul Eggert <eggert@cs.ucla.edu>
* getopt.m4 (gl_GETOPT_SUBSTITUTE): Define __GETOPT_PREFIX instead
-# canon-host.m4 serial 3
-dnl Copyright (C) 2002, 2003 Free Software Foundation, Inc.
+# canon-host.m4 serial 4
+dnl Copyright (C) 2002, 2003, 2004 Free Software Foundation, Inc.
dnl This file is free software, distributed under the terms of the GNU
dnl General Public License. As a special exception to the GNU General
dnl Public License, this file may be distributed as part of a program
AC_SEARCH_LIBS(gethostbyname, [inet nsl])
dnl These come from -lnsl on Solaris 2.5.1.
- AC_CHECK_FUNCS(gethostbyname gethostbyaddr inet_ntoa)
+ AC_CHECK_FUNCS(getaddrinfo gethostbyname gethostbyaddr inet_ntoa)
])
-#serial 77 -*- autoconf -*-
+#serial 78 -*- autoconf -*-
dnl Misc type-related macros for coreutils.
AC_REQUIRE([gl_FUNC_GROUP_MEMBER])
AC_REQUIRE([gl_AFS])
AC_REQUIRE([gl_AC_FUNC_LINK_FOLLOWS_SYMLINK])
+ AC_REQUIRE([gl_FUNC_FPENDING])
# This is for od and stat, and any other program that
# uses the PRI.MAX macros from inttypes.h.
m4/canon-host.m4
Depends-on:
+strdup
configure.ac:
gl_CANON_HOST
Maintainer:
Jim Meyering
-