@matheusbsbs / matheus-bagliano / commits / ad6f2157f9
Fork 0

dir: restructure in a way to avoid passing around a struct dirent

Restructure the code slightly to avoid passing around a struct dirent anywhere, which also enables us to avoid trying to manufacture one. Signed-off-by: Jeff King <peff@peff.net> Signed-off-by: Elijah Newren <newren@gmail.com> Signed-off-by: Junio C Hamano <gitster@pobox.com>

Jeff King committed Jan 16, 2020 at 20:21 UTC ad6f2157f951dc2ffeb7a01f090686f0bbb06f7a
1 file changed +31 -42
dir.c
+31 -42
@@ -41,7 +41,8 @@ struct cached_dir {
41 int nr_files;
42 int nr_dirs;
43
44 - struct dirent *de;
44 + const char *d_name;
45 + int d_type;
46 const char *file;
47 struct untracked_cache_dir *ucd;
48 };
@@ -50,8 +51,8 @@ static enum path_treatment read_directory_recursive(struct dir_struct *dir,
51 struct index_state *istate, const char *path, int len,
52 struct untracked_cache_dir *untracked,
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);
56
57 int count_slashes(const char *s)
58 {
@@ -1215,8 +1216,7 @@ static struct path_pattern *last_matching_pattern_from_list(const char *pathname
1216 int prefix = pattern->nowildcardlen;
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 if (*dtype != DT_DIR)
1221 continue;
1222 }
@@ -1842,10 +1842,9 @@ static int get_index_dtype(struct index_state *istate,
1842 return DT_UNKNOWN;
1843 }
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 {
1848 - int dtype = de ? DTYPE(de) : DT_UNKNOWN;
1848 struct stat st;
1849
1850 if (dtype != DT_UNKNOWN)
@@ -1870,14 +1869,13 @@ static enum path_treatment treat_one_path(struct dir_struct *dir,
1869 struct strbuf *path,
1870 int baselen,
1871 const struct pathspec *pathspec,
1873 - int dtype, struct dirent *de)
1872 + int dtype)
1873 {
1874 int exclude;
1875 int has_path_in_index = !!index_file_exists(istate, path->buf, path->len, ignore_case);
1876 enum path_treatment path_treatment;
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);
1879
1880 /* Always exclude indexed files */
1881 if (dtype != DT_DIR && has_path_in_index)
@@ -1985,21 +1983,18 @@ static enum path_treatment treat_path(struct dir_struct *dir,
1983 int baselen,
1984 const struct pathspec *pathspec)
1985 {
1988 - int dtype;
1989 - struct dirent *de = cdir->de;
1990 -
1991 - if (!de)
1986 + if (!cdir->d_name)
1987 return treat_path_fast(dir, untracked, cdir, istate, path,
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"))
1990 return path_none;
1991 strbuf_setlen(path, baselen);
1997 - strbuf_addstr(path, de->d_name);
1992 + strbuf_addstr(path, cdir->d_name);
1993 if (simplify_away(path->buf, path->len, pathspec))
1994 return path_none;
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);
1998 }
1999
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,
2082
2083 static int read_cached_dir(struct cached_dir *cdir)
2084 {
2085 + struct dirent *de;
2086 +
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;
2092 return -1;
2093 + }
2094 + cdir->d_name = de->d_name;
2095 + cdir->d_type = DTYPE(de);
2096 return 0;
2097 }
2098 while (cdir->nr_dirs < cdir->untracked->dirs_nr) {
@@ -2216,7 +2218,7 @@ static enum path_treatment read_directory_recursive(struct dir_struct *dir,
2218 /* recurse into subdir if instructed by treat_path */
2219 if ((state == path_recurse) ||
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) &&
2222 ((dir->flags & DIR_SHOW_IGNORED_TOO) ||
2223 (pathspec &&
2224 do_match_pathspec(istate, pathspec, path.buf, path.len,
@@ -2314,10 +2316,10 @@ static int treat_leading_path(struct dir_struct *dir,
2316 */
2317
2318 struct strbuf sb = STRBUF_INIT;
2319 + struct strbuf subdir = STRBUF_INIT;
2320 int prevlen, baselen;
2321 const char *cp;
2322 struct cached_dir cdir;
2320 - struct dirent *de;
2323 enum path_treatment state = path_none;
2324
2325 /*
@@ -2342,22 +2344,8 @@ static int treat_leading_path(struct dir_struct *dir,
2344 if (!len)
2345 return 1;
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));
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;
2349 baselen = 0;
2350 prevlen = 0;
2351 while (1) {
@@ -2374,12 +2362,13 @@ static int treat_leading_path(struct dir_struct *dir,
2362 break;
2363 strbuf_reset(&sb);
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;
2368 state = treat_path(dir, NULL, &cdir, istate, &sb, prevlen,
2369 pathspec);
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 &&
2372 (dir->flags & DIR_SHOW_IGNORED_TOO ||
2373 do_match_pathspec(istate, pathspec, sb.buf, sb.len,
2374 baselen, NULL, DO_MATCH_LEADING_PATHSPEC) == MATCHED_RECURSIVELY_LEADING_PATHSPEC)) {
@@ -2403,7 +2392,7 @@ static int treat_leading_path(struct dir_struct *dir,
2392 &sb, baselen, pathspec,
2393 state);
2394
2406 - free(de);
2395 + strbuf_release(&subdir);
2396 strbuf_release(&sb);
2397 return state == path_recurse;
2398 }