I'm trying to call the reboot
function from libc in Python via ctypes
and I just can not get it to work. I've been referencing the man 2 reboot
page (http://linux.die.net/man/2/reboot). My kernel version is 2.6.35.
Below is the console log from the interactive Python prompt where I'm trying to get my machine to reboot- what am I doing wrong?
Why isn't ctypes.get_errno()
working?
>>> from ctypes import CDLL, get_errno
>>> libc = CDLL('libc.so.6')
>>> libc.reboot(0xfee1dead, 537993216, 0x1234567, 0)
-1
>>> get_errno()
0
>>> libc.reboot(0xfee1dead, 537993216, 0x1234567)
-1
>>> get_errno()
0
>>> from ctypes import c_uint32
>>> libc.reboot(c_uint32(0xfee1dead), c_uint32(672274793), c_uint32(0x1234567), c_uint32(0))
-1
>>> get_errno()
0
>>> libc.reboot(c_uint32(0xfee1dead), c_uint32(672274793), c_uint32(0x1234567))
-1
>>> get_errno()
0
>>>
Edit:
Via Nemos reminder- I can get get_errno
to return 22 (invalid argument). Not a surprise. How should I be calling reboot()
? I'm clearly not passing arguments the function expects. =)
Try:
>>> libc = CDLL('libc.so.6', use_errno=True)
That should allow get_errno()
to work.
[update]
Also, the last argument is a void *
. If this is a 64-bit system, then the integer 0 is not a valid repesentation for NULL. I would try None
or maybe c_void_p(None)
. (Not sure how that could matter in this context, though.)
[update 2]
Apparently reboot(0x1234567)
does the trick (see comments).
The reboot()
in libc
is a wrapper around the syscall, which only takes the cmd
argument. So try:
libc.reboot(0x1234567)
Note that you should normally be initiating a reboot by sending SIGINT
to PID 1 - telling the kernel to reboot will not give any system daemons the chance to shut down cleanly, and won't even sync the filesystem cache to disk.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With