[git commit master 1/1] diff: make diff -r much less eager to recurse into directories

Denys Vlasenko vda.linux at googlemail.com
Sat Jul 10 14:25:47 UTC 2010


commit: http://git.busybox.net/busybox/commit/?id=75703eb8d5bd0d8d9ef0a8abaf25b421ca668ab5
branch: http://git.busybox.net/busybox/commit/?id=refs/heads/master

function                                             old     new   delta
skip_dir                                              44     120     +76
diff_main                                           1175    1185     +10

Signed-off-by: Denys Vlasenko <vda.linux at googlemail.com>
---
 editors/diff.c |   23 ++++++++++++++++++++++-
 1 files changed, 22 insertions(+), 1 deletions(-)

diff --git a/editors/diff.c b/editors/diff.c
index 3e20483..a3ca2b6 100644
--- a/editors/diff.c
+++ b/editors/diff.c
@@ -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];
 };
@@ -761,7 +762,7 @@ static int FAST_FUNC add_to_dirlist(const char *filename,
 {
 	struct dlist *const l = userdata;
 	const char *file = filename + l->len;
-	while(*file == '/')
+	while (*file == '/')
 		file++;
 	l->dl = xrealloc_vector(l->dl, 6, l->e);
 	l->dl[l->e] = xstrdup(file);
@@ -780,6 +781,25 @@ static int FAST_FUNC skip_dir(const char *filename,
 		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;
 }
 
@@ -793,6 +813,7 @@ static void diffdir(char *p[2], const char *s_start)
 		/*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. */
-- 
1.7.1



More information about the busybox-cvs mailing list