17

Is there a way to invoke syscalls directly from Java, or is it necessary to first call a native method?

Michael Mrozek
  • 91,316
  • 38
  • 238
  • 232
santiago.basulto
  • 395
  • 1
  • 3
  • 8

2 Answers2

19

You need to use a native method, but you don't need to implement it yourself. Java has a variation on JNI called JNA (Java Native Access), which lets you access shared libraries directly without needing a JNI interface wrapped around them, so you can use that to interface directly with glibc:

import com.sun.jna.Library;
import com.sun.jna.Native;

public class Test {
    public interface CStdLib extends Library {
        int syscall(int number, Object... args);
    }

    public static void main(String[] args) {
        CStdLib c = (CStdLib)Native.loadLibrary("c", CStdLib.class);

        // WARNING: These syscall numbers are for x86 only
        System.out.println("PID: " + c.syscall(20));
        System.out.println("UID: " + c.syscall(24));
        System.out.println("GID: " + c.syscall(47));
        c.syscall(39, "/tmp/create-new-directory-here");
    }
}
John Hascall
  • 287
  • 1
  • 14
Michael Mrozek
  • 91,316
  • 38
  • 238
  • 232
  • interesting, is it possible to use function names instead of numbers? – maxschlepzig Sep 06 '10 at 20:43
  • 2
    @max In the `syscall` interface? No, `syscall` takes an integer to represent the appropriate call to make, just like on the C side. There are a bunch of `#define` s in `/usr/include/asm/unistd.h`, like `#define __NR_mkdir 39` to make it easier for people calling the C function, but I don't think there's any way to automatically import those into Java, you'd have to define them all yourself – Michael Mrozek Sep 06 '10 at 20:55
  • 2
    Please beware - the numbers on x86 and x86-64 are different on Linux. – Maciej Piechotka Sep 06 '10 at 21:00
  • @Maciej Good point, added a warning in the answer – Michael Mrozek Sep 06 '10 at 21:14
  • Great Answer brother! Thanks for your help. From here i have another question. I'll ask it in a minute. – santiago.basulto Sep 07 '10 at 00:54
2

It is necessary to use a native method, or a library that does so for you.

bmargulies
  • 421
  • 1
  • 5
  • 16