|
|
|
@ -64,11 +64,13 @@ static inline void reset_lstat_cache(struct cache_def *cache)
@@ -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 |
|
|
|
|
* instead of the lstat() function to test each path component. |
|
|
|
|
*/ |
|
|
|
|
static int lstat_cache(struct cache_def *cache, const char *name, int len, |
|
|
|
|
int track_flags, int prefix_len_stat_func) |
|
|
|
|
static int lstat_cache_matchlen(struct cache_def *cache, |
|
|
|
|
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_flags, ret_flags, save_flags, max_len, ret; |
|
|
|
|
int save_flags, max_len, ret; |
|
|
|
|
struct stat st; |
|
|
|
|
|
|
|
|
|
if (cache->track_flags != track_flags || |
|
|
|
@ -90,13 +92,13 @@ static int lstat_cache(struct cache_def *cache, const char *name, int len,
@@ -90,13 +92,13 @@ static int lstat_cache(struct cache_def *cache, const char *name, int len,
|
|
|
|
|
match_len = last_slash = |
|
|
|
|
longest_path_match(name, len, cache->path, cache->len, |
|
|
|
|
&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) |
|
|
|
|
match_len = last_slash = previous_slash; |
|
|
|
|
|
|
|
|
|
if (match_flags && match_len == cache->len) |
|
|
|
|
return match_flags; |
|
|
|
|
if (*ret_flags && match_len == cache->len) |
|
|
|
|
return match_len; |
|
|
|
|
/* |
|
|
|
|
* If we now have match_len > 0, we would know that |
|
|
|
|
* 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,
@@ -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, |
|
|
|
|
* we can return immediately. |
|
|
|
|
*/ |
|
|
|
|
match_flags = track_flags & FL_DIR; |
|
|
|
|
if (match_flags && len == match_len) |
|
|
|
|
return match_flags; |
|
|
|
|
*ret_flags = track_flags & FL_DIR; |
|
|
|
|
if (*ret_flags && len == match_len) |
|
|
|
|
return match_len; |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
/* |
|
|
|
|
* Okay, no match from the cache so far, so now we have to |
|
|
|
|
* check the rest of the path components. |
|
|
|
|
*/ |
|
|
|
|
ret_flags = FL_DIR; |
|
|
|
|
*ret_flags = FL_DIR; |
|
|
|
|
last_slash_dir = last_slash; |
|
|
|
|
max_len = len < PATH_MAX ? len : PATH_MAX; |
|
|
|
|
while (match_len < max_len) { |
|
|
|
@ -133,16 +135,16 @@ static int lstat_cache(struct cache_def *cache, const char *name, int len,
@@ -133,16 +135,16 @@ static int lstat_cache(struct cache_def *cache, const char *name, int len,
|
|
|
|
|
ret = lstat(cache->path, &st); |
|
|
|
|
|
|
|
|
|
if (ret) { |
|
|
|
|
ret_flags = FL_LSTATERR; |
|
|
|
|
*ret_flags = FL_LSTATERR; |
|
|
|
|
if (errno == ENOENT) |
|
|
|
|
ret_flags |= FL_NOENT; |
|
|
|
|
*ret_flags |= FL_NOENT; |
|
|
|
|
} else if (S_ISDIR(st.st_mode)) { |
|
|
|
|
last_slash_dir = last_slash; |
|
|
|
|
continue; |
|
|
|
|
} else if (S_ISLNK(st.st_mode)) { |
|
|
|
|
ret_flags = FL_SYMLINK; |
|
|
|
|
*ret_flags = FL_SYMLINK; |
|
|
|
|
} else { |
|
|
|
|
ret_flags = FL_ERR; |
|
|
|
|
*ret_flags = FL_ERR; |
|
|
|
|
} |
|
|
|
|
break; |
|
|
|
|
} |
|
|
|
@ -152,7 +154,7 @@ static int lstat_cache(struct cache_def *cache, const char *name, int len,
@@ -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 |
|
|
|
|
* 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) { |
|
|
|
|
cache->path[last_slash] = '\0'; |
|
|
|
|
cache->len = last_slash; |
|
|
|
@ -176,7 +178,16 @@ static int lstat_cache(struct cache_def *cache, const char *name, int len,
@@ -176,7 +178,16 @@ static int lstat_cache(struct cache_def *cache, const char *name, int len,
|
|
|
|
|
} else { |
|
|
|
|
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 |
|
|
|
|