X-Git-Url: http://erislabs.net/gitweb/?a=blobdiff_plain;f=lib%2Fcareadlinkat.c;h=751578b9a58fc6f46894cbbef3237d716f1c347b;hb=64ee293cdac319d0f38cd0d31e758a823b7163ad;hp=95611f876c454fd4fb9dc81036394ecb0b826321;hpb=6dce4dba9e10423045b81def590df4e6d3c540c6;p=gnulib.git diff --git a/lib/careadlinkat.c b/lib/careadlinkat.c index 95611f876..751578b9a 100644 --- a/lib/careadlinkat.c +++ b/lib/careadlinkat.c @@ -24,6 +24,7 @@ #include #include +#include #include #include @@ -38,18 +39,19 @@ #include "allocator.h" -#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. */ +/* 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; + /* FD must be AT_FDCWD here, otherwise the caller is using this + function in contexts for which it was not meant for. */ + if (fd != AT_FDCWD) + abort (); return readlink (filename, buffer, buffer_size); } -#endif /* Assuming the current directory is FD, get the symbolic link value of FILENAME as a null-terminated string and put it into a buffer. @@ -131,6 +133,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); @@ -154,6 +157,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); @@ -161,7 +169,7 @@ careadlinkat (int fd, char const *filename, while (buf); if (alloc->die) - alloc->die (); + alloc->die (buf_size); errno = ENOMEM; return NULL; }