unpack-trees: handle lstat failure for existing directory
[gitweb.git] / path.c
diff --git a/path.c b/path.c
index b4c8d917229a4187f36a76f43603fc036e65632e..a2c9d1e24afb9d1250c846791607c49d82e9565e 100644 (file)
--- a/path.c
+++ b/path.c
@@ -122,6 +122,44 @@ char *git_path(const char *fmt, ...)
        return cleanup_path(pathname);
 }
 
+char *git_path_submodule(const char *path, const char *fmt, ...)
+{
+       char *pathname = get_pathname();
+       struct strbuf buf = STRBUF_INIT;
+       const char *git_dir;
+       va_list args;
+       unsigned len;
+
+       len = strlen(path);
+       if (len > PATH_MAX-100)
+               return bad_path;
+
+       strbuf_addstr(&buf, path);
+       if (len && path[len-1] != '/')
+               strbuf_addch(&buf, '/');
+       strbuf_addstr(&buf, ".git");
+
+       git_dir = read_gitfile_gently(buf.buf);
+       if (git_dir) {
+               strbuf_reset(&buf);
+               strbuf_addstr(&buf, git_dir);
+       }
+       strbuf_addch(&buf, '/');
+
+       if (buf.len >= PATH_MAX)
+               return bad_path;
+       memcpy(pathname, buf.buf, buf.len + 1);
+
+       strbuf_release(&buf);
+       len = strlen(pathname);
+
+       va_start(args, fmt);
+       len += vsnprintf(pathname + len, PATH_MAX - len, fmt, args);
+       va_end(args);
+       if (len >= PATH_MAX)
+               return bad_path;
+       return cleanup_path(pathname);
+}
 
 /* git_mkstemp() - create tmp file honoring TMPDIR variable */
 int git_mkstemp(char *path, size_t len, const char *template)
@@ -316,6 +354,8 @@ char *expand_user_path(const char *path)
                size_t username_len = first_slash - username;
                if (username_len == 0) {
                        const char *home = getenv("HOME");
+                       if (!home)
+                               goto return_null;
                        strbuf_add(&user_path, home, strlen(home));
                } else {
                        struct passwd *pw = getpw_str(username, username_len);