abspath: convert absolute_path() to strbuf

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>

René Scharfe committed Jul 28, 2014 at 20:33 UTC 679eebe24d4c2120f8c01fb4524fcc489718fc9c
4 files changed +37 -42
Documentation/technical/api-strbuf.txt
+6
@@ -293,6 +293,12 @@ same behaviour as well.
293
294 Set the buffer to the path of the current working directory.
295
296 +`strbuf_add_absolute_path`
297 +
298 + Add a path to a buffer, converting a relative path to an
299 + absolute one in the process. Symbolic links are not
300 + resolved.
301 +
302 `stripspace`::
303
304 Strip whitespace from a buffer. The second parameter controls if
abspath.c
+4 -42
@@ -140,54 +140,16 @@ const char *real_path_if_valid(const char *path)
140 return real_path_internal(path, 0);
141 }
142
143 -static const char *get_pwd_cwd(void)
144 -{
145 - static char cwd[PATH_MAX + 1];
146 - char *pwd;
147 - struct stat cwd_stat, pwd_stat;
148 - if (getcwd(cwd, PATH_MAX) == NULL)
149 - return NULL;
150 - pwd = getenv("PWD");
151 - if (pwd && strcmp(pwd, cwd)) {
152 - stat(cwd, &cwd_stat);
153 - if ((cwd_stat.st_dev || cwd_stat.st_ino) &&
154 - !stat(pwd, &pwd_stat) &&
155 - pwd_stat.st_dev == cwd_stat.st_dev &&
156 - pwd_stat.st_ino == cwd_stat.st_ino) {
157 - strlcpy(cwd, pwd, PATH_MAX);
158 - }
159 - }
160 - return cwd;
161 -}
162 -
143 /*
144 * Use this to get an absolute path from a relative one. If you want
145 * to resolve links, you should use real_path.
166 - *
167 - * If the path is already absolute, then return path. As the user is
168 - * never meant to free the return value, we're safe.
146 */
147 const char *absolute_path(const char *path)
148 {
172 - static char buf[PATH_MAX + 1];
173 -
174 - if (!*path) {
175 - die("The empty string is not a valid path");
176 - } else if (is_absolute_path(path)) {
177 - if (strlcpy(buf, path, PATH_MAX) >= PATH_MAX)
178 - die("Too long path: %.*s", 60, path);
179 - } else {
180 - size_t len;
181 - const char *fmt;
182 - const char *cwd = get_pwd_cwd();
183 - if (!cwd)
184 - die_errno("Cannot determine the current working directory");
185 - len = strlen(cwd);
186 - fmt = (len > 0 && is_dir_sep(cwd[len - 1])) ? "%s%s" : "%s/%s";
187 - if (snprintf(buf, PATH_MAX, fmt, cwd, path) >= PATH_MAX)
188 - die("Too long path: %.*s", 60, path);
189 - }
190 - return buf;
149 + static struct strbuf sb = STRBUF_INIT;
150 + strbuf_reset(&sb);
151 + strbuf_add_absolute_path(&sb, path);
152 + return sb.buf;
153 }
154
155 /*
strbuf.c
+25
@@ -568,6 +568,31 @@ void strbuf_humanise_bytes(struct strbuf *buf, off_t bytes)
568 }
569 }
570
571 +void strbuf_add_absolute_path(struct strbuf *sb, const char *path)
572 +{
573 + if (!*path)
574 + die("The empty string is not a valid path");
575 + if (!is_absolute_path(path)) {
576 + struct stat cwd_stat, pwd_stat;
577 + size_t orig_len = sb->len;
578 + char *cwd = xgetcwd();
579 + char *pwd = getenv("PWD");
580 + if (pwd && strcmp(pwd, cwd) &&
581 + !stat(cwd, &cwd_stat) &&
582 + (cwd_stat.st_dev || cwd_stat.st_ino) &&
583 + !stat(pwd, &pwd_stat) &&
584 + pwd_stat.st_dev == cwd_stat.st_dev &&
585 + pwd_stat.st_ino == cwd_stat.st_ino)
586 + strbuf_addstr(sb, pwd);
587 + else
588 + strbuf_addstr(sb, cwd);
589 + if (sb->len > orig_len && !is_dir_sep(sb->buf[sb->len - 1]))
590 + strbuf_addch(sb, '/');
591 + free(cwd);
592 + }
593 + strbuf_addstr(sb, path);
594 +}
595 +
596 int printf_ln(const char *fmt, ...)
597 {
598 int ret;
strbuf.h
+2
@@ -179,6 +179,8 @@ extern void strbuf_addstr_urlencode(struct strbuf *, const char *,
179 int reserved);
180 extern void strbuf_humanise_bytes(struct strbuf *buf, off_t bytes);
181
182 +extern void strbuf_add_absolute_path(struct strbuf *sb, const char *path);
183 +
184 __attribute__((format (printf,1,2)))
185 extern int printf_ln(const char *fmt, ...);
186 __attribute__((format (printf,2,3)))