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 <drizzd@aon.at> Signed-off-by: Junio C Hamano <gitster@pobox.com>
This commit is contained in:
parent
6838d1ad6b
commit
f7e3bd37fb
43
symlinks.c
43
symlinks.c
@ -64,11 +64,13 @@ static inline void reset_lstat_cache(struct cache_def *cache)
|
|||||||
* of the prefix, where the cache should use the stat() function
|
* of the prefix, where the cache should use the stat() function
|
||||||
* instead of the lstat() function to test each path component.
|
* instead of the lstat() function to test each path component.
|
||||||
*/
|
*/
|
||||||
static int lstat_cache(struct cache_def *cache, const char *name, int len,
|
static int lstat_cache_matchlen(struct cache_def *cache,
|
||||||
int track_flags, int prefix_len_stat_func)
|
const char *name, int len,
|
||||||
|
int *ret_flags, int track_flags,
|
||||||
|
int prefix_len_stat_func)
|
||||||
{
|
{
|
||||||
int match_len, last_slash, last_slash_dir, previous_slash;
|
int match_len, last_slash, last_slash_dir, previous_slash;
|
||||||
int match_flags, ret_flags, save_flags, max_len, ret;
|
int save_flags, max_len, ret;
|
||||||
struct stat st;
|
struct stat st;
|
||||||
|
|
||||||
if (cache->track_flags != track_flags ||
|
if (cache->track_flags != track_flags ||
|
||||||
@ -90,13 +92,13 @@ static int lstat_cache(struct cache_def *cache, const char *name, int len,
|
|||||||
match_len = last_slash =
|
match_len = last_slash =
|
||||||
longest_path_match(name, len, cache->path, cache->len,
|
longest_path_match(name, len, cache->path, cache->len,
|
||||||
&previous_slash);
|
&previous_slash);
|
||||||
match_flags = cache->flags & track_flags & (FL_NOENT|FL_SYMLINK);
|
*ret_flags = cache->flags & track_flags & (FL_NOENT|FL_SYMLINK);
|
||||||
|
|
||||||
if (!(track_flags & FL_FULLPATH) && match_len == len)
|
if (!(track_flags & FL_FULLPATH) && match_len == len)
|
||||||
match_len = last_slash = previous_slash;
|
match_len = last_slash = previous_slash;
|
||||||
|
|
||||||
if (match_flags && match_len == cache->len)
|
if (*ret_flags && match_len == cache->len)
|
||||||
return match_flags;
|
return match_len;
|
||||||
/*
|
/*
|
||||||
* If we now have match_len > 0, we would know that
|
* If we now have match_len > 0, we would know that
|
||||||
* the matched part will always be a directory.
|
* 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,
|
|||||||
* a substring of the cache on a path component basis,
|
* a substring of the cache on a path component basis,
|
||||||
* we can return immediately.
|
* we can return immediately.
|
||||||
*/
|
*/
|
||||||
match_flags = track_flags & FL_DIR;
|
*ret_flags = track_flags & FL_DIR;
|
||||||
if (match_flags && len == match_len)
|
if (*ret_flags && len == match_len)
|
||||||
return match_flags;
|
return match_len;
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Okay, no match from the cache so far, so now we have to
|
* Okay, no match from the cache so far, so now we have to
|
||||||
* check the rest of the path components.
|
* check the rest of the path components.
|
||||||
*/
|
*/
|
||||||
ret_flags = FL_DIR;
|
*ret_flags = FL_DIR;
|
||||||
last_slash_dir = last_slash;
|
last_slash_dir = last_slash;
|
||||||
max_len = len < PATH_MAX ? len : PATH_MAX;
|
max_len = len < PATH_MAX ? len : PATH_MAX;
|
||||||
while (match_len < max_len) {
|
while (match_len < max_len) {
|
||||||
@ -133,16 +135,16 @@ static int lstat_cache(struct cache_def *cache, const char *name, int len,
|
|||||||
ret = lstat(cache->path, &st);
|
ret = lstat(cache->path, &st);
|
||||||
|
|
||||||
if (ret) {
|
if (ret) {
|
||||||
ret_flags = FL_LSTATERR;
|
*ret_flags = FL_LSTATERR;
|
||||||
if (errno == ENOENT)
|
if (errno == ENOENT)
|
||||||
ret_flags |= FL_NOENT;
|
*ret_flags |= FL_NOENT;
|
||||||
} else if (S_ISDIR(st.st_mode)) {
|
} else if (S_ISDIR(st.st_mode)) {
|
||||||
last_slash_dir = last_slash;
|
last_slash_dir = last_slash;
|
||||||
continue;
|
continue;
|
||||||
} else if (S_ISLNK(st.st_mode)) {
|
} else if (S_ISLNK(st.st_mode)) {
|
||||||
ret_flags = FL_SYMLINK;
|
*ret_flags = FL_SYMLINK;
|
||||||
} else {
|
} else {
|
||||||
ret_flags = FL_ERR;
|
*ret_flags = FL_ERR;
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
@ -152,7 +154,7 @@ static int lstat_cache(struct cache_def *cache, const char *name, int len,
|
|||||||
* path types, FL_NOENT, FL_SYMLINK and FL_DIR, can be cached
|
* path types, FL_NOENT, FL_SYMLINK and FL_DIR, can be cached
|
||||||
* for the moment!
|
* for the moment!
|
||||||
*/
|
*/
|
||||||
save_flags = ret_flags & track_flags & (FL_NOENT|FL_SYMLINK);
|
save_flags = *ret_flags & track_flags & (FL_NOENT|FL_SYMLINK);
|
||||||
if (save_flags && last_slash > 0 && last_slash <= PATH_MAX) {
|
if (save_flags && last_slash > 0 && last_slash <= PATH_MAX) {
|
||||||
cache->path[last_slash] = '\0';
|
cache->path[last_slash] = '\0';
|
||||||
cache->len = last_slash;
|
cache->len = last_slash;
|
||||||
@ -176,7 +178,16 @@ static int lstat_cache(struct cache_def *cache, const char *name, int len,
|
|||||||
} else {
|
} else {
|
||||||
reset_lstat_cache(cache);
|
reset_lstat_cache(cache);
|
||||||
}
|
}
|
||||||
return ret_flags;
|
return match_len;
|
||||||
|
}
|
||||||
|
|
||||||
|
static int lstat_cache(struct cache_def *cache, const char *name, int len,
|
||||||
|
int track_flags, int prefix_len_stat_func)
|
||||||
|
{
|
||||||
|
int flags;
|
||||||
|
(void)lstat_cache_matchlen(cache, name, len, &flags, track_flags,
|
||||||
|
prefix_len_stat_func);
|
||||||
|
return flags;
|
||||||
}
|
}
|
||||||
|
|
||||||
#define USE_ONLY_LSTAT 0
|
#define USE_ONLY_LSTAT 0
|
||||||
|
Loading…
x
Reference in New Issue
Block a user