aboutsummaryrefslogtreecommitdiff
path: root/libbb/recursive_action.c
diff options
context:
space:
mode:
authorDenys Vlasenko <vda.linux@googlemail.com>2009-09-29 11:07:04 +0200
committerDenys Vlasenko <vda.linux@googlemail.com>2009-09-29 11:07:04 +0200
commit8f7a6d294fd0940e531bb8fef197b1b74fe2a842 (patch)
tree50e60d97d4d5922db6924fa8b423807a9559a06b /libbb/recursive_action.c
parent2f3f09c287f43dcad50b740793c2b467f166c058 (diff)
downloadbusybox-w32-8f7a6d294fd0940e531bb8fef197b1b74fe2a842.tar.gz
busybox-w32-8f7a6d294fd0940e531bb8fef197b1b74fe2a842.tar.bz2
busybox-w32-8f7a6d294fd0940e531bb8fef197b1b74fe2a842.zip
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 <vda.linux@googlemail.com>
Diffstat (limited to 'libbb/recursive_action.c')
-rw-r--r--libbb/recursive_action.c19
1 files changed, 14 insertions, 5 deletions
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,
48 * into that directory, instead recursive_action() returns 0 (if FALSE) 48 * into that directory, instead recursive_action() returns 0 (if FALSE)
49 * or 1 (if SKIP) 49 * or 1 (if SKIP)
50 * 50 *
51 * followLinks=0/1 differs mainly in handling of links to dirs. 51 * ACTION_FOLLOWLINKS mainly controls handling of links to dirs.
52 * 0: lstat(statbuf). Calls fileAction on link name even if points to dir. 52 * 0: lstat(statbuf). Calls fileAction on link name even if points to dir.
53 * 1: stat(statbuf). Calls dirAction and optionally recurse on link to dir. 53 * 1: stat(statbuf). Calls dirAction and optionally recurse on link to dir.
54 */ 54 */
@@ -61,6 +61,7 @@ int FAST_FUNC recursive_action(const char *fileName,
61 unsigned depth) 61 unsigned depth)
62{ 62{
63 struct stat statbuf; 63 struct stat statbuf;
64 unsigned follow;
64 int status; 65 int status;
65 DIR *dir; 66 DIR *dir;
66 struct dirent *next; 67 struct dirent *next;
@@ -68,14 +69,22 @@ int FAST_FUNC recursive_action(const char *fileName,
68 if (!fileAction) fileAction = true_action; 69 if (!fileAction) fileAction = true_action;
69 if (!dirAction) dirAction = true_action; 70 if (!dirAction) dirAction = true_action;
70 71
71 status = ACTION_FOLLOWLINKS; /* hijack a variable for bitmask... */ 72 follow = ACTION_FOLLOWLINKS;
72 if (!depth) 73 if (depth == 0)
73 status = ACTION_FOLLOWLINKS | ACTION_FOLLOWLINKS_L0; 74 follow = ACTION_FOLLOWLINKS | ACTION_FOLLOWLINKS_L0;
74 status = ((flags & status) ? stat : lstat)(fileName, &statbuf); 75 follow &= flags;
76 status = (follow ? stat : lstat)(fileName, &statbuf);
75 if (status < 0) { 77 if (status < 0) {
76#ifdef DEBUG_RECURS_ACTION 78#ifdef DEBUG_RECURS_ACTION
77 bb_error_msg("status=%d flags=%x", status, flags); 79 bb_error_msg("status=%d flags=%x", status, flags);
78#endif 80#endif
81 if ((flags & ACTION_DANGLING_OK)
82 && errno == ENOENT
83 && lstat(fileName, &statbuf) == 0
84 ) {
85 /* Dangling link */
86 return fileAction(fileName, &statbuf, userData, depth);
87 }
79 goto done_nak_warn; 88 goto done_nak_warn;
80 } 89 }
81 90