static char *resolve_symlink(char *p, size_t s)
{
int depth = MAXDEPTH;
+ static struct strbuf link = STRBUF_INIT;
while (depth--) {
- char link[PATH_MAX];
- int link_len = readlink(p, link, sizeof(link));
- if (link_len < 0) {
- /* not a symlink anymore */
- return p;
- }
- else if (link_len < sizeof(link))
- /* readlink() never null-terminates */
- link[link_len] = '\0';
- else {
- warning("%s: symlink too long", p);
- return p;
- }
+ if (strbuf_readlink(&link, p, strlen(p)) < 0)
+ break;
- if (is_absolute_path(link)) {
+ if (is_absolute_path(link.buf)) {
/* absolute path simply replaces p */
- if (link_len < s)
- strcpy(p, link);
+ if (link.len < s)
+ strcpy(p, link.buf);
else {
warning("%s: symlink too long", p);
- return p;
+ break;
}
} else {
/*
- * link is a relative path, so I must replace the
+ * link is a relative path, so replace the
* last element of p with it.
*/
char *r = (char *)last_path_elm(p);
- if (r - p + link_len < s)
- strcpy(r, link);
+ if (r - p + link.len < s)
+ strcpy(r, link.buf);
else {
warning("%s: symlink too long", p);
- return p;
+ break;
}
}
}
+ strbuf_reset(&link);
return p;
}