tags:

views:

222

answers:

2

Is there a way to map a signal number (e.g. signal.SIGINT) to its respective name (i.e. "SIGINT")?

I'd like to be able to print the name of a signal in the log when I receive it, however I cannot find a map from signal numbers to names in Python, i.e.

import signal
def signal_handler(signum, frame):
    logging.debug("Received signal (%s)" % sig_names[signum])

signal.signal(signal.SIGINT, signal_handler)

For some dictionary sig_names, so when the process receives SIGINT it prints:

 Received signal (SIGINT)

Thank you.

+2  A: 

There is none, but if you don't mind a little hack, you can generate it like this:

import signal
dict((k, v) for v, k in signal.__dict__.iteritems() if v.startswith('SIG'))
WoLpH
Strictly speaking this will map 1 to `SIG_IGN` and `SIGHUP` on most platforms, so I suppose the test should be if `v.startswith('SIG') and not v.startswith('SIG_')`.
Brian M. Hunt
It also double-maps 6 to `SIGABRT` and `SIGIOT` on Mac OS X (though they could be used interchangeably, I suppose, unlike `SIG_IGN` - which isn't a signal).
Brian M. Hunt
@Brian: very true... it's not a perfect solution by far. But it's atleast somewhat platform independent.
WoLpH
+2  A: 

Well, help(signal) says at the bottom:

DATA
    NSIG = 23
    SIGABRT = 22
    SIGBREAK = 21
    SIGFPE = 8
    SIGILL = 4
    SIGINT = 2
    SIGSEGV = 11
    SIGTERM = 15
    SIG_DFL = 0
    SIG_IGN = 1

So this should work:

sig_names = {23:"NSIG", 22:"SIGABRT", 21:"SIGBREAK", 8:"SIGFPE", 4:"SIGILL",
             2:"SIGINT", 11:"SIGSEGV", 15:"SIGTERM", 0:"SIG_DFL", 1:"SIG_IGN"}
Daniel G
Unfortunately different platforms have different signal numbers, so this isn't portable. Thanks, though.
Brian M. Hunt
For example, here's the Mac OS X `help(signal)`: SIGABRT = 6 SIGALRM = 14 SIGBUS = 10 SIGCHLD = 20 SIGCONT = 19 SIGEMT = 7 SIGFPE = 8 SIGHUP = 1 SIGILL = 4 SIGINFO = 29 SIGINT = 2 SIGIO = 23 SIGIOT = 6 SIGKILL = 9 SIGPIPE = 13 SIGPROF = 27 SIGQUIT = 3 SIGSEGV = 11 SIGSTOP = 17 SIGSYS = 12 SIGTERM = 15 SIGTRAP = 5 SIGTSTP = 18 SIGTTIN = 21 SIGTTOU = 22 SIGURG = 16 SIGUSR1 = 30 SIGUSR2 = 31 SIGVTALRM = 26 SIGWINCH = 28 SIGXCPU = 24 SIGXFSZ = 25
Brian M. Hunt
Ah - I really should have realized that, all things considered, especially since I've experienced how much different signals are on Windows and Linux. WoLpH's solution is cleaner anyway :)
Daniel G
@Daniel G: I wouldn't say my solution is cleaner. Yes, it works on every platform but if your solution is an option, than I'd definately use it and use my version as a fallback.
WoLpH