diff options
author | Peter Korsgaard <jacmet@sunsite.dk> | 2009-09-30 07:27:01 +0200 |
---|---|---|
committer | Peter Korsgaard <jacmet@sunsite.dk> | 2009-09-30 07:27:01 +0200 |
commit | 78145a624ceddf05d11a15d14c84a71785861293 (patch) | |
tree | a0bc018c3105834b2a93c9482ecf46173b23f0ab /package/busybox | |
parent | abd76618a48d0db187818c24a3ae1ed58111c97d (diff) |
busybox: 1.15.1 find fix
Signed-off-by: Peter Korsgaard <jacmet@sunsite.dk>
Diffstat (limited to 'package/busybox')
-rw-r--r-- | package/busybox/busybox-1.15.1-find.patch | 230 |
1 files changed, 230 insertions, 0 deletions
diff --git a/package/busybox/busybox-1.15.1-find.patch b/package/busybox/busybox-1.15.1-find.patch new file mode 100644 index 000000000..da2700a6b --- /dev/null +++ b/package/busybox/busybox-1.15.1-find.patch @@ -0,0 +1,230 @@ +diff -urpN busybox-1.15.1/findutils/find.c busybox-1.15.1-find/findutils/find.c +--- busybox-1.15.1/findutils/find.c 2009-09-12 17:55:58.000000000 +0200 ++++ busybox-1.15.1-find/findutils/find.c 2009-09-30 02:23:54.000000000 +0200 +@@ -62,9 +62,6 @@ + /* This is a NOEXEC applet. Be very careful! */ + + +-IF_FEATURE_FIND_XDEV(static dev_t *xdev_dev;) +-IF_FEATURE_FIND_XDEV(static int xdev_count;) +- + typedef int (*action_fp)(const char *fileName, struct stat *statbuf, void *) FAST_FUNC; + + typedef struct { +@@ -100,9 +97,24 @@ IF_FEATURE_FIND_DELETE( ACTS(delete)) + IF_FEATURE_FIND_EXEC( ACTS(exec, char **exec_argv; unsigned *subst_count; int exec_argc;)) + IF_FEATURE_FIND_GROUP( ACTS(group, gid_t gid;)) + +-static action ***actions; +-static bool need_print = 1; +-static int recurse_flags = ACTION_RECURSE; ++struct globals { ++ IF_FEATURE_FIND_XDEV(dev_t *xdev_dev;) ++ IF_FEATURE_FIND_XDEV(int xdev_count;) ++ action ***actions; ++ bool need_print; ++ recurse_flags_t recurse_flags; ++}; ++#define G (*(struct globals*)&bb_common_bufsiz1) ++#define INIT_G() do { \ ++ struct G_sizecheck { \ ++ char G_sizecheck[sizeof(G) > COMMON_BUFSIZE ? -1 : 1]; \ ++ }; \ ++ G.xdev_dev = NULL; \ ++ G.xdev_count = 0; \ ++ G.actions = NULL; \ ++ G.need_print = 1; \ ++ G.recurse_flags = ACTION_RECURSE; \ ++} while (0) + + #if ENABLE_FEATURE_FIND_EXEC + static unsigned count_subst(const char *str) +@@ -363,7 +375,7 @@ ACTF(context) + security_context_t con; + int rc; + +- if (recurse_flags & ACTION_FOLLOWLINKS) { ++ if (G.recurse_flags & ACTION_FOLLOWLINKS) { + rc = getfilecon(fileName, &con); + } else { + rc = lgetfilecon(fileName, &con); +@@ -392,18 +404,18 @@ static int FAST_FUNC fileAction(const ch + #endif + + #if ENABLE_FEATURE_FIND_XDEV +- if (S_ISDIR(statbuf->st_mode) && xdev_count) { +- for (i = 0; i < xdev_count; i++) { +- if (xdev_dev[i] == statbuf->st_dev) ++ if (S_ISDIR(statbuf->st_mode) && G.xdev_count) { ++ for (i = 0; i < G.xdev_count; i++) { ++ if (G.xdev_dev[i] == statbuf->st_dev) + break; + } +- if (i == xdev_count) ++ if (i == G.xdev_count) + return SKIP; + } + #endif +- i = exec_actions(actions, fileName, statbuf); ++ i = exec_actions(G.actions, fileName, statbuf); + /* Had no explicit -print[0] or -exec? then print */ +- if ((i & TRUE) && need_print) ++ if ((i & TRUE) && G.need_print) + puts(fileName); + /* Cannot return 0: our caller, recursive_action(), + * will perror() and skip dirs (if called on dir) */ +@@ -431,7 +443,7 @@ static int find_type(const char *type) + else if (*type == 's') + mask = S_IFSOCK; + +- if (mask == 0 || *(type + 1) != '\0') ++ if (mask == 0 || type[1] != '\0') + bb_error_msg_and_die(bb_msg_invalid_arg, type, "-type"); + + return mask; +@@ -592,21 +604,21 @@ static action*** parse_params(char **arg + + /* --- Tests and actions --- */ + else if (parm == PARM_print) { +- need_print = 0; ++ G.need_print = 0; + /* GNU find ignores '!' here: "find ! -print" */ + IF_FEATURE_FIND_NOT( invert_flag = 0; ) + (void) ALLOC_ACTION(print); + } + #if ENABLE_FEATURE_FIND_PRINT0 + else if (parm == PARM_print0) { +- need_print = 0; ++ G.need_print = 0; + IF_FEATURE_FIND_NOT( invert_flag = 0; ) + (void) ALLOC_ACTION(print0); + } + #endif + #if ENABLE_FEATURE_FIND_DEPTH + else if (parm == PARM_depth) { +- recurse_flags |= ACTION_DEPTHFIRST; ++ G.recurse_flags |= ACTION_DEPTHFIRST; + } + #endif + #if ENABLE_FEATURE_FIND_PRUNE +@@ -617,8 +629,8 @@ static action*** parse_params(char **arg + #endif + #if ENABLE_FEATURE_FIND_DELETE + else if (parm == PARM_delete) { +- need_print = 0; +- recurse_flags |= ACTION_DEPTHFIRST; ++ G.need_print = 0; ++ G.recurse_flags |= ACTION_DEPTHFIRST; + (void) ALLOC_ACTION(delete); + } + #endif +@@ -626,7 +638,7 @@ static action*** parse_params(char **arg + else if (parm == PARM_exec) { + int i; + action_exec *ap; +- need_print = 0; ++ G.need_print = 0; + IF_FEATURE_FIND_NOT( invert_flag = 0; ) + ap = ALLOC_ACTION(exec); + ap->exec_argv = ++argv; /* first arg after -exec */ +@@ -834,6 +846,8 @@ IF_FEATURE_FIND_MAXDEPTH(OPT_MINDEPTH,) + #define minmaxdepth NULL + #endif + ++ INIT_G(); ++ + for (firstopt = 1; firstopt < argc; firstopt++) { + if (argv[firstopt][0] == '-') + break; +@@ -861,21 +875,21 @@ IF_FEATURE_FIND_MAXDEPTH(OPT_MINDEPTH,) + while ((arg = argp[0])) { + int opt = index_in_strings(options, arg); + if (opt == OPT_FOLLOW) { +- recurse_flags |= ACTION_FOLLOWLINKS; ++ G.recurse_flags |= ACTION_FOLLOWLINKS | ACTION_DANGLING_OK; + argp[0] = (char*)"-a"; + } + #if ENABLE_FEATURE_FIND_XDEV + if (opt == OPT_XDEV) { + struct stat stbuf; +- if (!xdev_count) { +- xdev_count = firstopt - 1; +- xdev_dev = xmalloc(xdev_count * sizeof(dev_t)); ++ if (!G.xdev_count) { ++ G.xdev_count = firstopt - 1; ++ G.xdev_dev = xmalloc(G.xdev_count * sizeof(dev_t)); + for (i = 1; i < firstopt; i++) { + /* not xstat(): shouldn't bomb out on + * "find not_exist exist -xdev" */ + if (stat(argv[i], &stbuf)) + stbuf.st_dev = -1L; +- xdev_dev[i-1] = stbuf.st_dev; ++ G.xdev_dev[i-1] = stbuf.st_dev; + } + } + argp[0] = (char*)"-a"; +@@ -894,11 +908,11 @@ IF_FEATURE_FIND_MAXDEPTH(OPT_MINDEPTH,) + argp++; + } + +- actions = parse_params(&argv[firstopt]); ++ G.actions = parse_params(&argv[firstopt]); + + for (i = 1; i < firstopt; i++) { + if (!recursive_action(argv[i], +- recurse_flags, /* flags */ ++ G.recurse_flags,/* flags */ + fileAction, /* file action */ + fileAction, /* dir action */ + #if ENABLE_FEATURE_FIND_MAXDEPTH +diff -urpN busybox-1.15.1/include/libbb.h busybox-1.15.1-find/include/libbb.h +--- busybox-1.15.1/include/libbb.h 2009-09-12 17:55:58.000000000 +0200 ++++ busybox-1.15.1-find/include/libbb.h 2009-09-30 02:20:21.000000000 +0200 +@@ -286,7 +286,9 @@ enum { + ACTION_DEPTHFIRST = (1 << 3), + /*ACTION_REVERSE = (1 << 4), - unused */ + ACTION_QUIET = (1 << 5), ++ ACTION_DANGLING_OK = (1 << 6), + }; ++typedef uint8_t recurse_flags_t; + extern int recursive_action(const char *fileName, unsigned flags, + int FAST_FUNC (*fileAction)(const char *fileName, struct stat* statbuf, void* userData, int depth), + int FAST_FUNC (*dirAction)(const char *fileName, struct stat* statbuf, void* userData, int depth), +diff -urpN busybox-1.15.1/libbb/recursive_action.c busybox-1.15.1-find/libbb/recursive_action.c +--- busybox-1.15.1/libbb/recursive_action.c 2009-09-12 17:55:36.000000000 +0200 ++++ busybox-1.15.1-find/libbb/recursive_action.c 2009-09-30 02:20:21.000000000 +0200 +@@ -61,6 +61,7 @@ int FAST_FUNC recursive_action(const cha + unsigned depth) + { + struct stat statbuf; ++ unsigned follow; + int status; + DIR *dir; + struct dirent *next; +@@ -68,14 +69,22 @@ int FAST_FUNC recursive_action(const cha + 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; + } + |