1 // Define Py_NSIG constant for signal handling. 2 3 #ifndef Py_INTERNAL_SIGNAL_H 4 #define Py_INTERNAL_SIGNAL_H 5 #ifdef __cplusplus 6 extern "C" { 7 #endif 8 9 #ifndef Py_BUILD_CORE 10 # error "this header requires Py_BUILD_CORE define" 11 #endif 12 13 #include <signal.h> // NSIG 14 15 16 // Restore signals that the interpreter has called SIG_IGN on to SIG_DFL. 17 // Export for '_posixsubprocess' shared extension. 18 PyAPI_FUNC(void) _Py_RestoreSignals(void); 19 20 #ifdef _SIG_MAXSIG 21 // gh-91145: On FreeBSD, <signal.h> defines NSIG as 32: it doesn't include 22 // realtime signals: [SIGRTMIN,SIGRTMAX]. Use _SIG_MAXSIG instead. For 23 // example on x86-64 FreeBSD 13, SIGRTMAX is 126 and _SIG_MAXSIG is 128. 24 # define Py_NSIG _SIG_MAXSIG 25 #elif defined(NSIG) 26 # define Py_NSIG NSIG 27 #elif defined(_NSIG) 28 # define Py_NSIG _NSIG // BSD/SysV 29 #elif defined(_SIGMAX) 30 # define Py_NSIG (_SIGMAX + 1) // QNX 31 #elif defined(SIGMAX) 32 # define Py_NSIG (SIGMAX + 1) // djgpp 33 #else 34 # define Py_NSIG 64 // Use a reasonable default value 35 #endif 36 37 #define INVALID_FD (-1) 38 39 struct _signals_runtime_state { 40 struct { 41 // tripped and func should be accessed using atomic ops. 42 int tripped; 43 PyObject* func; 44 } handlers[Py_NSIG]; 45 46 volatile struct { 47 #ifdef MS_WINDOWS 48 /* This would be "SOCKET fd" if <winsock2.h> were always included. 49 It isn't so we must cast to SOCKET where appropriate. */ 50 volatile int fd; 51 #elif defined(__VXWORKS__) 52 int fd; 53 #else 54 sig_atomic_t fd; 55 #endif 56 57 int warn_on_full_buffer; 58 #ifdef MS_WINDOWS 59 int use_send; 60 #endif 61 } wakeup; 62 63 /* Speed up sigcheck() when none tripped. 64 is_tripped should be accessed using atomic ops. */ 65 int is_tripped; 66 67 /* These objects necessarily belong to the main interpreter. */ 68 PyObject *default_handler; 69 PyObject *ignore_handler; 70 71 #ifdef MS_WINDOWS 72 /* This would be "HANDLE sigint_event" if <windows.h> were always included. 73 It isn't so we must cast to HANDLE everywhere "sigint_event" is used. */ 74 void *sigint_event; 75 #endif 76 77 /* True if the main interpreter thread exited due to an unhandled 78 * KeyboardInterrupt exception, suggesting the user pressed ^C. */ 79 int unhandled_keyboard_interrupt; 80 }; 81 82 #ifdef MS_WINDOWS 83 # define _signals_WAKEUP_INIT \ 84 {.fd = INVALID_FD, .warn_on_full_buffer = 1, .use_send = 0} 85 #else 86 # define _signals_WAKEUP_INIT \ 87 {.fd = INVALID_FD, .warn_on_full_buffer = 1} 88 #endif 89 90 #define _signals_RUNTIME_INIT \ 91 { \ 92 .wakeup = _signals_WAKEUP_INIT, \ 93 } 94 95 96 // Export for '_multiprocessing' shared extension 97 PyAPI_FUNC(int) _PyOS_IsMainThread(void); 98 99 #ifdef MS_WINDOWS 100 // <windows.h> is not included by Python.h so use void* instead of HANDLE. 101 // Export for '_multiprocessing' shared extension 102 PyAPI_FUNC(void*) _PyOS_SigintEvent(void); 103 #endif 104 105 #ifdef __cplusplus 106 } 107 #endif 108 #endif // !Py_INTERNAL_SIGNAL_H 109