问题
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. =)
回答1:
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).
回答2:
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.
来源:https://stackoverflow.com/questions/6195575/python-ctypes-calling-reboot-from-libc-on-linux