realpath,readlink -f: coreutils compat, closes 11021
authorDenys Vlasenko <vda.linux@googlemail.com>
Thu, 24 May 2018 15:29:14 +0000 (17:29 +0200)
committerDenys Vlasenko <vda.linux@googlemail.com>
Thu, 24 May 2018 15:31:00 +0000 (17:31 +0200)
function                                             old     new   delta
xmalloc_realpath_coreutils                             -     121    +121

Signed-off-by: Denys Vlasenko <vda.linux@googlemail.com>
coreutils/readlink.c
coreutils/realpath.c
include/libbb.h
libbb/xreadlink.c

index b8e327d11863fcd5025b0dc26d06f91d9cedae32..49361cea03a899e3f6178829298f516c48915069 100644 (file)
@@ -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);
        }
index aa878fcd2e7258af5a9e2bc3f345f3f060c5bfba..43923681c434151111d980e63e4e4b1f9249ae41 100644 (file)
@@ -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);
index a605c7f03f7c5cbd2ae64e934168fbd3875b74dc..d4ba031dfe129dcd6f877235a82ca185e0066547 100644 (file)
@@ -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 */
index 9b62bcc4317ccd1ebec401ab3937e44d7b3a079a..6315033bb02a317bff73fb14ec7cc1aadf9ade08 100644 (file)
@@ -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;
+}