|
11 | 11 | import com.sun.jna.Library;
|
12 | 12 | import com.sun.jna.Memory;
|
13 | 13 | import com.sun.jna.Native;
|
| 14 | +import com.sun.jna.NativeLibrary; |
14 | 15 | import com.sun.jna.NativeLong;
|
15 | 16 | import com.sun.jna.Pointer;
|
16 | 17 | import com.sun.jna.Structure;
|
@@ -143,9 +144,17 @@ private interface FXStatFunction extends Library {
|
143 | 144 | this.functions = Native.load("c", NativeFunctions.class);
|
144 | 145 | FStat64Function fstat64;
|
145 | 146 | try {
|
| 147 | + // JNA lazily finds symbols, so even though we try to bind two different functions below, if fstat64 |
| 148 | + // isn't found, we won't know until runtime when calling the function. To force resolution of the |
| 149 | + // symbol we get a function object directly from the native library. We don't use it, we just want to |
| 150 | + // see if it will throw UnsatisfiedLinkError |
| 151 | + NativeLibrary.getInstance("c").getFunction("fstat64"); |
146 | 152 | fstat64 = Native.load("c", FStat64Function.class);
|
147 | 153 | } catch (UnsatisfiedLinkError e) {
|
148 |
| - // TODO: explain |
| 154 | + // fstat has a long history in linux from the 32-bit architecture days. On some modern linux systems, |
| 155 | + // fstat64 doesn't exist as a symbol in glibc. Instead, the compiler replaces fstat64 calls with |
| 156 | + // the internal __fxstat method. Here we fall back to __fxstat, and staticall bind the special |
| 157 | + // "version" argument so that the call site looks the same as that of fstat64 |
149 | 158 | var fxstat = Native.load("c", FXStatFunction.class);
|
150 | 159 | int version = System.getProperty("os.arch").equals("aarch64") ? 0 : 1;
|
151 | 160 | fstat64 = (fd, stat) -> fxstat.__fxstat(version, fd, stat);
|
|
0 commit comments