Search code examples
javalinuxjnadbus

How to shutdown/reboot linux machine programatically without using commands(Runtime)


In Windows, it is possible to shutdown a machine through a java program by natively(JNA) calling a ExitWindowsEx function in Windows API. I am looking for something similar in linux. I know this can be done by executing commands but then I cannot rely on parsing the human-readable text.

Is IPC(DBus) the only way to do this or is it possible to load some library natively and the call the shutdown method natively. If there is a simpler way to do it please do let me know.

Using JNA or similar to shutdown and restart computer in linux and mac

I looked at this question earlier but it does not provide an answer as to how to do it programmatically.


Solution

  • So I managed to find the solution on my own after I did some research online. There is a library called JNA(Java Native Access) that lets you load libraries natively and resolves and dependencies. Using JNA I loaded the POSIX library on java through an interface. Running your code as sudo will let you shut down or reboot the machine. Here is the code.

    import com.sun.jna.Library;
    import com.sun.jna.Native;
    import com.sun.jna.Platform;
    import com.sun.jna.ptr.IntByReference;
    
    public interface CLibrary extends Library {
    public CLibrary INSTANCE = (CLibrary) Native.loadLibrary(Platform.isWindows()?"msvcrt":"c",CLibrary.class);
    
    int kill(long pid, int sig);
    int reboot(int magic, int magic2, int cmd, IntByReference arg);
    int reboot(int cmd);
    
    int LINUX_REBOOT_MAGIC1 = 0xfee1dead;
    int LINUX_REBOOT_MAGIC2 = 672274793;
    int LINUX_REBOOT_MAGIC2A = 85072278;
    int LINUX_REBOOT_MAGIC2B = 369367448;
    int LINUX_REBOOT_MAGIC2C = 537993216;
    
    int LINUX_REBOOT_CMD_RESTART = 0x01234567;
    int LINUX_REBOOT_CMD_HALT = 0xCDEF0123;
    int LINUX_REBOOT_CMD_CAD_ON =0x89ABCDEF;
    int LINUX_REBOOT_CMD_CAD_OFF = 0x00000000;
    int LINUX_REBOOT_CMD_POWER_OFF = 0x4321FEDC;
    int LINUX_REBOOT_CMD_RESTART2 = 0xA1B2C3D4;
    int LINUX_REBOOT_CMD_SW_SUSPEND = 0xD000FCE2;
    int LINUX_REBOOT_CMD_KEXEC = 0x45584543;
    
    }
    
    p s v main(){
       CLibrary.INSTANCE.reboot(Clibrary.LINUX_REBOOT_CMD_POWER_OFF);
    }
    

    Note: This works only on Linux and not on Windows. To shutdown a machine programmatically look for ExitWindowsEx. Built into the JNA library.

    All C POSIX headers files can be found C POSIX Library - Wikipedia