strbuf_remove(remaining, 0, end - remaining->buf);
}
+/* copies root part from remaining to resolved, canonicalizing it on the way */
+static void get_root_part(struct strbuf *resolved, struct strbuf *remaining)
+{
+ int offset = offset_1st_component(remaining->buf);
+
+ strbuf_reset(resolved);
+ strbuf_add(resolved, remaining->buf, offset);
+#ifdef GIT_WINDOWS_NATIVE
+ convert_slashes(resolved->buf);
+#endif
+ strbuf_remove(remaining, 0, offset);
+}
+
/* We allow "recursive" symbolic links. Only within reason, though. */
-#define MAXSYMLINKS 5
+#ifndef MAXSYMLINKS
+#define MAXSYMLINKS 32
+#endif
/*
* Return the real path (i.e., absolute path, with symlinks resolved
goto error_out;
}
- strbuf_reset(resolved);
+ strbuf_addstr(&remaining, path);
+ get_root_part(resolved, &remaining);
- if (is_absolute_path(path)) {
- /* absolute path; start with only root as being resolved */
- int offset = offset_1st_component(path);
- strbuf_add(resolved, path, offset);
- strbuf_addstr(&remaining, path + offset);
- } else {
+ if (!resolved->len) {
/* relative path; can use CWD as the initial resolved path */
if (strbuf_getcwd(resolved)) {
if (die_on_error)
else
goto error_out;
}
- strbuf_addstr(&remaining, path);
}
/* Iterate over the remaining path components */
strbuf_reset(&symlink);
if (num_symlinks++ > MAXSYMLINKS) {
+ errno = ELOOP;
+
if (die_on_error)
die("More than %d nested symlinks "
"on path '%s'", MAXSYMLINKS, path);
if (is_absolute_path(symlink.buf)) {
/* absolute symlink; set resolved to root */
- int offset = offset_1st_component(symlink.buf);
- strbuf_reset(resolved);
- strbuf_add(resolved, symlink.buf, offset);
- strbuf_remove(&symlink, 0, offset);
+ get_root_part(resolved, &symlink);
} else {
/*
* relative symlink
return strbuf_realpath(&realpath, path, 0);
}
+char *real_pathdup(const char *path, int die_on_error)
+{
+ struct strbuf realpath = STRBUF_INIT;
+ char *retval = NULL;
+
+ if (strbuf_realpath(&realpath, path, die_on_error))
+ retval = strbuf_detach(&realpath, NULL);
+
+ strbuf_release(&realpath);
+
+ return retval;
+}
+
/*
* Use this to get an absolute path from a relative one. If you want
* to resolve links, you should use real_path.
return sb.buf;
}
+char *absolute_pathdup(const char *path)
+{
+ struct strbuf sb = STRBUF_INIT;
+ strbuf_add_absolute_path(&sb, path);
+ return strbuf_detach(&sb, NULL);
+}
+
/*
* Unlike prefix_path, this should be used if the named file does
* not have to interact with index entry; i.e. name of a random file