- /* 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 < MAXSIZE ? size + 1 : MAXSIZE;
-
- while (1)
- {
- char *buffer = xmalloc (buf_size);
- ssize_t r = readlink (filename, buffer, buf_size);
- size_t link_length = r;
-
- /* 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 (r < 0 && errno != ERANGE)
- {
- int saved_errno = errno;
- free (buffer);
- errno = saved_errno;
- return NULL;
- }
-
- if (link_length < buf_size)
- {
- buffer[link_length] = 0;
- return buffer;
- }
-
- free (buffer);
- if (buf_size <= MAXSIZE / 2)
- buf_size *= 2;
- else if (buf_size < MAXSIZE)
- buf_size = MAXSIZE;
- else
- xalloc_die ();
- }