Real path of soft links with missing target

maxxedev at gmail.com maxxedev at gmail.com
Wed Jul 20 17:16:50 UTC 2022


Hi,

How can one resolve the real path of a soft link where the target file
does not exist?

For example, given:
    $ ln -s foo-target foo-source

then this code throws an exception:
    Paths.get("foo-source").toRealPath();

    Exception in thread "main" java.nio.file.NoSuchFileException: foo-source
        at java.base/sun.nio.fs.UnixException.translateToIOException(UnixException.java:92)
        at java.base/sun.nio.fs.UnixException.rethrowAsIOException(UnixException.java:111)
        at java.base/sun.nio.fs.UnixException.rethrowAsIOException(UnixException.java:116)
        at java.base/sun.nio.fs.UnixPath.toRealPath(UnixPath.java:860)
        at App.main(App.java:33)

The underlying native code[1] reads like this:
    if (realpath(path, resolved) == NULL) {
        throwUnixException(env, errno);
    }

However, it appears that realpath() does save the result in "resolved"
argument even when the return value is null:
    #include <limits.h>
    #include <stdlib.h>
    #include <stdio.h>
    #include <errno.h>

    int main(int argc, char** argv) {
        char* path = "foo-source";
        char resolved[PATH_MAX + 1] = {0};
        char* result = realpath(path, resolved);
        printf("%d\n", result == NULL);  // 1
        printf("%d\n", errno == ENOENT); // 1
        printf("%s\n", resolved);   // "foo-target"
        return 0;
    }

Would it be possible to expose that behavior in Java, perhaps with a
new LinkOption value to Path::toRealPath? Note though that realpath()
specification[2] says the content of "resolved" argument is undefined
if return value is null.

Thanks

[1] https://github.com/openjdk/jdk/blob/jdk-20%2B6/src/java.base/unix/native/libnio/fs/UnixNativeDispatcher.c#L965-L966
[2] https://pubs.opengroup.org/onlinepubs/009696799/functions/realpath.html


More information about the nio-dev mailing list