Better exit cleanup handling

Catching individual signals is more robust than using the `atexit` module.