* Check if name 'name' of length 'len' has a symlink leading * component, or if the directory exists and is real, or not. * * To speed up the check, some information is allowed to be cached. * This can be indicated by the 'track_flags' argument, which also can * be used to indicate that we should check the full path. * * The 'prefix_len_stat_func' parameter can be used to set the length *
| 73 | * instead of the lstat() function to test each path component. |
| 74 | */ |
| 75 | static int lstat_cache_matchlen(struct cache_def *cache, |
| 76 | const char *name, int len, |
| 77 | unsigned int *ret_flags, unsigned int track_flags, |
| 78 | int prefix_len_stat_func) |
| 79 | { |
| 80 | int match_len, last_slash, last_slash_dir, previous_slash; |
| 81 | unsigned int save_flags; |
| 82 | int ret, saved_errno = 0; |
| 83 | struct stat st; |
| 84 | |
| 85 | if (cache->track_flags != track_flags || |
| 86 | cache->prefix_len_stat_func != prefix_len_stat_func) { |
| 87 | /* |
| 88 | * As a safeguard rule we clear the cache if the |
| 89 | * values of track_flags and/or prefix_len_stat_func |
| 90 | * does not match with the last supplied values. |
| 91 | */ |
| 92 | reset_lstat_cache(cache); |
| 93 | cache->track_flags = track_flags; |
| 94 | cache->prefix_len_stat_func = prefix_len_stat_func; |
| 95 | match_len = last_slash = 0; |
| 96 | } else { |
| 97 | /* |
| 98 | * Check to see if we have a match from the cache for |
| 99 | * the 2 "excluding" path types. |
| 100 | */ |
| 101 | match_len = last_slash = |
| 102 | longest_path_match(name, len, cache->path.buf, |
| 103 | cache->path.len, &previous_slash); |
| 104 | *ret_flags = cache->flags & track_flags & (FL_NOENT|FL_SYMLINK); |
| 105 | |
| 106 | if (!(track_flags & FL_FULLPATH) && match_len == len) |
| 107 | match_len = last_slash = previous_slash; |
| 108 | |
| 109 | if (*ret_flags && match_len == cache->path.len) |
| 110 | return match_len; |
| 111 | /* |
| 112 | * If we now have match_len > 0, we would know that |
| 113 | * the matched part will always be a directory. |
| 114 | * |
| 115 | * Also, if we are tracking directories and 'name' is |
| 116 | * a substring of the cache on a path component basis, |
| 117 | * we can return immediately. |
| 118 | */ |
| 119 | *ret_flags = track_flags & FL_DIR; |
| 120 | if (*ret_flags && len == match_len) |
| 121 | return match_len; |
| 122 | } |
| 123 | |
| 124 | /* |
| 125 | * Okay, no match from the cache so far, so now we have to |
| 126 | * check the rest of the path components. |
| 127 | */ |
| 128 | *ret_flags = FL_DIR; |
| 129 | last_slash_dir = last_slash; |
| 130 | if (len > cache->path.len) |
| 131 | strbuf_grow(&cache->path, len - cache->path.len); |
| 132 | while (match_len < len) { |
no test coverage detected