diff options
author | Denys Vlasenko <vda.linux@googlemail.com> | 2009-09-29 11:07:04 +0200 |
---|---|---|
committer | Denys Vlasenko <vda.linux@googlemail.com> | 2009-09-29 11:07:04 +0200 |
commit | 8f7a6d294fd0940e531bb8fef197b1b74fe2a842 (patch) | |
tree | 50e60d97d4d5922db6924fa8b423807a9559a06b /libbb/recursive_action.c | |
parent | 2f3f09c287f43dcad50b740793c2b467f166c058 (diff) | |
download | busybox-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.c | 19 |
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 | ||