Skip to content

Commit f7e3bd3

Browse files
Clemens Buchachergitster
authored andcommitted
lstat_cache: optionally return match_len
Return match_len so that the caller can know which leading path component matched. Signed-off-by: Clemens Buchacher <[email protected]> Signed-off-by: Junio C Hamano <[email protected]>
1 parent 6838d1a commit f7e3bd3

File tree

1 file changed

+27
-16
lines changed

1 file changed

+27
-16
lines changed

symlinks.c

Lines changed: 27 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -64,11 +64,13 @@ static inline void reset_lstat_cache(struct cache_def *cache)
6464
* of the prefix, where the cache should use the stat() function
6565
* instead of the lstat() function to test each path component.
6666
*/
67-
static int lstat_cache(struct cache_def *cache, const char *name, int len,
68-
int track_flags, int prefix_len_stat_func)
67+
static int lstat_cache_matchlen(struct cache_def *cache,
68+
const char *name, int len,
69+
int *ret_flags, int track_flags,
70+
int prefix_len_stat_func)
6971
{
7072
int match_len, last_slash, last_slash_dir, previous_slash;
71-
int match_flags, ret_flags, save_flags, max_len, ret;
73+
int save_flags, max_len, ret;
7274
struct stat st;
7375

7476
if (cache->track_flags != track_flags ||
@@ -90,13 +92,13 @@ static int lstat_cache(struct cache_def *cache, const char *name, int len,
9092
match_len = last_slash =
9193
longest_path_match(name, len, cache->path, cache->len,
9294
&previous_slash);
93-
match_flags = cache->flags & track_flags & (FL_NOENT|FL_SYMLINK);
95+
*ret_flags = cache->flags & track_flags & (FL_NOENT|FL_SYMLINK);
9496

9597
if (!(track_flags & FL_FULLPATH) && match_len == len)
9698
match_len = last_slash = previous_slash;
9799

98-
if (match_flags && match_len == cache->len)
99-
return match_flags;
100+
if (*ret_flags && match_len == cache->len)
101+
return match_len;
100102
/*
101103
* If we now have match_len > 0, we would know that
102104
* the matched part will always be a directory.
@@ -105,16 +107,16 @@ static int lstat_cache(struct cache_def *cache, const char *name, int len,
105107
* a substring of the cache on a path component basis,
106108
* we can return immediately.
107109
*/
108-
match_flags = track_flags & FL_DIR;
109-
if (match_flags && len == match_len)
110-
return match_flags;
110+
*ret_flags = track_flags & FL_DIR;
111+
if (*ret_flags && len == match_len)
112+
return match_len;
111113
}
112114

113115
/*
114116
* Okay, no match from the cache so far, so now we have to
115117
* check the rest of the path components.
116118
*/
117-
ret_flags = FL_DIR;
119+
*ret_flags = FL_DIR;
118120
last_slash_dir = last_slash;
119121
max_len = len < PATH_MAX ? len : PATH_MAX;
120122
while (match_len < max_len) {
@@ -133,16 +135,16 @@ static int lstat_cache(struct cache_def *cache, const char *name, int len,
133135
ret = lstat(cache->path, &st);
134136

135137
if (ret) {
136-
ret_flags = FL_LSTATERR;
138+
*ret_flags = FL_LSTATERR;
137139
if (errno == ENOENT)
138-
ret_flags |= FL_NOENT;
140+
*ret_flags |= FL_NOENT;
139141
} else if (S_ISDIR(st.st_mode)) {
140142
last_slash_dir = last_slash;
141143
continue;
142144
} else if (S_ISLNK(st.st_mode)) {
143-
ret_flags = FL_SYMLINK;
145+
*ret_flags = FL_SYMLINK;
144146
} else {
145-
ret_flags = FL_ERR;
147+
*ret_flags = FL_ERR;
146148
}
147149
break;
148150
}
@@ -152,7 +154,7 @@ static int lstat_cache(struct cache_def *cache, const char *name, int len,
152154
* path types, FL_NOENT, FL_SYMLINK and FL_DIR, can be cached
153155
* for the moment!
154156
*/
155-
save_flags = ret_flags & track_flags & (FL_NOENT|FL_SYMLINK);
157+
save_flags = *ret_flags & track_flags & (FL_NOENT|FL_SYMLINK);
156158
if (save_flags && last_slash > 0 && last_slash <= PATH_MAX) {
157159
cache->path[last_slash] = '\0';
158160
cache->len = last_slash;
@@ -176,7 +178,16 @@ static int lstat_cache(struct cache_def *cache, const char *name, int len,
176178
} else {
177179
reset_lstat_cache(cache);
178180
}
179-
return ret_flags;
181+
return match_len;
182+
}
183+
184+
static int lstat_cache(struct cache_def *cache, const char *name, int len,
185+
int track_flags, int prefix_len_stat_func)
186+
{
187+
int flags;
188+
(void)lstat_cache_matchlen(cache, name, len, &flags, track_flags,
189+
prefix_len_stat_func);
190+
return flags;
180191
}
181192

182193
#define USE_ONLY_LSTAT 0

0 commit comments

Comments
 (0)