aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorDenys Vlasenko <vda.linux@googlemail.com>2010-07-10 16:25:47 +0200
committerDenys Vlasenko <vda.linux@googlemail.com>2010-07-10 16:25:47 +0200
commit75703eb8d5bd0d8d9ef0a8abaf25b421ca668ab5 (patch)
tree75c79372e5def8a0feb93e48e0da72b1c2e112ba
parenta48a29f921d9d50598784047b40c97c6850bb8ec (diff)
downloadbusybox-w32-75703eb8d5bd0d8d9ef0a8abaf25b421ca668ab5.tar.gz
busybox-w32-75703eb8d5bd0d8d9ef0a8abaf25b421ca668ab5.tar.bz2
busybox-w32-75703eb8d5bd0d8d9ef0a8abaf25b421ca668ab5.zip
diff: make diff -r much less eager to recurse into directories
function old new delta skip_dir 44 120 +76 diff_main 1175 1185 +10 Signed-off-by: Denys Vlasenko <vda.linux@googlemail.com>
-rw-r--r--editors/diff.c23
1 files changed, 22 insertions, 1 deletions
diff --git a/editors/diff.c b/editors/diff.c
index 3e2048330..a3ca2b660 100644
--- a/editors/diff.c
+++ b/editors/diff.c
@@ -121,6 +121,7 @@ typedef struct FILE_and_pos_t {
121struct globals { 121struct globals {
122 smallint exit_status; 122 smallint exit_status;
123 int opt_U_context; 123 int opt_U_context;
124 const char *other_dir;
124 char *label[2]; 125 char *label[2];
125 struct stat stb[2]; 126 struct stat stb[2];
126}; 127};
@@ -761,7 +762,7 @@ static int FAST_FUNC add_to_dirlist(const char *filename,
761{ 762{
762 struct dlist *const l = userdata; 763 struct dlist *const l = userdata;
763 const char *file = filename + l->len; 764 const char *file = filename + l->len;
764 while(*file == '/') 765 while (*file == '/')
765 file++; 766 file++;
766 l->dl = xrealloc_vector(l->dl, 6, l->e); 767 l->dl = xrealloc_vector(l->dl, 6, l->e);
767 l->dl[l->e] = xstrdup(file); 768 l->dl[l->e] = xstrdup(file);
@@ -780,6 +781,25 @@ static int FAST_FUNC skip_dir(const char *filename,
780 add_to_dirlist(filename, sb, userdata, depth); 781 add_to_dirlist(filename, sb, userdata, depth);
781 return SKIP; 782 return SKIP;
782 } 783 }
784 if (!(option_mask32 & FLAG(N))) {
785 /* -r without -N: no need to recurse into dirs
786 * which do not exist on the "other side".
787 * Testcase: diff -r /tmp /
788 * (it would recurse deep into /proc without this code) */
789 struct dlist *const l = userdata;
790 filename += l->len;
791 if (filename[0]) {
792 struct stat osb;
793 char *othername = concat_path_file(G.other_dir, filename);
794 int r = stat(othername, &osb);
795 free(othername);
796 if (r != 0 || !S_ISDIR(osb.st_mode)) {
797 /* other dir doesn't have similarly named
798 * directory, don't recurse */
799 return SKIP;
800 }
801 }
802 }
783 return TRUE; 803 return TRUE;
784} 804}
785 805
@@ -793,6 +813,7 @@ static void diffdir(char *p[2], const char *s_start)
793 /*list[i].s = list[i].e = 0; - memset did it */ 813 /*list[i].s = list[i].e = 0; - memset did it */
794 /*list[i].dl = NULL; */ 814 /*list[i].dl = NULL; */
795 815
816 G.other_dir = p[1 - i];
796 /* We need to trim root directory prefix. 817 /* We need to trim root directory prefix.
797 * Using list.len to specify its length, 818 * Using list.len to specify its length,
798 * add_to_dirlist will remove it. */ 819 * add_to_dirlist will remove it. */