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>
Clemens Buchacher committed
Oct 9, 2010 at 15:52 UTC
f7e3bd37fb9355ee036da4cf11d6e8186b506d5f
1 file changed
+27
-16
symlinks.c
+27
-16
@@ -64,11 +64,13 @@ static inline void reset_lstat_cache(struct cache_def *cache)
64
* of the prefix, where the cache should use the stat() function
65
* instead of the lstat() function to test each path component.
66
*/
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)
71
{
72
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;
74
struct stat st;
75
76
if (cache->track_flags != track_flags ||
@@ -90,13 +92,13 @@ static int lstat_cache(struct cache_def *cache, const char *name, int len,
92
match_len = last_slash =
93
longest_path_match(name, len, cache->path, cache->len,
94
&previous_slash);
93
- match_flags = cache->flags & track_flags & (FL_NOENT|FL_SYMLINK);
95
+ *ret_flags = cache->flags & track_flags & (FL_NOENT|FL_SYMLINK);
96
97
if (!(track_flags & FL_FULLPATH) && match_len == len)
98
match_len = last_slash = previous_slash;
99
98
- if (match_flags && match_len == cache->len)
99
- return match_flags;
100
+ if (*ret_flags && match_len == cache->len)
101
+ return match_len;
102
/*
103
* If we now have match_len > 0, we would know that
104
* 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,
107
* a substring of the cache on a path component basis,
108
* we can return immediately.
109
*/
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;
113
}
114
115
/*
116
* Okay, no match from the cache so far, so now we have to
117
* check the rest of the path components.
118
*/
117
- ret_flags = FL_DIR;
119
+ *ret_flags = FL_DIR;
120
last_slash_dir = last_slash;
121
max_len = len < PATH_MAX ? len : PATH_MAX;
122
while (match_len < max_len) {
@@ -133,16 +135,16 @@ static int lstat_cache(struct cache_def *cache, const char *name, int len,
135
ret = lstat(cache->path, &st);
136
137
if (ret) {
136
- ret_flags = FL_LSTATERR;
138
+ *ret_flags = FL_LSTATERR;
139
if (errno == ENOENT)
138
- ret_flags |= FL_NOENT;
140
+ *ret_flags |= FL_NOENT;
141
} else if (S_ISDIR(st.st_mode)) {
142
last_slash_dir = last_slash;
143
continue;
144
} else if (S_ISLNK(st.st_mode)) {
143
- ret_flags = FL_SYMLINK;
145
+ *ret_flags = FL_SYMLINK;
146
} else {
145
- ret_flags = FL_ERR;
147
+ *ret_flags = FL_ERR;
148
}
149
break;
150
}
@@ -152,7 +154,7 @@ static int lstat_cache(struct cache_def *cache, const char *name, int len,
154
* path types, FL_NOENT, FL_SYMLINK and FL_DIR, can be cached
155
* for the moment!
156
*/
155
- save_flags = ret_flags & track_flags & (FL_NOENT|FL_SYMLINK);
157
+ save_flags = *ret_flags & track_flags & (FL_NOENT|FL_SYMLINK);
158
if (save_flags && last_slash > 0 && last_slash <= PATH_MAX) {
159
cache->path[last_slash] = '\0';
160
cache->len = last_slash;
@@ -176,7 +178,16 @@ static int lstat_cache(struct cache_def *cache, const char *name, int len,
178
} else {
179
reset_lstat_cache(cache);
180
}
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;
191
}
192
193
#define USE_ONLY_LSTAT 0