Linux blocking signals to Python init

This is a follow up to my other post Installing signal handler with Python. In short, Linux blocks all signals to PID 1 (including SIGKILL) unless Init has installed a signal handler for a particular signal; as to prevent kernel panic if someone were to send a termination signal to PID1. The issue I've been having, is it would seem that the signal module in Python doesn't install signal handlers in a way the system recognises. My Python Init script was seemingly, completely ignoring all signals as I think they were being blocked.

I seem to have found a solution; using ctypes to install the signal handlers with the signal() function in libc (in this case uClibc). Below is a python based test init. It opens a shell on TTY2 from which I can send signals to PID1 for testing. It seems to work in the KVM im using for testing (I'm willing to share the VM with anyone interested)

Is this the best way around this issue? Is there a 'better' way to install the signal handlers without the signal module? (I am not at all concerned with portably)

Is this a bug in 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)

9
задан Community 23 May 2017 в 02:29
поделиться