I did most of this weeks ago and just noticed I never checked it in. Ok with you, Bruno?
Rewrite xreadlink as a trivial mreadlink wrapper. * lib/xreadlink.c (xreadlink): Rewrite as a simple mreadlink wrapper. * modules/xreadlink: Adjust dependencies. Index: lib/xreadlink.c =================================================================== RCS file: /cvsroot/gnulib/gnulib/lib/xreadlink.c,v retrieving revision 1.26 diff -u -p -r1.26 xreadlink.c --- lib/xreadlink.c 3 Mar 2007 19:20:41 -0000 1.26 +++ lib/xreadlink.c 23 Aug 2007 11:35:05 -0000 @@ -25,7 +25,6 @@ /* Specification. */ #include "xreadlink.h" -#include <stdio.h> #include <string.h> #include <errno.h> #include <limits.h> @@ -40,92 +39,18 @@ # define SSIZE_MAX ((ssize_t) (SIZE_MAX / 2)) #endif -#ifdef NO_XMALLOC -# define xmalloc malloc -#else -# include "xalloc.h" -#endif +#include "mreadlink.h" +#include "xalloc.h" -/* Call readlink to get the symbolic link value of FILENAME. - Return a pointer to that NUL-terminated string in malloc'd storage. - If readlink fails, return NULL (caller may use errno to diagnose). - If realloc fails, or if the link value is longer than SIZE_MAX :-), - give a diagnostic and exit. */ +/* Call mreadlink to get the symbolic link value of FILENAME in malloc'd + storage. If mreadlink fails, call xalloc_die. Otherwise, return + the malloc'd string. */ char * xreadlink (char const *filename) { - /* The initial buffer size for the link value. A power of 2 - detects arithmetic overflow earlier, but is not required. */ -#define INITIAL_BUF_SIZE 1024 - - /* Allocate the initial buffer on the stack. This way, in the common - case of a symlink of small size, we get away with a single small malloc() - instead of a big malloc() followed by a shrinking realloc(). */ - char initial_buf[INITIAL_BUF_SIZE]; - - char *buffer = initial_buf; - size_t buf_size = sizeof (initial_buf); - - while (1) - { - /* Attempt to read the link into the current buffer. */ - ssize_t link_length = readlink (filename, buffer, buf_size); - - /* On AIX 5L v5.3 and HP-UX 11i v2 04/09, readlink returns -1 - with errno == ERANGE if the buffer is too small. */ - if (link_length < 0 && errno != ERANGE) - { - if (buffer != initial_buf) - { - int saved_errno = errno; - free (buffer); - errno = saved_errno; - } - return NULL; - } - - if ((size_t) link_length < buf_size) - { - buffer[link_length++] = '\0'; - - /* Return it in a chunk of memory as small as possible. */ - if (buffer == initial_buf) - { - buffer = (char *) xmalloc (link_length); -#ifdef NO_XMALLOC - if (buffer == NULL) - return NULL; -#endif - memcpy (buffer, initial_buf, link_length); - } - else - { - /* Shrink buffer before returning it. */ - if ((size_t) link_length < buf_size) - { - char *smaller_buffer = (char *) realloc (buffer, link_length); - - if (smaller_buffer != NULL) - buffer = smaller_buffer; - } - } - return buffer; - } - - if (buffer != initial_buf) - free (buffer); - buf_size *= 2; - if (SSIZE_MAX < buf_size || (SIZE_MAX / 2 < SSIZE_MAX && buf_size == 0)) -#ifdef NO_XMALLOC - return NULL; -#else - xalloc_die (); -#endif - buffer = (char *) xmalloc (buf_size); -#ifdef NO_XMALLOC - if (buffer == NULL) - return NULL; -#endif - } + char *p = mreadlink (filename); + if (p == NULL) + xalloc_die (); + return p; } Index: modules/xreadlink =================================================================== RCS file: /cvsroot/gnulib/gnulib/modules/xreadlink,v retrieving revision 1.15 diff -u -p -r1.15 xreadlink --- modules/xreadlink 3 Mar 2007 19:20:41 -0000 1.15 +++ modules/xreadlink 23 Aug 2007 11:35:05 -0000 @@ -1,15 +1,13 @@ Description: -Reading symbolic links without size limitation. +Read symbolic links without size limitation. Files: lib/xreadlink.h lib/xreadlink.c Depends-on: -readlink -ssize_t -unistd -xalloc +mreadlink +xalloc-die configure.ac: