Obtain the native value of errno from Java in macOS

Viewed 15

I'm porting my JNA-based library to "pure" Java using the Foreign Function and Memory API (JEP 424) in JDK 19.

I've successfully implemented the sysctl() function and am fetching values using:

public static MethodHandle sysctl = Linker.nativeLinker().downcallHandle(
        SYSTEM_LIBRARY.lookup("sysctl").orElseThrow(), FunctionDescriptor.of(ValueLayout.JAVA_INT,
                ValueLayout.ADDRESS, ValueLayout.JAVA_INT, ValueLayout.ADDRESS, ValueLayout.ADDRESS,
                ValueLayout.ADDRESS, ValueLayout.JAVA_LONG));

In the process of debugging before getting this working, I was occasionally getting a -1 return value:

Upon successful completion, the value 0 is returned; otherwise the value -1 is returned and the global variable errno is set to indicate the error.

In JNA, this is easily obtainable using Native.getLastError(). This answer shows how I could write code in JNI to fetch it, but the whole point of JEP 424 is to remove the need for JNA or JNI.

The Windows API has a helpful GetLastError function that can be mapped, as demonstrated in this test in the JDK

However, I was unable to find any native function on macOS that I could map to return errno. The closest I have found is perror() which prints the error to STDERR:

public static MethodHandle perror = Linker.nativeLinker()
        .downcallHandle(SYSTEM_LIBRARY.lookup("perror").orElseThrow(),
                FunctionDescriptor.of(ValueLayout.ADDRESS, ValueLayout.ADDRESS));

While output to STDERR was helpful in the near term, I'd like to use this value for exception handling/error messages.

This seems a common enough use case that there should be a method in the JDK for it, but I can't find it.

Any ideas other than temporarily redirecting STDERR into a string I can parse?

0 Answers
Related