@@ -557,8 +557,7 @@ int add_excludes_from_file_to_list(const char *fname,
557
557
buf = xrealloc (buf , size + 1 );
558
558
buf [size ++ ] = '\n' ;
559
559
}
560
- }
561
- else {
560
+ } else {
562
561
size = xsize_t (st .st_size );
563
562
if (size == 0 ) {
564
563
close (fd );
@@ -793,17 +792,19 @@ static void prep_exclude(struct dir_struct *dir, const char *base, int baselen)
793
792
794
793
group = & dir -> exclude_list_group [EXC_DIRS ];
795
794
796
- /* Pop the exclude lists from the EXCL_DIRS exclude_list_group
795
+ /*
796
+ * Pop the exclude lists from the EXCL_DIRS exclude_list_group
797
797
* which originate from directories not in the prefix of the
798
- * path being checked. */
798
+ * path being checked.
799
+ */
799
800
while ((stk = dir -> exclude_stack ) != NULL ) {
800
801
if (stk -> baselen <= baselen &&
801
- !strncmp (dir -> basebuf , base , stk -> baselen ))
802
+ !strncmp (dir -> basebuf . buf , base , stk -> baselen ))
802
803
break ;
803
804
el = & group -> el [dir -> exclude_stack -> exclude_ix ];
804
805
dir -> exclude_stack = stk -> prev ;
805
806
dir -> exclude = NULL ;
806
- free ((char * )el -> src ); /* see strdup () below */
807
+ free ((char * )el -> src ); /* see strbuf_detach () below */
807
808
clear_exclude_list (el );
808
809
free (stk );
809
810
group -> nr -- ;
@@ -813,17 +814,25 @@ static void prep_exclude(struct dir_struct *dir, const char *base, int baselen)
813
814
if (dir -> exclude )
814
815
return ;
815
816
817
+ /*
818
+ * Lazy initialization. All call sites currently just
819
+ * memset(dir, 0, sizeof(*dir)) before use. Changing all of
820
+ * them seems lots of work for little benefit.
821
+ */
822
+ if (!dir -> basebuf .buf )
823
+ strbuf_init (& dir -> basebuf , PATH_MAX );
824
+
816
825
/* Read from the parent directories and push them down. */
817
826
current = stk ? stk -> baselen : -1 ;
827
+ strbuf_setlen (& dir -> basebuf , current < 0 ? 0 : current );
818
828
while (current < baselen ) {
819
829
struct exclude_stack * stk = xcalloc (1 , sizeof (* stk ));
820
830
const char * cp ;
821
831
822
832
if (current < 0 ) {
823
833
cp = base ;
824
834
current = 0 ;
825
- }
826
- else {
835
+ } else {
827
836
cp = strchr (base + current + 1 , '/' );
828
837
if (!cp )
829
838
die ("oops in prep_exclude" );
@@ -833,48 +842,47 @@ static void prep_exclude(struct dir_struct *dir, const char *base, int baselen)
833
842
stk -> baselen = cp - base ;
834
843
stk -> exclude_ix = group -> nr ;
835
844
el = add_exclude_list (dir , EXC_DIRS , NULL );
836
- memcpy ( dir -> basebuf + current , base + current ,
837
- stk -> baselen - current );
845
+ strbuf_add ( & dir -> basebuf , base + current , stk -> baselen - current );
846
+ assert ( stk -> baselen == dir -> basebuf . len );
838
847
839
848
/* Abort if the directory is excluded */
840
849
if (stk -> baselen ) {
841
850
int dt = DT_DIR ;
842
- dir -> basebuf [stk -> baselen - 1 ] = 0 ;
851
+ dir -> basebuf . buf [stk -> baselen - 1 ] = 0 ;
843
852
dir -> exclude = last_exclude_matching_from_lists (dir ,
844
- dir -> basebuf , stk -> baselen - 1 ,
845
- dir -> basebuf + current , & dt );
846
- dir -> basebuf [stk -> baselen - 1 ] = '/' ;
853
+ dir -> basebuf . buf , stk -> baselen - 1 ,
854
+ dir -> basebuf . buf + current , & dt );
855
+ dir -> basebuf . buf [stk -> baselen - 1 ] = '/' ;
847
856
if (dir -> exclude &&
848
857
dir -> exclude -> flags & EXC_FLAG_NEGATIVE )
849
858
dir -> exclude = NULL ;
850
859
if (dir -> exclude ) {
851
- dir -> basebuf [stk -> baselen ] = 0 ;
852
860
dir -> exclude_stack = stk ;
853
861
return ;
854
862
}
855
863
}
856
864
857
- /* Try to read per-directory file unless path is too long */
858
- if (dir -> exclude_per_dir &&
859
- stk -> baselen + strlen (dir -> exclude_per_dir ) < PATH_MAX ) {
860
- strcpy (dir -> basebuf + stk -> baselen ,
861
- dir -> exclude_per_dir );
865
+ /* Try to read per-directory file */
866
+ if (dir -> exclude_per_dir ) {
862
867
/*
863
868
* dir->basebuf gets reused by the traversal, but we
864
869
* need fname to remain unchanged to ensure the src
865
870
* member of each struct exclude correctly
866
871
* back-references its source file. Other invocations
867
872
* of add_exclude_list provide stable strings, so we
868
- * strdup () and free() here in the caller.
873
+ * strbuf_detach () and free() here in the caller.
869
874
*/
870
- el -> src = strdup (dir -> basebuf );
871
- add_excludes_from_file_to_list (dir -> basebuf ,
872
- dir -> basebuf , stk -> baselen , el , 1 );
875
+ struct strbuf sb = STRBUF_INIT ;
876
+ strbuf_addbuf (& sb , & dir -> basebuf );
877
+ strbuf_addstr (& sb , dir -> exclude_per_dir );
878
+ el -> src = strbuf_detach (& sb , NULL );
879
+ add_excludes_from_file_to_list (el -> src , el -> src ,
880
+ stk -> baselen , el , 1 );
873
881
}
874
882
dir -> exclude_stack = stk ;
875
883
current = stk -> baselen ;
876
884
}
877
- dir -> basebuf [ baselen ] = '\0' ;
885
+ strbuf_setlen ( & dir -> basebuf , baselen ) ;
878
886
}
879
887
880
888
/*
@@ -1671,4 +1679,5 @@ void clear_directory(struct dir_struct *dir)
1671
1679
free (stk );
1672
1680
stk = prev ;
1673
1681
}
1682
+ strbuf_release (& dir -> basebuf );
1674
1683
}
0 commit comments