diff options
author | Denys Vlasenko | 2018-05-24 17:29:14 +0200 |
---|---|---|
committer | Denys Vlasenko | 2018-05-24 17:31:00 +0200 |
commit | 747162109fb1c891baf6aafa1ca0410bd08d04a4 (patch) | |
tree | 7215b1a5b94212e207b9c3d7c1426e65c2ce0553 | |
parent | 3f91e662f21083d4febf74fa89ccc50e406cbf6c (diff) | |
download | busybox-747162109fb1c891baf6aafa1ca0410bd08d04a4.zip busybox-747162109fb1c891baf6aafa1ca0410bd08d04a4.tar.gz |
realpath,readlink -f: coreutils compat, closes 11021
function old new delta
xmalloc_realpath_coreutils - 121 +121
Signed-off-by: Denys Vlasenko <vda.linux@googlemail.com>
-rw-r--r-- | coreutils/readlink.c | 2 | ||||
-rw-r--r-- | coreutils/realpath.c | 2 | ||||
-rw-r--r-- | include/libbb.h | 1 | ||||
-rw-r--r-- | libbb/xreadlink.c | 30 |
4 files changed, 33 insertions, 2 deletions
diff --git a/coreutils/readlink.c b/coreutils/readlink.c index b8e327d..49361ce 100644 --- a/coreutils/readlink.c +++ b/coreutils/readlink.c @@ -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); } diff --git a/coreutils/realpath.c b/coreutils/realpath.c index aa878fc..4392368 100644 --- a/coreutils/realpath.c +++ b/coreutils/realpath.c @@ -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); diff --git a/include/libbb.h b/include/libbb.h index a605c7f..d4ba031 100644 --- a/include/libbb.h +++ b/include/libbb.h @@ -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 */ diff --git a/libbb/xreadlink.c b/libbb/xreadlink.c index 9b62bcc..6315033 100644 --- a/libbb/xreadlink.c +++ b/libbb/xreadlink.c @@ -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; +} |