@@ -41,7 +41,8 @@ struct cached_dir {
41
41
int nr_files ;
42
42
int nr_dirs ;
43
43
44
- struct dirent * de ;
44
+ const char * d_name ;
45
+ int d_type ;
45
46
const char * file ;
46
47
struct untracked_cache_dir * ucd ;
47
48
};
@@ -50,8 +51,8 @@ static enum path_treatment read_directory_recursive(struct dir_struct *dir,
50
51
struct index_state * istate , const char * path , int len ,
51
52
struct untracked_cache_dir * untracked ,
52
53
int check_only , int stop_at_first_file , const struct pathspec * pathspec );
53
- static int get_dtype ( struct dirent * de , struct index_state * istate ,
54
- const char * path , int len );
54
+ static int resolve_dtype ( int dtype , struct index_state * istate ,
55
+ const char * path , int len );
55
56
56
57
int count_slashes (const char * s )
57
58
{
@@ -1215,8 +1216,7 @@ static struct path_pattern *last_matching_pattern_from_list(const char *pathname
1215
1216
int prefix = pattern -> nowildcardlen ;
1216
1217
1217
1218
if (pattern -> flags & PATTERN_FLAG_MUSTBEDIR ) {
1218
- if (* dtype == DT_UNKNOWN )
1219
- * dtype = get_dtype (NULL , istate , pathname , pathlen );
1219
+ * dtype = resolve_dtype (* dtype , istate , pathname , pathlen );
1220
1220
if (* dtype != DT_DIR )
1221
1221
continue ;
1222
1222
}
@@ -1842,10 +1842,9 @@ static int get_index_dtype(struct index_state *istate,
1842
1842
return DT_UNKNOWN ;
1843
1843
}
1844
1844
1845
- static int get_dtype ( struct dirent * de , struct index_state * istate ,
1846
- const char * path , int len )
1845
+ static int resolve_dtype ( int dtype , struct index_state * istate ,
1846
+ const char * path , int len )
1847
1847
{
1848
- int dtype = de ? DTYPE (de ) : DT_UNKNOWN ;
1849
1848
struct stat st ;
1850
1849
1851
1850
if (dtype != DT_UNKNOWN )
@@ -1870,14 +1869,13 @@ static enum path_treatment treat_one_path(struct dir_struct *dir,
1870
1869
struct strbuf * path ,
1871
1870
int baselen ,
1872
1871
const struct pathspec * pathspec ,
1873
- int dtype , struct dirent * de )
1872
+ int dtype )
1874
1873
{
1875
1874
int exclude ;
1876
1875
int has_path_in_index = !!index_file_exists (istate , path -> buf , path -> len , ignore_case );
1877
1876
enum path_treatment path_treatment ;
1878
1877
1879
- if (dtype == DT_UNKNOWN )
1880
- dtype = get_dtype (de , istate , path -> buf , path -> len );
1878
+ dtype = resolve_dtype (dtype , istate , path -> buf , path -> len );
1881
1879
1882
1880
/* Always exclude indexed files */
1883
1881
if (dtype != DT_DIR && has_path_in_index )
@@ -1985,21 +1983,18 @@ static enum path_treatment treat_path(struct dir_struct *dir,
1985
1983
int baselen ,
1986
1984
const struct pathspec * pathspec )
1987
1985
{
1988
- int dtype ;
1989
- struct dirent * de = cdir -> de ;
1990
-
1991
- if (!de )
1986
+ if (!cdir -> d_name )
1992
1987
return treat_path_fast (dir , untracked , cdir , istate , path ,
1993
1988
baselen , pathspec );
1994
- if (is_dot_or_dotdot (de -> d_name ) || !fspathcmp (de -> d_name , ".git" ))
1989
+ if (is_dot_or_dotdot (cdir -> d_name ) || !fspathcmp (cdir -> d_name , ".git" ))
1995
1990
return path_none ;
1996
1991
strbuf_setlen (path , baselen );
1997
- strbuf_addstr (path , de -> d_name );
1992
+ strbuf_addstr (path , cdir -> d_name );
1998
1993
if (simplify_away (path -> buf , path -> len , pathspec ))
1999
1994
return path_none ;
2000
1995
2001
- dtype = DTYPE ( de );
2002
- return treat_one_path ( dir , untracked , istate , path , baselen , pathspec , dtype , de );
1996
+ return treat_one_path ( dir , untracked , istate , path , baselen , pathspec ,
1997
+ cdir -> d_type );
2003
1998
}
2004
1999
2005
2000
static void add_untracked (struct untracked_cache_dir * dir , const char * name )
@@ -2087,10 +2082,17 @@ static int open_cached_dir(struct cached_dir *cdir,
2087
2082
2088
2083
static int read_cached_dir (struct cached_dir * cdir )
2089
2084
{
2085
+ struct dirent * de ;
2086
+
2090
2087
if (cdir -> fdir ) {
2091
- cdir -> de = readdir (cdir -> fdir );
2092
- if (!cdir -> de )
2088
+ de = readdir (cdir -> fdir );
2089
+ if (!de ) {
2090
+ cdir -> d_name = NULL ;
2091
+ cdir -> d_type = DT_UNKNOWN ;
2093
2092
return -1 ;
2093
+ }
2094
+ cdir -> d_name = de -> d_name ;
2095
+ cdir -> d_type = DTYPE (de );
2094
2096
return 0 ;
2095
2097
}
2096
2098
while (cdir -> nr_dirs < cdir -> untracked -> dirs_nr ) {
@@ -2216,7 +2218,7 @@ static enum path_treatment read_directory_recursive(struct dir_struct *dir,
2216
2218
/* recurse into subdir if instructed by treat_path */
2217
2219
if ((state == path_recurse ) ||
2218
2220
((state == path_untracked ) &&
2219
- (get_dtype (cdir .de , istate , path .buf , path .len ) == DT_DIR ) &&
2221
+ (resolve_dtype (cdir .d_type , istate , path .buf , path .len ) == DT_DIR ) &&
2220
2222
((dir -> flags & DIR_SHOW_IGNORED_TOO ) ||
2221
2223
(pathspec &&
2222
2224
do_match_pathspec (istate , pathspec , path .buf , path .len ,
@@ -2308,16 +2310,16 @@ static int treat_leading_path(struct dir_struct *dir,
2308
2310
* WARNING WARNING WARNING:
2309
2311
*
2310
2312
* Any updates to the traversal logic here may need corresponding
2311
- * updates in treat_leading_path (). See the commit message for the
2312
- * commit adding this warning as well as the commit preceding it
2313
- * for details.
2313
+ * updates in read_directory_recursive (). See 777b420347 (dir:
2314
+ * synchronize treat_leading_path() and read_directory_recursive(),
2315
+ * 2019-12-19) and its parent commit for details.
2314
2316
*/
2315
2317
2316
2318
struct strbuf sb = STRBUF_INIT ;
2319
+ struct strbuf subdir = STRBUF_INIT ;
2317
2320
int prevlen , baselen ;
2318
2321
const char * cp ;
2319
2322
struct cached_dir cdir ;
2320
- struct dirent * de ;
2321
2323
enum path_treatment state = path_none ;
2322
2324
2323
2325
/*
@@ -2342,22 +2344,8 @@ static int treat_leading_path(struct dir_struct *dir,
2342
2344
if (!len )
2343
2345
return 1 ;
2344
2346
2345
- /*
2346
- * We need a manufactured dirent with sufficient space to store a
2347
- * leading directory component of path in its d_name. Here, we
2348
- * assume that the dirent's d_name is either declared as
2349
- * char d_name[BIG_ENOUGH]
2350
- * or that it is declared at the end of the struct as
2351
- * char d_name[]
2352
- * For either case, padding with len+1 bytes at the end will ensure
2353
- * sufficient storage space.
2354
- */
2355
- de = xcalloc (1 , st_add3 (sizeof (struct dirent ), len , 1 ));
2356
2347
memset (& cdir , 0 , sizeof (cdir ));
2357
- cdir .de = de ;
2358
- #if defined(DT_UNKNOWN ) && !defined(NO_D_TYPE_IN_DIRENT )
2359
- de -> d_type = DT_DIR ;
2360
- #endif
2348
+ cdir .d_type = DT_DIR ;
2361
2349
baselen = 0 ;
2362
2350
prevlen = 0 ;
2363
2351
while (1 ) {
@@ -2374,15 +2362,20 @@ static int treat_leading_path(struct dir_struct *dir,
2374
2362
break ;
2375
2363
strbuf_reset (& sb );
2376
2364
strbuf_add (& sb , path , prevlen );
2377
- memcpy (de -> d_name , path + prevlen , baselen - prevlen );
2378
- de -> d_name [baselen - prevlen ] = '\0' ;
2365
+ strbuf_reset (& subdir );
2366
+ strbuf_add (& subdir , path + prevlen , baselen - prevlen );
2367
+ cdir .d_name = subdir .buf ;
2379
2368
state = treat_path (dir , NULL , & cdir , istate , & sb , prevlen ,
2380
2369
pathspec );
2381
2370
if (state == path_untracked &&
2382
- get_dtype (cdir .de , istate , sb .buf , sb .len ) == DT_DIR &&
2371
+ resolve_dtype (cdir .d_type , istate , sb .buf , sb .len ) == DT_DIR &&
2383
2372
(dir -> flags & DIR_SHOW_IGNORED_TOO ||
2384
2373
do_match_pathspec (istate , pathspec , sb .buf , sb .len ,
2385
2374
baselen , NULL , DO_MATCH_LEADING_PATHSPEC ) == MATCHED_RECURSIVELY_LEADING_PATHSPEC )) {
2375
+ if (!match_pathspec (istate , pathspec , sb .buf , sb .len ,
2376
+ 0 /* prefix */ , NULL ,
2377
+ 0 /* do NOT special case dirs */ ))
2378
+ state = path_none ;
2386
2379
add_path_to_appropriate_result_list (dir , NULL , & cdir ,
2387
2380
istate ,
2388
2381
& sb , baselen ,
@@ -2399,7 +2392,7 @@ static int treat_leading_path(struct dir_struct *dir,
2399
2392
& sb , baselen , pathspec ,
2400
2393
state );
2401
2394
2402
- free ( de );
2395
+ strbuf_release ( & subdir );
2403
2396
strbuf_release (& sb );
2404
2397
return state == path_recurse ;
2405
2398
}
0 commit comments