X-Git-Url: http://erislabs.net/gitweb/?a=blobdiff_plain;f=lib%2Fareadlink.c;h=6bf9a0c415c88511f3b49cd9832232b9b4ce196f;hb=eb9e60e319faa80e5d0b8a196970191aec1cdcd7;hp=b506eb8bcab31b7f453e5871ca30d9b954f88cfb;hpb=441aa3044f43e5572f58c354f01e6bc070acd5c7;p=gnulib.git diff --git a/lib/areadlink.c b/lib/areadlink.c index b506eb8bc..6bf9a0c41 100644 --- a/lib/areadlink.c +++ b/lib/areadlink.c @@ -1,7 +1,7 @@ /* areadlink.c -- readlink wrapper to return the link name in malloc'd storage Unlike xreadlink and xreadlink_with_size, don't ever call exit. - Copyright (C) 2001, 2003-2007, 2009 Free Software Foundation, Inc. + Copyright (C) 2001, 2003-2007, 2009-2011 Free Software Foundation, Inc. This program is free software: you can redistribute it and/or modify it under the terms of the GNU General Public License as published by @@ -24,96 +24,16 @@ /* Specification. */ #include "areadlink.h" -#include -#include -#include -#include -#include -#include - -#ifndef SSIZE_MAX -# define SSIZE_MAX ((ssize_t) (SIZE_MAX / 2)) -#endif - -/* The initial buffer size for the link value. A power of 2 - detects arithmetic overflow earlier, but is not required. */ -enum { - INITIAL_BUF_SIZE = 1024 -}; +#include "careadlinkat.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 and set errno. - If realloc fails, or if the link value is longer than SIZE_MAX :-), + If allocation fails, or if the link value is longer than SIZE_MAX :-), return NULL and set errno to ENOMEM. */ char * areadlink (char const *filename) { - /* 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 *) 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; - } + return careadlinkat (AT_FDCWD, filename, NULL, 0, NULL, careadlinkatcwd); }