【问题标题】:Python ctypes calling reboot() from libc on LinuxPython ctypes 在 Linux 上从 libc 调用 reboot()
【发布时间】:2011-06-01 02:21:32
【问题描述】:

我试图通过 ctypes 从 Python 中的 libc 调用 reboot 函数,但我无法让它工作。我一直在引用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()?我显然没有传递函数期望的参数。 =)

【问题讨论】:

  • 运行这个脚本时你是root吗?
  • 访问被拒绝?我不知道...尝试(重新)阅读此内容:linux.die.net/man/2/reboot
  • 即使访问被拒绝,人们也会期望errno 报告EPERM
  • 是的,在启动 python 交互式提示之前我是 root

标签: python c linux ctypes libc


【解决方案1】:

试试:

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

这应该允许get_errno() 工作。

[更新]

另外,最后一个参数是void *。如果这是 64 位系统,则整数 0 不是 NULL 的有效表示。我会尝试None 或者c_void_p(None)。 (不过,不确定这在这种情况下有何影响。)

[更新 2]

显然reboot(0x1234567) 可以解决问题(参见 cmets)。

【讨论】:

  • 尝试 libc.reboot(0xfee1dead, 672274793, 0x1234567, c_void_p(None)) 仍然返回 errno 22。不过感谢您的想法。 (尝试在 args 周围使用 c_uint() 也是如此)
  • 你试过reboot(0x1234567)吗?这是我在 sys/reboot.h 中看到的签名...
  • 我以为我有,但我想没有——这似乎可以解决问题。也许更新答案?
【解决方案2】:

libc 中的reboot() 是系统调用的包装器,它只接受cmd 参数。所以试试:

libc.reboot(0x1234567)

请注意,您通常应该通过向 PID 1 发送 SIGINT 来启动重新启动 - 告诉内核重新启动不会给任何系统守护进程干净关闭的机会,甚至不会将文件系统缓存同步到磁盘.

【讨论】:

    猜你喜欢
    • 2011-09-07
    • 2011-04-03
    • 2011-06-16
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2023-03-27
    相关资源
    最近更新 更多