changeset 5385:3c3f7d39051d

(MAXSIZE): New macro. (xreadlink): Use it instead of SSIZE_MAX. Ensure initial buffer size does not exceed MAXSIZE. Avoid cast. As suggested by Mark D. Baushke in <http://lists.gnu.org/archive/html/bug-gnulib/2004-11/msg00009.html>, if readlink fails with buffer size just under MAXSIZE, try again with MAXSIZE.
author Paul Eggert <eggert@cs.ucla.edu>
date Tue, 02 Nov 2004 20:17:37 +0000
parents 16ed8f3aadca
children c008e99bcbab
files lib/xreadlink.c
diffstat 1 files changed, 12 insertions(+), 6 deletions(-) [+]
line wrap: on
line diff
--- a/lib/xreadlink.c
+++ b/lib/xreadlink.c
@@ -41,6 +41,8 @@
 # define SSIZE_MAX ((ssize_t) (SIZE_MAX / 2))
 #endif
 
+#define MAXSIZE (SIZE_MAX < SSIZE_MAX ? SIZE_MAX : SSIZE_MAX)
+
 #include "xalloc.h"
 
 /* Call readlink to get the symbolic link value of FILENAME.
@@ -56,14 +58,15 @@
 {
   /* The initial buffer size for the link value.  A power of 2
      detects arithmetic overflow earlier, but is not required.  */
-  size_t buf_size = size + 1;
+  size_t buf_size = size < MAXSIZE ? size + 1 : MAXSIZE;
 
   while (1)
     {
       char *buffer = xmalloc (buf_size);
-      ssize_t link_length = readlink (filename, buffer, buf_size);
+      ssize_t r = readlink (filename, buffer, buf_size);
+      size_t link_length = r;
 
-      if (link_length < 0)
+      if (r < 0)
 	{
 	  int saved_errno = errno;
 	  free (buffer);
@@ -71,15 +74,18 @@
 	  return NULL;
 	}
 
-      if ((size_t) link_length < buf_size)
+      if (link_length < buf_size)
 	{
 	  buffer[link_length] = 0;
 	  return buffer;
 	}
 
       free (buffer);
-      buf_size *= 2;
-      if (! (0 < buf_size && buf_size <= SSIZE_MAX))
+      if (buf_size <= MAXSIZE / 2)
+	buf_size *= 2;
+      else if (buf_size < MAXSIZE)
+	buf_size = MAXSIZE;
+      else
 	xalloc_die ();
     }
 }