X-Git-Url: http://erislabs.net/gitweb/?a=blobdiff_plain;ds=sidebyside;f=lib%2Flinkat.c;h=524ddde6a0e900b0c8d2fe9acee4b09b99cf53cf;hb=78d218ff8a7c36feaa55c58abdcec8270654e6f1;hp=f785d091f869d3936e660c817148e069043c5048;hpb=cdba659e0746e0d7c6ecbcabfbb25132f5418a38;p=gnulib.git diff --git a/lib/linkat.c b/lib/linkat.c index f785d091f..524ddde6a 100644 --- a/lib/linkat.c +++ b/lib/linkat.c @@ -23,6 +23,7 @@ #include #include #include +#include #include #include #include @@ -188,83 +189,6 @@ linkat (int fd1, char const *file1, int fd2, char const *file2, int flag) # undef linkat -/* Read a symlink, like areadlink, but relative to FD. */ - -static char * -areadlinkat (int fd, 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 = readlinkat (fd, 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 *) malloc (link_length); - if (buffer == NULL) - /* errno is ENOMEM. */ - return NULL; - 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)) - { - errno = ENOMEM; - return NULL; - } - buffer = (char *) malloc (buf_size); - if (buffer == NULL) - /* errno is ENOMEM. */ - return NULL; - } -} - /* Create a link. If FILE1 is a symlink, create a hardlink to the canonicalized file. */