2011-06-01 63 views
5

我试图从Python的libc中通过​​调用reboot函数,我只是无法让它工作。我一直在参考man 2 reboot页(http://linux.die.net/man/2/reboot)。我的内核版本是2.6.35。python ctypes从Linux上的libc调用reboot()

下面是来自交互式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 reminder-我能得到get_errno返回22(无效参数)。不出所料。我应该怎么叫reboot()?我显然不会传递函数期望的参数。 =)

+0

运行此脚本时,您是否是root用户? – 2011-06-01 02:25:52

+0

访问被拒绝?我不知道...尝试(重新)阅读:http://linux.die.net/man/2/reboot – Manux 2011-06-01 02:26:32

+1

即使访问被拒绝,人们会期望'errno'报告'EPERM'。 – sarnold 2011-06-01 02:27:47

回答

3

尝试:

>>> libc = CDLL('libc.so.6', use_errno=True) 

这应该允许get_errno()工作。

[更新]

此外,最后一个参数是一个void *。如果这是一个64位系统,那么整数0不是NULL的有效表示。我会尝试None或者c_void_p(None)。 (不知道怎么会在这方面无所谓,虽然)。

[更新2]

显然reboot(0x1234567)的伎俩(见注释)。

+0

之前的root权利 - 它响了一下钟。谢谢 – tMC 2011-06-01 02:57:23

+0

尝试'libc.reboot(0xfee1dead,672274793,0x1234567,c_void_p(无))'仍然返回errno 22.谢谢你的想法。 (所以试图在参数周围使用'c_uint()') – tMC 2011-06-01 03:11:33

+0

你是否试过'reboot(0x1234567)'?这是我在sys/reboot.h中看到的签名... – Nemo 2011-06-01 03:19:36

2

reboot() in libc是syscall的一个包装,它只包含cmd参数。因此,尝试:

libc.reboot(0x1234567) 

注意,你通常应该通过发送SIGINT将启动重新启动以PID 1 - 告诉内核重启不会给任何系统守护进程完全关闭的机会,而且也不会同步文件系统缓存到磁盘。

+0

关于libc-的更多详细信息,谢谢。 – tMC 2011-06-01 03:49:35