>From 6be031b4c9d6cb742a010dbe3fe38f77fe515fec Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?P=C3=A1draig=20Brady?= Date: Thu, 4 Jul 2019 11:50:16 +0100 Subject: [PATCH] areadlink-with-size: guess a lower bound with 0 size * lib/areadlink-with-size.c (areadlink_with_size): The size is usually taken from st_size, which can be zero, resulting in inefficient operation as seen with: $ strace -e readlink stat -c %N /proc/$$/cwd readlink("/proc/9036/cwd", "/", 1) = 1 readlink("/proc/9036/cwd", "/h", 2) = 2 readlink("/proc/9036/cwd", "/hom", 4) = 4 readlink("/proc/9036/cwd", "/home/pa", 8) = 8 readlink("/proc/9036/cwd", "/home/padraig", 16) = 13 Instead let zero select an appropriate lower bound, as was already done for sizes more than 8Ki. We also change SYMLINK_MAX to 1023 so that the initial allocation is a power of two. --- ChangeLog | 10 ++++++++++ lib/areadlink-with-size.c | 7 ++++--- 2 files changed, 14 insertions(+), 3 deletions(-) diff --git a/ChangeLog b/ChangeLog index ea2e86a..bbd91f0 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,13 @@ +2019-07-04 Pádraig Brady + + areadlink-with-size: guess a lower bound with 0 size + * lib/areadlink-with-size.c (areadlink_with_size): + SIZE is usually taken from st_size, which can be zero. + Instead let zero select an appropriate lower bound, + as was already done for sizes more than 8Ki. + We also change SYMLINK_MAX to 1023 so that the initial + allocation is a power of two. + 2019-07-03 Bruno Haible mbrtowc: Fix invalid use of mbtowc() on MSVC. diff --git a/lib/areadlink-with-size.c b/lib/areadlink-with-size.c index eacad3f..2fbe51c 100644 --- a/lib/areadlink-with-size.c +++ b/lib/areadlink-with-size.c @@ -36,14 +36,15 @@ check, so it's OK to guess too small on hosts where there is no arbitrary limit to symbolic link length. */ #ifndef SYMLINK_MAX -# define SYMLINK_MAX 1024 +# define SYMLINK_MAX 1023 #endif #define MAXSIZE (SIZE_MAX < SSIZE_MAX ? SIZE_MAX : SSIZE_MAX) /* Call readlink to get the symbolic link value of FILE. SIZE is a hint as to how long the link is expected to be; - typically it is taken from st_size. It need not be correct. + typically it is taken from st_size. It need not be correct, + and a value of 0 (or more than 8Ki) will select an appropriate lower bound. Return a pointer to that NUL-terminated string in malloc'd storage. If readlink fails, malloc fails, or if the link value is longer than SSIZE_MAX, return NULL (caller may use errno to diagnose). */ @@ -61,7 +62,7 @@ areadlink_with_size (char const *file, size_t size) : INITIAL_LIMIT_BOUND); /* The initial buffer size for the link value. */ - size_t buf_size = size < initial_limit ? size + 1 : initial_limit; + size_t buf_size = size && size < initial_limit ? size + 1 : initial_limit; while (1) { -- 2.9.3