X-Git-Url: http://erislabs.net/gitweb/?a=blobdiff_plain;f=lib%2Fcareadlinkat.c;h=b36fea28302078d8935dfa78d22effdedf74100a;hb=1276a2c5f24c0c932426aca9c899fa524d2443f2;hp=5f0d43c2e719d34e3d3ee606c00b2c3f304f4a7f;hpb=0f6ac7dc9db3359b624ff31ad563426b437b965e;p=gnulib.git diff --git a/lib/careadlinkat.c b/lib/careadlinkat.c index 5f0d43c2e..b36fea283 100644 --- a/lib/careadlinkat.c +++ b/lib/careadlinkat.c @@ -1,6 +1,6 @@ /* Read symbolic links into a buffer without size limitation, relative to fd. - Copyright (C) 2001, 2003-2004, 2007, 2009-2011 Free Software Foundation, + Copyright (C) 2001, 2003-2004, 2007, 2009-2014 Free Software Foundation, Inc. This program is free software: you can redistribute it and/or modify @@ -18,16 +18,12 @@ /* Written by Paul Eggert, Bruno Haible, and Jim Meyering. */ -#define _GL_USE_STDLIB_ALLOC 1 #include #include "careadlinkat.h" -#include "allocator.h" - #include #include -#include #include #include @@ -40,23 +36,7 @@ # define SSIZE_MAX ((ssize_t) (SIZE_MAX / 2)) #endif -#if ! HAVE_READLINKAT -/* Ignore FD. Get the symbolic link value of FILENAME and put it into - BUFFER, with size BUFFER_SIZE. This function acts like readlink - but has readlinkat's signature. */ -ssize_t -careadlinkatcwd (int fd, char const *filename, char *buffer, - size_t buffer_size) -{ - (void) fd; - return readlink (filename, buffer, buffer_size); -} -#endif - -/* A standard allocator. For now, only careadlinkat needs this, but - perhaps it should be moved to the allocator module. */ -static struct allocator const standard_allocator = - { malloc, realloc, free, NULL }; +#include "allocator.h" /* Assuming the current directory is FD, get the symbolic link value of FILENAME as a null-terminated string and put it into a buffer. @@ -72,7 +52,10 @@ static struct allocator const standard_allocator = the returned value if it is nonnull and is not BUFFER. A null ALLOC stands for the standard allocator. - The PREADLINKAT function specifies how to read links. + The PREADLINKAT function specifies how to read links. It operates + like POSIX readlinkat() + + but can assume that its first argument is the same as FD. If successful, return the buffer address; otherwise return NULL and set errno. */ @@ -90,7 +73,7 @@ careadlinkat (int fd, char const *filename, char stack_buf[1024]; if (! alloc) - alloc = &standard_allocator; + alloc = &stdlib_allocator; if (! buffer_size) { @@ -135,6 +118,7 @@ careadlinkat (int fd, char const *filename, if (buf == stack_buf) { char *b = (char *) alloc->allocate (link_size); + buf_size = link_size; if (! b) break; memcpy (b, buf, link_size); @@ -158,6 +142,11 @@ careadlinkat (int fd, char const *filename, buf_size *= 2; else if (buf_size < buf_size_max) buf_size = buf_size_max; + else if (buf_size_max < SIZE_MAX) + { + errno = ENAMETOOLONG; + return NULL; + } else break; buf = (char *) alloc->allocate (buf_size); @@ -165,7 +154,7 @@ careadlinkat (int fd, char const *filename, while (buf); if (alloc->die) - alloc->die (); + alloc->die (buf_size); errno = ENOMEM; return NULL; }