Skip to content

Commit 679eebe

Browse files
rscharfegitster
authored andcommitted
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 <[email protected]> Signed-off-by: Junio C Hamano <[email protected]>
1 parent 4d3ab44 commit 679eebe

File tree

4 files changed

+37
-42
lines changed

4 files changed

+37
-42
lines changed

Documentation/technical/api-strbuf.txt

+6
Original file line numberDiff line numberDiff line change
@@ -293,6 +293,12 @@ same behaviour as well.
293293

294294
Set the buffer to the path of the current working directory.
295295

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+
296302
`stripspace`::
297303

298304
Strip whitespace from a buffer. The second parameter controls if

abspath.c

+4-42
Original file line numberDiff line numberDiff line change
@@ -140,54 +140,16 @@ const char *real_path_if_valid(const char *path)
140140
return real_path_internal(path, 0);
141141
}
142142

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-
163143
/*
164144
* Use this to get an absolute path from a relative one. If you want
165145
* 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.
169146
*/
170147
const char *absolute_path(const char *path)
171148
{
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;
191153
}
192154

193155
/*

strbuf.c

+25
Original file line numberDiff line numberDiff line change
@@ -568,6 +568,31 @@ void strbuf_humanise_bytes(struct strbuf *buf, off_t bytes)
568568
}
569569
}
570570

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+
571596
int printf_ln(const char *fmt, ...)
572597
{
573598
int ret;

strbuf.h

+2
Original file line numberDiff line numberDiff line change
@@ -179,6 +179,8 @@ extern void strbuf_addstr_urlencode(struct strbuf *, const char *,
179179
int reserved);
180180
extern void strbuf_humanise_bytes(struct strbuf *buf, off_t bytes);
181181

182+
extern void strbuf_add_absolute_path(struct strbuf *sb, const char *path);
183+
182184
__attribute__((format (printf,1,2)))
183185
extern int printf_ln(const char *fmt, ...);
184186
__attribute__((format (printf,2,3)))

0 commit comments

Comments
 (0)