[Top][All Lists]
[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]
Re: [Bug-gnulib] xreadlink.c patch
From: |
Paul Eggert |
Subject: |
Re: [Bug-gnulib] xreadlink.c patch |
Date: |
Tue, 02 Nov 2004 12:23:15 -0800 |
User-agent: |
Gnus/5.1006 (Gnus v5.10.6) Emacs/21.3 (gnu/linux) |
"Mark D. Baushke" <address@hidden> writes:
> 1) bugfix. readlink() on AIX 4.3 returns a
> negative link_length and sets errno == ERANGE
> when the length of the link is greater than
> buf_size.
Shouldn't this incompatibility be fixed in readlink.c rather than
xreadlink? I would expect other users of the readlink module to be
affected by it. Perhaps Bruno can comment, since he did readlink.c.
> 2) enhancement. The size passed to xreadlink
> could be the maximum value and adding one
> could wrap it to zero which would be a bad
> idea.
>
> 3) enhancement. Allow for at least one attempt
> at the maximum allowed buffer size if
> doubling the current buf_size pushes over the
> limit.
These are both good suggestions, but there's a problem with that
patch: it assumes SSIZE_MAX < SIZE_MAX, but POSIX does not require
this. I installed the following patch instead.
2004-11-02 Paul Eggert <address@hidden>
* xreadlink.c (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.
Index: xreadlink.c
===================================================================
RCS file: /cvsroot/gnulib/gnulib/lib/xreadlink.c,v
retrieving revision 1.15
retrieving revision 1.16
diff -p -u -r1.15 -r1.16
--- xreadlink.c 7 Aug 2004 00:09:39 -0000 1.15
+++ xreadlink.c 2 Nov 2004 20:17:37 -0000 1.16
@@ -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 @@ xreadlink (char const *filename, size_t
{
/* 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 @@ xreadlink (char const *filename, size_t
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 ();
}
}
Re: [Bug-gnulib] xreadlink.c patch, Bruno Haible, 2004/11/05