我试图通过reboot
从Python中调用libc中的ctypes
函数,但我无法让它工作。我一直在引用man 2 reboot
页面(http://linux.die.net/man/2/reboot)。我的内核版本是2.6.35。
下面是来自交互式Python提示的控制台日志,我试图让我的机器重启 - 我做错了什么?
为什么ctypes.get_errno()
没有工作?
>>> 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
>>>
修改
通过Nemos提醒 - 我可以让get_errno
返回22(无效参数)。不足为奇。我该怎么称呼reboot()
?我显然没有传递函数期望的参数。 =)
答案 0 :(得分:3)
尝试:
>>> libc = CDLL('libc.so.6', use_errno=True)
这应该允许get_errno()
工作。
[更新]
此外,最后一个参数是void *
。如果这是64位系统,则整数0不是NULL的有效重复。我会尝试None
或c_void_p(None)
。 (不知道在这种情况下这可能是多么重要。)
[更新2]
显然reboot(0x1234567)
可以解决问题(见评论)。
答案 1 :(得分:2)
reboot()
中的libc
是系统调用的包装器,只接受cmd
参数。所以试试:
libc.reboot(0x1234567)
请注意,您通常应该通过将SIGINT
发送到PID 1来启动重新启动 - 告诉内核重新启动不会让任何系统守护程序有机会干净地关闭,甚至不会同步文件系统缓存到磁盘。