← Commit list

747162109

Denys Vlasenko
Denys Vlasenko
2018-05-24
SUCCESS Duration: 145s

Subject

realpath,readlink -f: coreutils compat, closes 11021

Binary

No binary (build failed)

Architecture & Compiler Flags

Architecture: x86_64-linux-gnu Compiler: gcc (Ubuntu 11.4.0-1ubuntu1~22.04.3) 11.4.0

—

Build Log

(log yok)

Commit Diff GitHub →

coreutils/readlink.c+1 -1
@@ -86,7 +86,7 @@ int readlink_main(int argc UNUSED_PARAM, char **argv)
/* NOFORK: only one alloc is allowed; must free */
if (opt & 1) { /* -f */
- buf = xmalloc_realpath(fname);
+ buf = xmalloc_realpath_coreutils(fname);
} else {
buf = xmalloc_readlink_or_warn(fname);
}
coreutils/realpath.c+1 -1
@@ -38,7 +38,7 @@ int realpath_main(int argc UNUSED_PARAM, char **argv)
do {
/* NOFORK: only one alloc is allowed; must free */
- char *resolved_path = xmalloc_realpath(*argv);
+ char *resolved_path = xmalloc_realpath_coreutils(*argv);
if (resolved_path != NULL) {
puts(resolved_path);
free(resolved_path);
include/libbb.h+1 -0
@@ -485,6 +485,7 @@ DIR *xopendir(const char *path) FAST_FUNC;
DIR *warn_opendir(const char *path) FAST_FUNC;
char *xmalloc_realpath(const char *path) FAST_FUNC RETURNS_MALLOC;
+char *xmalloc_realpath_coreutils(const char *path) FAST_FUNC RETURNS_MALLOC;
char *xmalloc_readlink(const char *path) FAST_FUNC RETURNS_MALLOC;
char *xmalloc_readlink_or_warn(const char *path) FAST_FUNC RETURNS_MALLOC;
/* !RETURNS_MALLOC: it's a realloc-like function */
libbb/xreadlink.c+30 -0
@@ -122,3 +122,33 @@ char* FAST_FUNC xmalloc_realpath(const char *path)
return xstrdup(realpath(path, buf));
#endif
}
+
+char* FAST_FUNC xmalloc_realpath_coreutils(const char *path)
+{
+ char *buf;
+
+ errno = 0;
+ buf = xmalloc_realpath(path);
+ /*
+ * There is one case when "readlink -f" and
+ * "realpath" from coreutils succeed,
+ * even though file does not exist, such as:
+ * /tmp/file_does_not_exist
+ * (the directory must exist).
+ */
+ if (!buf && errno == ENOENT) {
+ char *last_slash = strrchr(path, '/');
+ if (last_slash) {
+ *last_slash++ = '\0';
+ buf = xmalloc_realpath(path);
+ if (buf) {
+ unsigned len = strlen(buf);
+ buf = xrealloc(buf, len + strlen(last_slash) + 2);
+ buf[len++] = '/';
+ strcpy(buf + len, last_slash);
+ }
+ }
+ }
+
+ return buf;
+}