2011-06-01 82 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