Merge branch 'rs/freebsd-getcwd-workaround'
authorJunio C Hamano <gitster@pobox.com>
Thu, 30 Mar 2017 21:07:15 +0000 (14:07 -0700)
committerJunio C Hamano <gitster@pobox.com>
Thu, 30 Mar 2017 21:07:15 +0000 (14:07 -0700)
FreeBSD implementation of getcwd(3) behaved differently when an
intermediate directory is unreadable/unsearchable depending on the
length of the buffer provided, which our strbuf_getcwd() was not
aware of. strbuf_getcwd() has been taught to cope with it better.

* rs/freebsd-getcwd-workaround:
strbuf: support long paths w/o read rights in strbuf_getcwd() on FreeBSD

1  2 
strbuf.c
diff --combined strbuf.c
index ace58e7367300975e118660ed2004c7d0885481c,01d25942014f277122dfe826f47a6be4d8d35474..00457940cfc163fed58b0206f5167c25c2c71b8a
+++ b/strbuf.c
@@@ -449,6 -449,17 +449,17 @@@ int strbuf_getcwd(struct strbuf *sb
                        strbuf_setlen(sb, strlen(sb->buf));
                        return 0;
                }
+               /*
+                * If getcwd(3) is implemented as a syscall that falls
+                * back to a regular lookup using readdir(3) etc. then
+                * we may be able to avoid EACCES by providing enough
+                * space to the syscall as it's not necessarily bound
+                * to the same restrictions as the fallback.
+                */
+               if (errno == EACCES && guessed_len < PATH_MAX)
+                       continue;
                if (errno != ERANGE)
                        break;
        }
@@@ -707,17 -718,6 +718,17 @@@ void strbuf_add_absolute_path(struct st
        strbuf_addstr(sb, path);
  }
  
 +void strbuf_add_real_path(struct strbuf *sb, const char *path)
 +{
 +      if (sb->len) {
 +              struct strbuf resolved = STRBUF_INIT;
 +              strbuf_realpath(&resolved, path, 1);
 +              strbuf_addbuf(sb, &resolved);
 +              strbuf_release(&resolved);
 +      } else
 +              strbuf_realpath(sb, path, 1);
 +}
 +
  int printf_ln(const char *fmt, ...)
  {
        int ret;