diff -urpN busybox-1.17.0/editors/diff.c busybox-1.17.0-diff/editors/diff.c --- busybox-1.17.0/editors/diff.c 2010-06-24 04:40:43.000000000 +0200 +++ busybox-1.17.0-diff/editors/diff.c 2010-07-19 00:27:45.000000000 +0200 @@ -121,6 +121,7 @@ typedef struct FILE_and_pos_t { struct globals { smallint exit_status; int opt_U_context; + const char *other_dir; char *label[2]; struct stat stb[2]; }; @@ -760,9 +761,11 @@ static int FAST_FUNC add_to_dirlist(cons void *userdata, int depth UNUSED_PARAM) { struct dlist *const l = userdata; + const char *file = filename + l->len; + while (*file == '/') + file++; l->dl = xrealloc_vector(l->dl, 6, l->e); - /* + 1 skips "/" after dirname */ - l->dl[l->e] = xstrdup(filename + l->len + 1); + l->dl[l->e] = xstrdup(file); l->e++; return TRUE; } @@ -778,6 +781,25 @@ static int FAST_FUNC skip_dir(const char add_to_dirlist(filename, sb, userdata, depth); return SKIP; } + if (!(option_mask32 & FLAG(N))) { + /* -r without -N: no need to recurse into dirs + * which do not exist on the "other side". + * Testcase: diff -r /tmp / + * (it would recurse deep into /proc without this code) */ + struct dlist *const l = userdata; + filename += l->len; + if (filename[0]) { + struct stat osb; + char *othername = concat_path_file(G.other_dir, filename); + int r = stat(othername, &osb); + free(othername); + if (r != 0 || !S_ISDIR(osb.st_mode)) { + /* other dir doesn't have similarly named + * directory, don't recurse */ + return SKIP; + } + } + } return TRUE; } @@ -791,6 +813,7 @@ static void diffdir(char *p[2], const ch /*list[i].s = list[i].e = 0; - memset did it */ /*list[i].dl = NULL; */ + G.other_dir = p[1 - i]; /* We need to trim root directory prefix. * Using list.len to specify its length, * add_to_dirlist will remove it. */ diff -urpN busybox-1.17.0/testsuite/diff.tests busybox-1.17.0-diff/testsuite/diff.tests --- busybox-1.17.0/testsuite/diff.tests 2010-06-24 04:40:43.000000000 +0200 +++ busybox-1.17.0-diff/testsuite/diff.tests 2010-07-10 01:31:51.000000000 +0200 @@ -4,7 +4,7 @@ . ./testing.sh -# testing "test name" "options" "expected result" "file input" "stdin" +# testing "test name" "commands" "expected result" "file input" "stdin" # diff outputs date/time in the header, which should not be analysed # NB: sed has tab character in s command! @@ -100,9 +100,11 @@ testing "diff always takes context from "abc\na c\ndef\n" \ "a c\n" -# testing "test name" "options" "expected result" "file input" "stdin" +# testing "test name" "commands" "expected result" "file input" "stdin" +# clean up rm -rf diff1 diff2 + mkdir diff1 diff2 diff2/subdir echo qwe >diff1/- echo asd >diff2/subdir/- @@ -187,4 +189,29 @@ SKIP= # clean up rm -rf diff1 diff2 +# NOT using directory structure from prev test... +mkdir diff1 diff2 +echo qwe >diff1/- +echo rty >diff2/- +optional FEATURE_DIFF_DIR +testing "diff diff1 diff2/" \ + "diff -ur diff1 diff2/ | $TRIM_TAB; diff -ur .///diff1 diff2//// | $TRIM_TAB" \ +"\ +--- diff1/- ++++ diff2/- +@@ -1 +1 @@ +-qwe ++rty +--- .///diff1/- ++++ diff2////- +@@ -1 +1 @@ +-qwe ++rty +" \ + "" "" +SKIP= + +# clean up +rm -rf diff1 diff2 + exit $FAILCOUNT