From 8f7a6d294fd0940e531bb8fef197b1b74fe2a842 Mon Sep 17 00:00:00 2001 From: Denys Vlasenko Date: Tue, 29 Sep 2009 11:07:04 +0200 Subject: find: -follow should not error out on dandling links function old new delta recursive_action 425 465 +40 find_main 436 465 +29 test_main 247 253 +6 need_print 1 - -1 doCommands 2523 2521 -2 compare_keys 737 735 -2 xdev_dev 4 - -4 xdev_count 4 - -4 recurse_flags 4 - -4 mkfs_vfat_main 1609 1605 -4 actions 4 - -4 fileAction 588 583 -5 ------------------------------------------------------------------------------ (add/remove: 0/5 grow/shrink: 3/4 up/down: 75/-30) Total: 45 bytes text data bss dec hex filename 822711 450 7684 830845 cad7d busybox_old 822773 445 7668 830886 cada6 busybox_unstripped Signed-off-by: Denys Vlasenko --- libbb/recursive_action.c | 19 ++++++++++++++----- 1 file changed, 14 insertions(+), 5 deletions(-) (limited to 'libbb/recursive_action.c') diff --git a/libbb/recursive_action.c b/libbb/recursive_action.c index 3ec596a35..57262cd43 100644 --- a/libbb/recursive_action.c +++ b/libbb/recursive_action.c @@ -48,7 +48,7 @@ static int FAST_FUNC true_action(const char *fileName UNUSED_PARAM, * into that directory, instead recursive_action() returns 0 (if FALSE) * or 1 (if SKIP) * - * followLinks=0/1 differs mainly in handling of links to dirs. + * ACTION_FOLLOWLINKS mainly controls handling of links to dirs. * 0: lstat(statbuf). Calls fileAction on link name even if points to dir. * 1: stat(statbuf). Calls dirAction and optionally recurse on link to dir. */ @@ -61,6 +61,7 @@ int FAST_FUNC recursive_action(const char *fileName, unsigned depth) { struct stat statbuf; + unsigned follow; int status; DIR *dir; struct dirent *next; @@ -68,14 +69,22 @@ int FAST_FUNC recursive_action(const char *fileName, if (!fileAction) fileAction = true_action; if (!dirAction) dirAction = true_action; - status = ACTION_FOLLOWLINKS; /* hijack a variable for bitmask... */ - if (!depth) - status = ACTION_FOLLOWLINKS | ACTION_FOLLOWLINKS_L0; - status = ((flags & status) ? stat : lstat)(fileName, &statbuf); + follow = ACTION_FOLLOWLINKS; + if (depth == 0) + follow = ACTION_FOLLOWLINKS | ACTION_FOLLOWLINKS_L0; + follow &= flags; + status = (follow ? stat : lstat)(fileName, &statbuf); if (status < 0) { #ifdef DEBUG_RECURS_ACTION bb_error_msg("status=%d flags=%x", status, flags); #endif + if ((flags & ACTION_DANGLING_OK) + && errno == ENOENT + && lstat(fileName, &statbuf) == 0 + ) { + /* Dangling link */ + return fileAction(fileName, &statbuf, userData, depth); + } goto done_nak_warn; } -- cgit v1.2.3