Skip to content

Commit

Permalink
Browse files Browse the repository at this point in the history
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>
  • Loading branch information
René Scharfe authored and Junio C Hamano committed Aug 26, 2014
1 parent 4d3ab44 commit 679eebe
Show file tree
Hide file tree
Showing 4 changed files with 37 additions and 42 deletions.
6 changes: 6 additions & 0 deletions Documentation/technical/api-strbuf.txt
Expand Up @@ -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
Expand Down
46 changes: 4 additions & 42 deletions abspath.c
Expand Up @@ -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;
}

/*
Expand Down
25 changes: 25 additions & 0 deletions strbuf.c
Expand Up @@ -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;
Expand Down
2 changes: 2 additions & 0 deletions strbuf.h
Expand Up @@ -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)))
Expand Down

0 comments on commit 679eebe

Please sign in to comment.