From 882a32613d5addd01c669bb36b1cdab93317a1b8 Mon Sep 17 00:00:00 2001 From: Yorhel Date: Thu, 24 Jan 2019 08:56:19 +0100 Subject: [PATCH] symlinks: Only call stat_to_dir() once, impove manual stat_to_dir() assumes that buf_dir is clean; calling it twice breaks that asumption. --- doc/ncdu.pod | 8 +++++--- src/dir_scan.c | 16 +++++++--------- 2 files changed, 12 insertions(+), 12 deletions(-) diff --git a/doc/ncdu.pod b/doc/ncdu.pod index eaa0ddc..784500f 100644 --- a/doc/ncdu.pod +++ b/doc/ncdu.pod @@ -172,10 +172,12 @@ displayed, but not their content, and they are not counted towards the disk usage statistics. See http://www.brynosaurus.com/cachedir/ -=item -L,--follow-symlinks +=item -L, --follow-symlinks -Follow symlinks (except to directories) 00and count the size of the file -they point to. Symlink loops and directories will be ignored. +Follow symlinks and count the size of the file they point to. As of ncdu 1.14, +this option will not follow symlinks to directories and will count each +symlinked file as a unique file (i.e. unlike how hard links are handled). This +is subject to change in later versions. =back diff --git a/src/dir_scan.c b/src/dir_scan.c index 3ec508c..38068f1 100644 --- a/src/dir_scan.c +++ b/src/dir_scan.c @@ -185,7 +185,7 @@ static int dir_scan_recurse(const char *name) { * directory. Assumes we're chdir'ed in the directory in which this item * resides. */ static int dir_scan_item(const char *name) { - struct stat st; + static struct stat st, stl; int fail = 0; #ifdef __CYGWIN__ @@ -204,14 +204,12 @@ static int dir_scan_item(const char *name) { dir_setlasterr(dir_curpath); } - if(!(buf_dir->flags & (FF_ERR|FF_EXL))) - stat_to_dir(&st); - - if (!(buf_dir->flags & (FF_ERR|FF_EXL)) && follow_symlinks && S_ISLNK(st.st_mode)) - if (!stat(name, &st)) { - if (!S_ISDIR(st.st_mode)) - stat_to_dir(&st); - } + if(!(buf_dir->flags & (FF_ERR|FF_EXL))) { + if(follow_symlinks && S_ISLNK(st.st_mode) && !stat(name, &stl) && !S_ISDIR(stl.st_mode)) + stat_to_dir(&stl); + else + stat_to_dir(&st); + } if(cachedir_tags && (buf_dir->flags & FF_DIR) && !(buf_dir->flags & (FF_ERR|FF_EXL|FF_OTHFS))) if(has_cachedir_tag(buf_dir->name)) {