Signals – that’s a great rock album, and it’s also how you talk to processes in flight on your computer. When you hit control-C, what you’ve done is send a smoke signal called SIGINT to the process your console session is attached to.
Sometimes that’s good, sometimes you want to handle what happens on receipt of a signal.
There are 64 signals available on Linux systems. If you’re not using Linux, it’s OK. You can. Just upgrade. You’ll thank me.
All of those signals have default actions and you can substitute your own handling for any of them.
Except signal 9, SIGKILL. To paraphrase Arthur C. Clarke. All these signals are yours – except SIGKILL. Attempt no intercepts there.
Seriously. The OS always handles SIGKILL. All the others, though, clay on the potter’s wheel.
Python supplies a nice module, signal, that does pretty much what’s needed, but in industrial packaging. Works great, doesn’t win beauty contests.
That’s why I wrote signals.py (note the plural to differentiate it from Python’s signal library). There are many support libraries for signals, but if you want easy (and easy to debug), then signals might be what you need.
Signals lets you set a handler with options to automatically restore the handler to its previous state or to chain to the previous handler after running a cleanup function of your choosing.
For instance, if you have a function called gracefulShutdown that you want to run on control-C, after which you want the process to terminate, this will do what you need in just one line of code:
handler = SigIntercept(cleanup = gracefulShutdown, chainSig = True)
Since SigIntercept defaults to control-C, that’s all that’s needed. After that line executes, control-C will divert through gracefulShutdown and then behave exactly like control-C did before – which could have been diverted by a previous SigIntecept, too, if you wanted to do such a thing.