Merge branch 'bw/realpath-wo-chdir'
authorJunio C Hamano <gitster@pobox.com>
Wed, 18 Jan 2017 23:12:16 +0000 (15:12 -0800)
committerJunio C Hamano <gitster@pobox.com>
Wed, 18 Jan 2017 23:12:16 +0000 (15:12 -0800)
The implementation of "real_path()" was to go there with chdir(2)
and call getcwd(3), but this obviously wouldn't be usable in a
threaded environment. Rewrite it to manually resolve relative
paths including symbolic links in path components.

* bw/realpath-wo-chdir:
real_path: set errno when max number of symlinks is exceeded
real_path: prevent redefinition of MAXSYMLINKS

abspath.c
dir.c
index 1d56f5ed9f95002d018458c907625fff27472231..fce40fddcc3b68a644fb93a698da8164a1d9b9cf 100644 (file)
--- a/abspath.c
+++ b/abspath.c
@@ -62,7 +62,9 @@ static void get_root_part(struct strbuf *resolved, struct strbuf *remaining)
 }
 
 /* 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
@@ -139,6 +141,8 @@ char *strbuf_realpath(struct strbuf *resolved, const char *path,
                        strbuf_reset(&symlink);
 
                        if (num_symlinks++ > MAXSYMLINKS) {
+                               errno = ELOOP;
+
                                if (die_on_error)
                                        die("More than %d nested symlinks "
                                            "on path '%s'", MAXSYMLINKS, path);
diff --git a/dir.c b/dir.c
index 4ac63bc940fa043fe82002dd6c282b0b5abcbad8..65c3e681b8e04aa47b6cf41faca0822ead59fb6a 100644 (file)
--- a/dir.c
+++ b/dir.c
@@ -2731,8 +2731,8 @@ void connect_work_tree_and_git_dir(const char *work_tree_, const char *git_dir_)
 {
        struct strbuf file_name = STRBUF_INIT;
        struct strbuf rel_path = STRBUF_INIT;
-       char *git_dir = xstrdup(real_path(git_dir_));
-       char *work_tree = xstrdup(real_path(work_tree_));
+       char *git_dir = real_pathdup(git_dir_);
+       char *work_tree = real_pathdup(work_tree_);
 
        /* Update gitfile */
        strbuf_addf(&file_name, "%s/.git", work_tree);