【发布时间】:2011-08-16 04:57:44
【问题描述】:
这是对我的另一篇帖子Installing signal handler with Python 的跟进。简而言之,除非 Init 为特定信号安装了信号处理程序,否则 Linux 会阻止所有到 PID 1 的信号(包括 SIGKILL);如果有人要向 PID1 发送终止信号,以防止内核恐慌。我遇到的问题是,Python 中的 signal 模块似乎没有以系统识别的方式安装信号处理程序。我的 Python Init 脚本似乎完全忽略了所有信号,因为我认为它们被阻止了。
我似乎找到了解决办法;使用ctypes 在libc(在本例中为uClibc)中安装带有signal() 函数的信号处理程序。下面是一个基于 python 的测试初始化。它在 TTY2 上打开一个 shell,我可以从中向 PID1 发送信号进行测试。它似乎在用于测试的 KVM 中工作(我愿意与任何感兴趣的人共享 VM)
这是解决此问题的最佳方法吗?有没有“更好”的方法来安装没有信号模块的信号处理程序? (我根本不关心便携)
这是 Python 中的错误吗?
#!/usr/bin/python
import os
import sys
import time
from ctypes import *
def SigHUP():
print "Caught SIGHUP"
return 0
def SigCHLD():
print "Caught SIGCHLD"
return 0
SIGFUNC = CFUNCTYPE(c_int)
SigHUPFunc = SIGFUNC(SigHUP)
SigCHLDFunc = SIGFUNC(SigCHLD)
libc = cdll.LoadLibrary('libc.so.0')
libc.signal(1, SigHUPFunc) # 1 = SIGHUP
libc.signal(17, SigCHLDFunc) # 17 = SIGCHLD
print "Mounting Proc: %s" % libc.mount(None, "/proc", "proc", 0, None)
print "forking for ash"
cpid = os.fork()
if cpid == 0:
os.closerange(0, 4)
sys.stdin = open('/dev/tty2', 'r')
sys.stdout = open('/dev/tty2', 'w')
sys.stderr = open('/dev/tty2', 'w')
os.execv('/bin/ash', ('ash',))
print "ash started on tty2"
print "sleeping"
while True:
time.sleep(0.01)
【问题讨论】:
-
这确实属于 codereview.SE,但 +1 是为了在 Python 中实现
init的酷想法。 -
我认为这可能是我应该发布的地方,但我没有设置这种方法,并且认为可能有很多我没有想到的想法。
标签: python c linux signals init