nologin: make it possible to build it as single applet
[oweals/busybox.git] / libbb / xreadlink.c
index 6315033bb02a317bff73fb14ec7cc1aadf9ade08..a18dd0748dd1793f16bce6eead9c5b3e34860930 100644 (file)
@@ -143,10 +143,39 @@ char* FAST_FUNC xmalloc_realpath_coreutils(const char *path)
                        buf = xmalloc_realpath(path);
                        if (buf) {
                                unsigned len = strlen(buf);
-                                buf = xrealloc(buf, len + strlen(last_slash) + 2);
+                               buf = xrealloc(buf, len + strlen(last_slash) + 2);
                                buf[len++] = '/';
                                strcpy(buf + len, last_slash);
                        }
+               } else {
+                       char *target = xmalloc_readlink(path);
+                       if (target) {
+                               char *cwd;
+                               if (target[0] == '/') {
+                                       /*
+                                        * $ ln -s /bin/qwe symlink  # note: /bin is a link to /usr/bin
+                                        * $ readlink -f symlink
+                                        * /usr/bin/qwe/target_does_not_exist
+                                        * $ realpath symlink
+                                        * /usr/bin/qwe/target_does_not_exist
+                                        */
+                                       buf = xmalloc_realpath_coreutils(target);
+                                       free(target);
+                                       return buf;
+                               }
+                               /*
+                                * $ ln -s target_does_not_exist symlink
+                                * $ readlink -f symlink
+                                * /CURDIR/target_does_not_exist
+                                * $ realpath symlink
+                                * /CURDIR/target_does_not_exist
+                                */
+                               cwd = xrealloc_getcwd_or_warn(NULL);
+                               buf = concat_path_file(cwd, target);
+                               free(cwd);
+                               free(target);
+                               return buf;
+                       }
                }
        }