• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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