-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathsignal_handler.py
71 lines (55 loc) · 2.11 KB
/
signal_handler.py
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
#!/usr/bin/env python3
# -*- coding: utf-8 -*-
"""
signal_handler.py - Utility for gracefully handling keyboard interrupts
This module provides a signal handler for CTRL+C interrupts that ensures
the program exits cleanly with a proper message instead of showing
a traceback, which can be confusing for users.
Author: Jonathan Care <jonc@lacunae.org>
"""
import os
import sys
import signal
import time
# Flag to track if we're in the process of handling an interrupt
_interrupt_in_progress = False
def _handle_interrupt(signum, frame):
"""
Signal handler for keyboard interrupts (CTRL+C).
Args:
signum: Signal number
frame: Current stack frame
"""
global _interrupt_in_progress
# Avoid handling the signal twice
if _interrupt_in_progress:
# If the user is really insistent by pressing CTRL+C multiple times,
# exit immediately without cleanup
print("\n\n! Received multiple interrupts. Exiting immediately.")
sys.exit(130) # Standard exit code for SIGINT
_interrupt_in_progress = True
print("\n\n! Operation interrupted by user. Cleaning up and exiting...")
# Wait a brief moment to allow any current I/O operations to complete
time.sleep(0.5)
# Exit with the appropriate exit code for SIGINT
sys.exit(130)
def setup_interrupt_handling():
"""
Set up the handler for CTRL+C interrupts.
Call this at the beginning of the main program.
"""
signal.signal(signal.SIGINT, _handle_interrupt)
# Also handle SIGTERM (sent by some process managers)
signal.signal(signal.SIGTERM, _handle_interrupt)
print("Signal handlers registered. Press CTRL+C at any time to stop safely.")
def register_cleanup_function(cleanup_func):
"""
Register a cleanup function to be called before exiting.
Args:
cleanup_func: Function to be called for cleanup before exit
"""
# Python's atexit module provides a cleaner way to handle exit cleanup
# than trying to implement it in the signal handler
import atexit
atexit.register(cleanup_func)
return cleanup_func