abspath: convert absolute_path() to strbuf
authorRené Scharfe <l.s.r@web.de>
Mon, 28 Jul 2014 18:33:55 +0000 (20:33 +0200)
committerJunio C Hamano <gitster@pobox.com>
Tue, 26 Aug 2014 18:06:06 +0000 (11:06 -0700)
Move most of the code of absolute_path() into the new function
strbuf_add_absolute_path() and in the process transform it to use
struct strbuf and xgetcwd() instead of a PATH_MAX-sized buffer,
which can be too small on some file systems.

Signed-off-by: Rene Scharfe <l.s.r@web.de>
Signed-off-by: Junio C Hamano <gitster@pobox.com>
Documentation/technical/api-strbuf.txt
abspath.c
strbuf.c
strbuf.h
index 834c406b3ba3943ccd193c8e62cbbc2d194c6d1f..1639a4a56b420cab84391d2f9338ea582046cfcc 100644 (file)
@@ -293,6 +293,12 @@ same behaviour as well.
 
        Set the buffer to the path of the current working directory.
 
+`strbuf_add_absolute_path`
+
+       Add a path to a buffer, converting a relative path to an
+       absolute one in the process.  Symbolic links are not
+       resolved.
+
 `stripspace`::
 
        Strip whitespace from a buffer. The second parameter controls if
index 6aa328f805fe1b0074e4e173effd97386218b923..5edb4e78162ca6646ef42ad2c8abc36872cd75a5 100644 (file)
--- a/abspath.c
+++ b/abspath.c
@@ -140,54 +140,16 @@ const char *real_path_if_valid(const char *path)
        return real_path_internal(path, 0);
 }
 
-static const char *get_pwd_cwd(void)
-{
-       static char cwd[PATH_MAX + 1];
-       char *pwd;
-       struct stat cwd_stat, pwd_stat;
-       if (getcwd(cwd, PATH_MAX) == NULL)
-               return NULL;
-       pwd = getenv("PWD");
-       if (pwd && strcmp(pwd, cwd)) {
-               stat(cwd, &cwd_stat);
-               if ((cwd_stat.st_dev || cwd_stat.st_ino) &&
-                   !stat(pwd, &pwd_stat) &&
-                   pwd_stat.st_dev == cwd_stat.st_dev &&
-                   pwd_stat.st_ino == cwd_stat.st_ino) {
-                       strlcpy(cwd, pwd, PATH_MAX);
-               }
-       }
-       return cwd;
-}
-
 /*
  * Use this to get an absolute path from a relative one. If you want
  * to resolve links, you should use real_path.
- *
- * If the path is already absolute, then return path. As the user is
- * never meant to free the return value, we're safe.
  */
 const char *absolute_path(const char *path)
 {
-       static char buf[PATH_MAX + 1];
-
-       if (!*path) {
-               die("The empty string is not a valid path");
-       } else if (is_absolute_path(path)) {
-               if (strlcpy(buf, path, PATH_MAX) >= PATH_MAX)
-                       die("Too long path: %.*s", 60, path);
-       } else {
-               size_t len;
-               const char *fmt;
-               const char *cwd = get_pwd_cwd();
-               if (!cwd)
-                       die_errno("Cannot determine the current working directory");
-               len = strlen(cwd);
-               fmt = (len > 0 && is_dir_sep(cwd[len - 1])) ? "%s%s" : "%s/%s";
-               if (snprintf(buf, PATH_MAX, fmt, cwd, path) >= PATH_MAX)
-                       die("Too long path: %.*s", 60, path);
-       }
-       return buf;
+       static struct strbuf sb = STRBUF_INIT;
+       strbuf_reset(&sb);
+       strbuf_add_absolute_path(&sb, path);
+       return sb.buf;
 }
 
 /*
index f3af203ec7ee5dab1f049118919250229576f559..bf4c31b1579b01f925c9963c1ba7d49e32dc93ee 100644 (file)
--- a/strbuf.c
+++ b/strbuf.c
@@ -568,6 +568,31 @@ void strbuf_humanise_bytes(struct strbuf *buf, off_t bytes)
        }
 }
 
+void strbuf_add_absolute_path(struct strbuf *sb, const char *path)
+{
+       if (!*path)
+               die("The empty string is not a valid path");
+       if (!is_absolute_path(path)) {
+               struct stat cwd_stat, pwd_stat;
+               size_t orig_len = sb->len;
+               char *cwd = xgetcwd();
+               char *pwd = getenv("PWD");
+               if (pwd && strcmp(pwd, cwd) &&
+                   !stat(cwd, &cwd_stat) &&
+                   (cwd_stat.st_dev || cwd_stat.st_ino) &&
+                   !stat(pwd, &pwd_stat) &&
+                   pwd_stat.st_dev == cwd_stat.st_dev &&
+                   pwd_stat.st_ino == cwd_stat.st_ino)
+                       strbuf_addstr(sb, pwd);
+               else
+                       strbuf_addstr(sb, cwd);
+               if (sb->len > orig_len && !is_dir_sep(sb->buf[sb->len - 1]))
+                       strbuf_addch(sb, '/');
+               free(cwd);
+       }
+       strbuf_addstr(sb, path);
+}
+
 int printf_ln(const char *fmt, ...)
 {
        int ret;
index 23b16c6cdf580984db5d5e9d3213bfcd473e95cf..455826ceb075631fdd9c86e54344080895808259 100644 (file)
--- a/strbuf.h
+++ b/strbuf.h
@@ -179,6 +179,8 @@ extern void strbuf_addstr_urlencode(struct strbuf *, const char *,
                                    int reserved);
 extern void strbuf_humanise_bytes(struct strbuf *buf, off_t bytes);
 
+extern void strbuf_add_absolute_path(struct strbuf *sb, const char *path);
+
 __attribute__((format (printf,1,2)))
 extern int printf_ln(const char *fmt, ...);
 __attribute__((format (printf,2,3)))