Coverage Report

Created: 2025-10-10 06:33

next uncovered line (L), next uncovered region (R), next uncovered branch (B)
/src/cpython/Modules/signalmodule.c
Line
Count
Source
1
2
/* Signal module -- many thanks to Lance Ellinghaus */
3
4
/* XXX Signals should be recorded per thread, now we have thread state. */
5
6
#include "Python.h"
7
#include "pycore_call.h"          // _PyObject_Call()
8
#include "pycore_ceval.h"         // _PyEval_SignalReceived()
9
#include "pycore_emscripten_signal.h"  // _Py_CHECK_EMSCRIPTEN_SIGNALS
10
#include "pycore_fileutils.h"     // _Py_BEGIN_SUPPRESS_IPH
11
#include "pycore_interpframe.h"   // _PyThreadState_GetFrame()
12
#include "pycore_moduleobject.h"  // _PyModule_GetState()
13
#include "pycore_pyerrors.h"      // _PyErr_SetString()
14
#include "pycore_pystate.h"       // _PyThreadState_GET()
15
#include "pycore_signal.h"        // _Py_RestoreSignals()
16
#include "pycore_time.h"          // _PyTime_FromSecondsObject()
17
18
#ifndef MS_WINDOWS
19
#  include "posixmodule.h"        // _PyLong_FromUid()
20
#endif
21
#ifdef MS_WINDOWS
22
#  include "socketmodule.h"       // SOCKET_T
23
#endif
24
25
#ifdef HAVE_UNISTD_H
26
#  include <unistd.h>             // alarm()
27
#endif
28
#ifdef MS_WINDOWS
29
#  ifdef HAVE_PROCESS_H
30
#    include <process.h>
31
#  endif
32
#endif
33
34
#ifdef HAVE_SIGNAL_H
35
#  include <signal.h>             // sigaction()
36
#endif
37
#ifdef HAVE_SYS_SYSCALL_H
38
#  include <sys/syscall.h>        // __NR_pidfd_send_signal
39
#endif
40
#ifdef HAVE_SYS_STAT_H
41
#  include <sys/stat.h>
42
#endif
43
#ifdef HAVE_SYS_TIME_H
44
#  include <sys/time.h>           // setitimer()
45
#endif
46
47
#if defined(HAVE_PTHREAD_SIGMASK) && !defined(HAVE_BROKEN_PTHREAD_SIGMASK)
48
#  define PYPTHREAD_SIGMASK
49
#endif
50
51
#if defined(PYPTHREAD_SIGMASK) && defined(HAVE_PTHREAD_H)
52
#  include <pthread.h>
53
#endif
54
55
#ifndef SIG_ERR
56
#  define SIG_ERR ((PyOS_sighandler_t)(-1))
57
#endif
58
59
#include "clinic/signalmodule.c.h"
60
61
/*[clinic input]
62
module signal
63
[clinic start generated code]*/
64
/*[clinic end generated code: output=da39a3ee5e6b4b0d input=b0301a3bde5fe9d3]*/
65
66
#ifdef HAVE_SETSIG_T
67
68
/*[python input]
69
70
class sigset_t_converter(CConverter):
71
    type = 'sigset_t'
72
    converter = '_Py_Sigset_Converter'
73
74
[python start generated code]*/
75
/*[python end generated code: output=da39a3ee5e6b4b0d input=b5689d14466b6823]*/
76
#endif
77
78
/*
79
   NOTES ON THE INTERACTION BETWEEN SIGNALS AND THREADS
80
81
   We want the following semantics:
82
83
   - only the main thread can set a signal handler
84
   - only the main thread runs the signal handler
85
   - signals can be delivered to any thread
86
   - any thread can get a signal handler
87
88
   I.e. we don't support "synchronous signals" like SIGFPE (catching
89
   this doesn't make much sense in Python anyway) nor do we support
90
   signals as a means of inter-thread communication, since not all
91
   thread implementations support that (at least our thread library
92
   doesn't).
93
94
   We still have the problem that in some implementations signals
95
   generated by the keyboard (e.g. SIGINT) are delivered to all
96
   threads (e.g. SGI), while in others (e.g. Solaris) such signals are
97
   delivered to one random thread. On Linux, signals are delivered to
98
   the main thread (unless the main thread is blocking the signal, for
99
   example because it's already handling the same signal).  Since we
100
   allow signals to be delivered to any thread, this works fine. The
101
   only oddity is that the thread executing the Python signal handler
102
   may not be the thread that received the signal.
103
*/
104
105
3.10k
#define Handlers _PyRuntime.signals.handlers
106
0
#define wakeup _PyRuntime.signals.wakeup
107
62.7M
#define is_tripped _PyRuntime.signals.is_tripped
108
109
// State shared by all Python interpreters
110
typedef struct _signals_runtime_state signal_state_t;
111
32
#define signal_global_state _PyRuntime.signals
112
113
#if defined(HAVE_GETITIMER) || defined(HAVE_SETITIMER)
114
#  define PYHAVE_ITIMER_ERROR
115
#endif
116
117
typedef struct {
118
    PyObject *default_handler;  // borrowed ref (signal_global_state)
119
    PyObject *ignore_handler;  // borrowed ref (signal_global_state)
120
#ifdef PYHAVE_ITIMER_ERROR
121
    PyObject *itimer_error;
122
#endif
123
    PyTypeObject *siginfo_type;
124
} _signal_module_state;
125
126
127
Py_LOCAL_INLINE(PyObject *)
128
get_handler(int i)
129
1.04k
{
130
1.04k
    return (PyObject *)_Py_atomic_load_ptr(&Handlers[i].func);
131
1.04k
}
132
133
Py_LOCAL_INLINE(void)
134
set_handler(int i, PyObject* func)
135
1.04k
{
136
    /* Store func with atomic operation to ensure
137
       that PyErr_SetInterrupt is async-signal-safe. */
138
1.04k
    _Py_atomic_store_ptr(&Handlers[i].func, func);
139
1.04k
}
140
141
142
static inline _signal_module_state*
143
get_signal_state(PyObject *module)
144
3.71k
{
145
3.71k
    void *state = _PyModule_GetState(module);
146
3.71k
    assert(state != NULL);
147
3.71k
    return (_signal_module_state *)state;
148
3.71k
}
149
150
151
static inline int
152
compare_handler(PyObject *func, PyObject *dfl_ign_handler)
153
0
{
154
    // See https://github.com/python/cpython/pull/102399
155
0
    if (func == NULL || dfl_ign_handler == NULL) {
156
0
        return 0;
157
0
    }
158
0
    assert(PyLong_CheckExact(dfl_ign_handler));
159
0
    if (!PyLong_CheckExact(func)) {
160
0
        return 0;
161
0
    }
162
    // Assume that comparison of two PyLong objects will never fail.
163
0
    return PyObject_RichCompareBool(func, dfl_ign_handler, Py_EQ) == 1;
164
0
}
165
166
#ifdef HAVE_SETITIMER
167
/* auxiliary function for setitimer */
168
static int
169
timeval_from_double(PyObject *obj, struct timeval *tv)
170
0
{
171
0
    if (obj == NULL) {
172
0
        tv->tv_sec = 0;
173
0
        tv->tv_usec = 0;
174
0
        return 0;
175
0
    }
176
177
0
    PyTime_t t;
178
0
    if (_PyTime_FromSecondsObject(&t, obj, _PyTime_ROUND_CEILING) < 0) {
179
0
        return -1;
180
0
    }
181
0
    return _PyTime_AsTimeval(t, tv, _PyTime_ROUND_CEILING);
182
0
}
183
#endif
184
185
#if defined(HAVE_SETITIMER) || defined(HAVE_GETITIMER)
186
/* auxiliary functions for get/setitimer */
187
Py_LOCAL_INLINE(double)
188
double_from_timeval(struct timeval *tv)
189
0
{
190
0
    return tv->tv_sec + (double)(tv->tv_usec / 1000000.0);
191
0
}
192
193
static PyObject *
194
itimer_retval(struct itimerval *iv)
195
0
{
196
0
    PyObject *r, *v;
197
198
0
    r = PyTuple_New(2);
199
0
    if (r == NULL)
200
0
        return NULL;
201
202
0
    if(!(v = PyFloat_FromDouble(double_from_timeval(&iv->it_value)))) {
203
0
        Py_DECREF(r);
204
0
        return NULL;
205
0
    }
206
207
0
    PyTuple_SET_ITEM(r, 0, v);
208
209
0
    if(!(v = PyFloat_FromDouble(double_from_timeval(&iv->it_interval)))) {
210
0
        Py_DECREF(r);
211
0
        return NULL;
212
0
    }
213
214
0
    PyTuple_SET_ITEM(r, 1, v);
215
216
0
    return r;
217
0
}
218
#endif
219
220
/*[clinic input]
221
signal.default_int_handler
222
    signalnum: int
223
    frame: object
224
    /
225
226
The default handler for SIGINT installed by Python.
227
228
It raises KeyboardInterrupt.
229
[clinic start generated code]*/
230
231
static PyObject *
232
signal_default_int_handler_impl(PyObject *module, int signalnum,
233
                                PyObject *frame)
234
/*[clinic end generated code: output=bb11c2eb115ace4e input=efcd4a56a207acfd]*/
235
0
{
236
0
    PyErr_SetNone(PyExc_KeyboardInterrupt);
237
0
    return NULL;
238
0
}
239
240
241
static int
242
report_wakeup_write_error(void *data)
243
0
{
244
0
    int save_errno = errno;
245
0
    errno = (int) (intptr_t) data;
246
0
    PyObject *exc = PyErr_GetRaisedException();
247
0
    PyErr_SetFromErrno(PyExc_OSError);
248
0
    PyErr_FormatUnraisable("Exception ignored while "
249
0
                           "trying to write to the signal wakeup fd");
250
0
    PyErr_SetRaisedException(exc);
251
0
    errno = save_errno;
252
0
    return 0;
253
0
}
254
255
#ifdef MS_WINDOWS
256
static int
257
report_wakeup_send_error(void* data)
258
{
259
    int send_errno = (int) (intptr_t) data;
260
261
    PyObject *exc = PyErr_GetRaisedException();
262
    /* PyErr_SetExcFromWindowsErr() invokes FormatMessage() which
263
       recognizes the error codes used by both GetLastError() and
264
       WSAGetLastError */
265
    PyErr_SetExcFromWindowsErr(PyExc_OSError, send_errno);
266
    PyErr_FormatUnraisable("Exception ignored while "
267
                           "trying to send to the signal wakeup fd");
268
    PyErr_SetRaisedException(exc);
269
    return 0;
270
}
271
#endif   /* MS_WINDOWS */
272
273
static void
274
trip_signal(int sig_num)
275
0
{
276
0
    _Py_atomic_store_int(&Handlers[sig_num].tripped, 1);
277
278
    /* Set is_tripped after setting .tripped, as it gets
279
       cleared in PyErr_CheckSignals() before .tripped. */
280
0
    _Py_atomic_store_int(&is_tripped, 1);
281
282
0
    _PyEval_SignalReceived();
283
284
    /* And then write to the wakeup fd *after* setting all the globals and
285
       doing the _PyEval_SignalReceived. We used to write to the wakeup fd
286
       and then set the flag, but this allowed the following sequence of events
287
       (especially on windows, where trip_signal may run in a new thread):
288
289
       - main thread blocks on select([wakeup.fd], ...)
290
       - signal arrives
291
       - trip_signal writes to the wakeup fd
292
       - the main thread wakes up
293
       - the main thread checks the signal flags, sees that they're unset
294
       - the main thread empties the wakeup fd
295
       - the main thread goes back to sleep
296
       - trip_signal sets the flags to request the Python-level signal handler
297
         be run
298
       - the main thread doesn't notice, because it's asleep
299
300
       See bpo-30038 for more details.
301
    */
302
303
0
    int fd = wakeup.fd;
304
0
    if (fd != INVALID_FD) {
305
0
        PyInterpreterState *interp = _PyInterpreterState_Main();
306
0
        unsigned char byte = (unsigned char)sig_num;
307
#ifdef MS_WINDOWS
308
        if (wakeup.use_send) {
309
            Py_ssize_t rc = send(fd, &byte, 1, 0);
310
311
            if (rc < 0) {
312
                int last_error = GetLastError();
313
                if (wakeup.warn_on_full_buffer ||
314
                    last_error != WSAEWOULDBLOCK)
315
                {
316
                    /* _PyEval_AddPendingCall() isn't signal-safe, but we
317
                       still use it for this exceptional case. */
318
                    _PyEval_AddPendingCall(interp,
319
                                           report_wakeup_send_error,
320
                                           (void *)(intptr_t) last_error,
321
                                           _Py_PENDING_MAINTHREADONLY);
322
                }
323
            }
324
        }
325
        else
326
#endif
327
0
        {
328
            /* _Py_write_noraise() retries write() if write() is interrupted by
329
               a signal (fails with EINTR). */
330
0
            Py_ssize_t rc = _Py_write_noraise(fd, &byte, 1);
331
332
0
            if (rc < 0) {
333
0
                if (wakeup.warn_on_full_buffer ||
334
0
                    (errno != EWOULDBLOCK && errno != EAGAIN))
335
0
                {
336
                    /* _PyEval_AddPendingCall() isn't signal-safe, but we
337
                       still use it for this exceptional case. */
338
0
                    _PyEval_AddPendingCall(interp,
339
0
                                           report_wakeup_write_error,
340
0
                                           (void *)(intptr_t)errno,
341
0
                                           _Py_PENDING_MAINTHREADONLY);
342
0
                }
343
0
            }
344
0
        }
345
0
    }
346
0
}
347
348
static void
349
signal_handler(int sig_num)
350
0
{
351
0
    int save_errno = errno;
352
353
0
    trip_signal(sig_num);
354
355
#ifndef HAVE_SIGACTION
356
#ifdef SIGCHLD
357
    /* To avoid infinite recursion, this signal remains
358
       reset until explicit re-instated.
359
       Don't clear the 'func' field as it is our pointer
360
       to the Python handler... */
361
    if (sig_num != SIGCHLD)
362
#endif
363
    /* If the handler was not set up with sigaction, reinstall it.  See
364
     * Python/pylifecycle.c for the implementation of PyOS_setsig which
365
     * makes this true.  See also issue8354. */
366
    PyOS_setsig(sig_num, signal_handler);
367
#endif
368
369
    /* Issue #10311: asynchronously executing signal handlers should not
370
       mutate errno under the feet of unsuspecting C code. */
371
0
    errno = save_errno;
372
373
#ifdef MS_WINDOWS
374
    if (sig_num == SIGINT) {
375
        signal_state_t *state = &signal_global_state;
376
        SetEvent((HANDLE)state->sigint_event);
377
    }
378
#endif
379
0
}
380
381
382
#ifdef HAVE_ALARM
383
384
/*[clinic input]
385
signal.alarm -> long
386
387
    seconds: int
388
    /
389
390
Arrange for SIGALRM to arrive after the given number of seconds.
391
[clinic start generated code]*/
392
393
static long
394
signal_alarm_impl(PyObject *module, int seconds)
395
/*[clinic end generated code: output=144232290814c298 input=0d5e97e0e6f39e86]*/
396
0
{
397
    /* alarm() returns the number of seconds remaining */
398
0
    return (long)alarm(seconds);
399
0
}
400
401
#endif
402
403
#ifdef HAVE_PAUSE
404
405
/*[clinic input]
406
signal.pause
407
408
Wait until a signal arrives.
409
[clinic start generated code]*/
410
411
static PyObject *
412
signal_pause_impl(PyObject *module)
413
/*[clinic end generated code: output=391656788b3c3929 input=f03de0f875752062]*/
414
0
{
415
0
    Py_BEGIN_ALLOW_THREADS
416
0
    (void)pause();
417
0
    Py_END_ALLOW_THREADS
418
    /* make sure that any exceptions that got raised are propagated
419
     * back into Python
420
     */
421
0
    if (PyErr_CheckSignals())
422
0
        return NULL;
423
424
0
    Py_RETURN_NONE;
425
0
}
426
427
#endif
428
429
/*[clinic input]
430
signal.raise_signal
431
432
    signalnum: int
433
    /
434
435
Send a signal to the executing process.
436
[clinic start generated code]*/
437
438
static PyObject *
439
signal_raise_signal_impl(PyObject *module, int signalnum)
440
/*[clinic end generated code: output=e2b014220aa6111d input=e90c0f9a42358de6]*/
441
0
{
442
0
    int err;
443
0
    Py_BEGIN_ALLOW_THREADS
444
0
    _Py_BEGIN_SUPPRESS_IPH
445
0
    err = raise(signalnum);
446
0
    _Py_END_SUPPRESS_IPH
447
0
    Py_END_ALLOW_THREADS
448
449
0
    if (err) {
450
0
        return PyErr_SetFromErrno(PyExc_OSError);
451
0
    }
452
453
    // If the current thread can handle signals, handle immediately
454
    // the raised signal.
455
0
    if (PyErr_CheckSignals()) {
456
0
        return NULL;
457
0
    }
458
459
0
    Py_RETURN_NONE;
460
0
}
461
462
/*[clinic input]
463
@permit_long_docstring_body
464
signal.signal
465
466
    signalnum: int
467
    handler:   object
468
    /
469
470
Set the action for the given signal.
471
472
The action can be SIG_DFL, SIG_IGN, or a callable Python object.
473
The previous action is returned.  See getsignal() for possible return values.
474
475
*** IMPORTANT NOTICE ***
476
A signal handler function is called with two arguments:
477
the first is the signal number, the second is the interrupted stack frame.
478
[clinic start generated code]*/
479
480
static PyObject *
481
signal_signal_impl(PyObject *module, int signalnum, PyObject *handler)
482
/*[clinic end generated code: output=b44cfda43780f3a1 input=7608656f34fa378b]*/
483
0
{
484
0
    _signal_module_state *modstate = get_signal_state(module);
485
0
    PyObject *old_handler;
486
0
    void (*func)(int);
487
#ifdef MS_WINDOWS
488
    /* Validate that signalnum is one of the allowable signals */
489
    switch (signalnum) {
490
        case SIGABRT: break;
491
#ifdef SIGBREAK
492
        /* Issue #10003: SIGBREAK is not documented as permitted, but works
493
           and corresponds to CTRL_BREAK_EVENT. */
494
        case SIGBREAK: break;
495
#endif
496
        case SIGFPE: break;
497
        case SIGILL: break;
498
        case SIGINT: break;
499
        case SIGSEGV: break;
500
        case SIGTERM: break;
501
        default:
502
            PyErr_SetString(PyExc_ValueError, "invalid signal value");
503
            return NULL;
504
    }
505
#endif
506
507
0
    PyThreadState *tstate = _PyThreadState_GET();
508
0
    if (!_Py_ThreadCanHandleSignals(tstate->interp)) {
509
0
        _PyErr_SetString(tstate, PyExc_ValueError,
510
0
                         "signal only works in main thread "
511
0
                         "of the main interpreter");
512
0
        return NULL;
513
0
    }
514
0
    if (signalnum < 1 || signalnum >= Py_NSIG) {
515
0
        _PyErr_SetString(tstate, PyExc_ValueError,
516
0
                         "signal number out of range");
517
0
        return NULL;
518
0
    }
519
0
    if (PyCallable_Check(handler)) {
520
0
        func = signal_handler;
521
0
    } else if (compare_handler(handler, modstate->ignore_handler)) {
522
0
        func = SIG_IGN;
523
0
    } else if (compare_handler(handler, modstate->default_handler)) {
524
0
        func = SIG_DFL;
525
0
    } else {
526
0
        _PyErr_SetString(tstate, PyExc_TypeError,
527
0
                         "signal handler must be signal.SIG_IGN, "
528
0
                         "signal.SIG_DFL, or a callable object");
529
0
        return NULL;
530
0
    }
531
532
    /* Check for pending signals before changing signal handler */
533
0
    if (_PyErr_CheckSignalsTstate(tstate)) {
534
0
        return NULL;
535
0
    }
536
0
    if (PyOS_setsig(signalnum, func) == SIG_ERR) {
537
0
        PyErr_SetFromErrno(PyExc_OSError);
538
0
        return NULL;
539
0
    }
540
541
0
    old_handler = get_handler(signalnum);
542
0
    set_handler(signalnum, Py_NewRef(handler));
543
544
0
    if (old_handler != NULL) {
545
0
        return old_handler;
546
0
    }
547
0
    else {
548
0
        Py_RETURN_NONE;
549
0
    }
550
0
}
551
552
553
/*[clinic input]
554
signal.getsignal
555
556
    signalnum: int
557
    /
558
559
Return the current action for the given signal.
560
561
The return value can be:
562
  SIG_IGN -- if the signal is being ignored
563
  SIG_DFL -- if the default action for the signal is in effect
564
  None    -- if an unknown handler is in effect
565
  anything else -- the callable Python object used as a handler
566
[clinic start generated code]*/
567
568
static PyObject *
569
signal_getsignal_impl(PyObject *module, int signalnum)
570
/*[clinic end generated code: output=35b3e0e796fd555e input=ac23a00f19dfa509]*/
571
0
{
572
0
    PyObject *old_handler;
573
0
    if (signalnum < 1 || signalnum >= Py_NSIG) {
574
0
        PyErr_SetString(PyExc_ValueError,
575
0
                        "signal number out of range");
576
0
        return NULL;
577
0
    }
578
0
    old_handler = get_handler(signalnum);
579
0
    if (old_handler != NULL) {
580
0
        return Py_NewRef(old_handler);
581
0
    }
582
0
    else {
583
0
        Py_RETURN_NONE;
584
0
    }
585
0
}
586
587
588
/*[clinic input]
589
signal.strsignal
590
591
    signalnum: int
592
    /
593
594
Return the system description of the given signal.
595
596
Returns the description of signal *signalnum*, such as "Interrupt"
597
for :const:`SIGINT`. Returns :const:`None` if *signalnum* has no
598
description. Raises :exc:`ValueError` if *signalnum* is invalid.
599
[clinic start generated code]*/
600
601
static PyObject *
602
signal_strsignal_impl(PyObject *module, int signalnum)
603
/*[clinic end generated code: output=44e12e1e3b666261 input=238b335847778bc0]*/
604
0
{
605
0
    const char *res;
606
607
0
    if (signalnum < 1 || signalnum >= Py_NSIG) {
608
0
        PyErr_SetString(PyExc_ValueError,
609
0
                "signal number out of range");
610
0
        return NULL;
611
0
    }
612
613
#ifndef HAVE_STRSIGNAL
614
    switch (signalnum) {
615
        /* Though being a UNIX, HP-UX does not provide strsignal(3). */
616
#ifndef MS_WINDOWS
617
        case SIGHUP:
618
            res = "Hangup";
619
            break;
620
        case SIGALRM:
621
            res = "Alarm clock";
622
            break;
623
        case SIGPIPE:
624
            res = "Broken pipe";
625
            break;
626
        case SIGQUIT:
627
            res = "Quit";
628
            break;
629
        case SIGCHLD:
630
            res = "Child exited";
631
            break;
632
#endif
633
        /* Custom redefinition of POSIX signals allowed on Windows. */
634
        case SIGINT:
635
            res = "Interrupt";
636
            break;
637
        case SIGILL:
638
            res = "Illegal instruction";
639
            break;
640
        case SIGABRT:
641
            res = "Aborted";
642
            break;
643
        case SIGFPE:
644
            res = "Floating-point exception";
645
            break;
646
        case SIGSEGV:
647
            res = "Segmentation fault";
648
            break;
649
        case SIGTERM:
650
            res = "Terminated";
651
            break;
652
        default:
653
            Py_RETURN_NONE;
654
    }
655
#else
656
0
    errno = 0;
657
0
    res = strsignal(signalnum);
658
659
0
    if (errno || res == NULL || strstr(res, "Unknown signal") != NULL)
660
0
        Py_RETURN_NONE;
661
0
#endif
662
663
0
    return PyUnicode_FromString(res);
664
0
}
665
666
#ifdef HAVE_SIGINTERRUPT
667
668
/*[clinic input]
669
signal.siginterrupt
670
671
    signalnum: int
672
    flag:      int
673
    /
674
675
Change system call restart behaviour.
676
677
If flag is False, system calls will be restarted when interrupted by
678
signal sig, else system calls will be interrupted.
679
[clinic start generated code]*/
680
681
static PyObject *
682
signal_siginterrupt_impl(PyObject *module, int signalnum, int flag)
683
/*[clinic end generated code: output=063816243d85dd19 input=4160acacca3e2099]*/
684
0
{
685
0
    if (signalnum < 1 || signalnum >= Py_NSIG) {
686
0
        PyErr_SetString(PyExc_ValueError,
687
0
                        "signal number out of range");
688
0
        return NULL;
689
0
    }
690
0
#ifdef HAVE_SIGACTION
691
0
    struct sigaction act;
692
0
    (void) sigaction(signalnum, NULL, &act);
693
0
    if (flag) {
694
0
        act.sa_flags &= ~SA_RESTART;
695
0
    }
696
0
    else {
697
0
        act.sa_flags |= SA_RESTART;
698
0
    }
699
0
    if (sigaction(signalnum, &act, NULL) < 0) {
700
#else
701
    if (siginterrupt(signalnum, flag) < 0) {
702
#endif
703
0
        PyErr_SetFromErrno(PyExc_OSError);
704
0
        return NULL;
705
0
    }
706
0
    Py_RETURN_NONE;
707
0
}
708
709
#endif
710
711
712
/*[clinic input]
713
@permit_long_summary
714
signal.set_wakeup_fd
715
716
    fd as fdobj: object
717
    /
718
    *
719
    warn_on_full_buffer: bool = True
720
721
Sets the fd to be written to (with the signal number) when a signal comes in.
722
723
A library can use this to wakeup select or poll.
724
The previous fd or -1 is returned.
725
726
The fd must be non-blocking.
727
[clinic start generated code]*/
728
729
static PyObject *
730
signal_set_wakeup_fd_impl(PyObject *module, PyObject *fdobj,
731
                          int warn_on_full_buffer)
732
/*[clinic end generated code: output=2280d72dd2a54c4f input=1b914d48079e9274]*/
733
0
{
734
0
    struct _Py_stat_struct status;
735
#ifdef MS_WINDOWS
736
    SOCKET_T sockfd, old_sockfd;
737
    int res;
738
    int res_size = sizeof res;
739
    PyObject *mod;
740
    int is_socket;
741
742
    sockfd = PyLong_AsSocket_t(fdobj);
743
    if (sockfd == (SOCKET_T)(-1) && PyErr_Occurred())
744
        return NULL;
745
#else
746
0
    int fd = PyLong_AsInt(fdobj);
747
0
    if (fd == -1 && PyErr_Occurred()) {
748
0
        return NULL;
749
0
    }
750
0
#endif
751
752
0
    PyThreadState *tstate = _PyThreadState_GET();
753
0
    if (!_Py_ThreadCanHandleSignals(tstate->interp)) {
754
0
        _PyErr_SetString(tstate, PyExc_ValueError,
755
0
                         "set_wakeup_fd only works in main thread "
756
0
                         "of the main interpreter");
757
0
        return NULL;
758
0
    }
759
760
#ifdef MS_WINDOWS
761
    is_socket = 0;
762
    if (sockfd != INVALID_FD) {
763
        /* Import the _socket module to call WSAStartup() */
764
        mod = PyImport_ImportModule("_socket");
765
        if (mod == NULL)
766
            return NULL;
767
        Py_DECREF(mod);
768
769
        /* test the socket */
770
        if (getsockopt(sockfd, SOL_SOCKET, SO_ERROR,
771
                       (char *)&res, &res_size) != 0) {
772
            int fd, err;
773
774
            err = WSAGetLastError();
775
            if (err != WSAENOTSOCK) {
776
                PyErr_SetExcFromWindowsErr(PyExc_OSError, err);
777
                return NULL;
778
            }
779
780
            fd = (int)sockfd;
781
            if ((SOCKET_T)fd != sockfd) {
782
                _PyErr_SetString(tstate, PyExc_ValueError, "invalid fd");
783
                return NULL;
784
            }
785
786
            if (_Py_fstat(fd, &status) != 0) {
787
                return NULL;
788
            }
789
790
            /* on Windows, a file cannot be set to non-blocking mode */
791
        }
792
        else {
793
            is_socket = 1;
794
795
            /* Windows does not provide a function to test if a socket
796
               is in non-blocking mode */
797
        }
798
    }
799
800
    old_sockfd = wakeup.fd;
801
    wakeup.fd = Py_SAFE_DOWNCAST(sockfd, SOCKET_T, int);
802
    wakeup.warn_on_full_buffer = warn_on_full_buffer;
803
    wakeup.use_send = is_socket;
804
805
    if (old_sockfd != INVALID_FD)
806
        return PyLong_FromSocket_t(old_sockfd);
807
    else
808
        return PyLong_FromLong(-1);
809
#else
810
0
    if (fd != -1) {
811
0
        int blocking;
812
813
0
        if (_Py_fstat(fd, &status) != 0)
814
0
            return NULL;
815
816
0
        blocking = _Py_get_blocking(fd);
817
0
        if (blocking < 0)
818
0
            return NULL;
819
0
        if (blocking) {
820
0
            _PyErr_Format(tstate, PyExc_ValueError,
821
0
                          "the fd %i must be in non-blocking mode",
822
0
                          fd);
823
0
            return NULL;
824
0
        }
825
0
    }
826
827
0
    int old_fd = wakeup.fd;
828
0
    wakeup.fd = fd;
829
0
    wakeup.warn_on_full_buffer = warn_on_full_buffer;
830
831
0
    return PyLong_FromLong(old_fd);
832
0
#endif
833
0
}
834
835
/* C API for the same, without all the error checking */
836
int
837
PySignal_SetWakeupFd(int fd)
838
0
{
839
0
    if (fd < 0) {
840
0
        fd = -1;
841
0
    }
842
843
0
    int old_fd = wakeup.fd;
844
0
    wakeup.fd = fd;
845
0
    wakeup.warn_on_full_buffer = 1;
846
0
    return old_fd;
847
0
}
848
849
850
#ifdef HAVE_SETITIMER
851
/*[clinic input]
852
@permit_long_docstring_body
853
signal.setitimer
854
855
    which:    int
856
    seconds:  object
857
    interval: object(c_default="NULL") = 0.0
858
    /
859
860
Sets given itimer (one of ITIMER_REAL, ITIMER_VIRTUAL or ITIMER_PROF).
861
862
The timer will fire after value seconds and after that every interval seconds.
863
The itimer can be cleared by setting seconds to zero.
864
865
Returns old values as a tuple: (delay, interval).
866
[clinic start generated code]*/
867
868
static PyObject *
869
signal_setitimer_impl(PyObject *module, int which, PyObject *seconds,
870
                      PyObject *interval)
871
/*[clinic end generated code: output=65f9dcbddc35527b input=ab5bf2b8f5cff3f4]*/
872
0
{
873
0
    _signal_module_state *modstate = get_signal_state(module);
874
875
0
    struct itimerval new;
876
0
    if (timeval_from_double(seconds, &new.it_value) < 0) {
877
0
        return NULL;
878
0
    }
879
0
    if (timeval_from_double(interval, &new.it_interval) < 0) {
880
0
        return NULL;
881
0
    }
882
883
    /* Let OS check "which" value */
884
0
    struct itimerval old;
885
0
    if (setitimer(which, &new, &old) != 0) {
886
0
        PyErr_SetFromErrno(modstate->itimer_error);
887
0
        return NULL;
888
0
    }
889
890
0
    return itimer_retval(&old);
891
0
}
892
#endif  // HAVE_SETITIMER
893
894
895
#ifdef HAVE_GETITIMER
896
/*[clinic input]
897
signal.getitimer
898
899
    which:    int
900
    /
901
902
Returns current value of given itimer.
903
[clinic start generated code]*/
904
905
static PyObject *
906
signal_getitimer_impl(PyObject *module, int which)
907
/*[clinic end generated code: output=9e053175d517db40 input=f7d21d38f3490627]*/
908
0
{
909
0
    _signal_module_state *modstate = get_signal_state(module);
910
911
0
    struct itimerval old;
912
0
    if (getitimer(which, &old) != 0) {
913
0
        PyErr_SetFromErrno(modstate->itimer_error);
914
0
        return NULL;
915
0
    }
916
917
0
    return itimer_retval(&old);
918
0
}
919
#endif // HAVE_GETITIMER
920
921
922
#ifdef HAVE_SIGSET_T
923
#if defined(PYPTHREAD_SIGMASK) || defined(HAVE_SIGPENDING)
924
static PyObject*
925
sigset_to_set(sigset_t mask)
926
0
{
927
0
    PyObject *signum, *result;
928
0
    int sig;
929
930
0
    result = PySet_New(0);
931
0
    if (result == NULL)
932
0
        return NULL;
933
934
0
    for (sig = 1; sig < Py_NSIG; sig++) {
935
0
        if (sigismember(&mask, sig) != 1)
936
0
            continue;
937
938
        /* Handle the case where it is a member by adding the signal to
939
           the result list.  Ignore the other cases because they mean the
940
           signal isn't a member of the mask or the signal was invalid,
941
           and an invalid signal must have been our fault in constructing
942
           the loop boundaries. */
943
0
        signum = PyLong_FromLong(sig);
944
0
        if (signum == NULL) {
945
0
            Py_DECREF(result);
946
0
            return NULL;
947
0
        }
948
0
        if (PySet_Add(result, signum) == -1) {
949
0
            Py_DECREF(signum);
950
0
            Py_DECREF(result);
951
0
            return NULL;
952
0
        }
953
0
        Py_DECREF(signum);
954
0
    }
955
0
    return result;
956
0
}
957
#endif
958
959
#ifdef PYPTHREAD_SIGMASK
960
961
/*[clinic input]
962
signal.pthread_sigmask
963
964
    how:  int
965
    mask: sigset_t
966
    /
967
968
Fetch and/or change the signal mask of the calling thread.
969
[clinic start generated code]*/
970
971
static PyObject *
972
signal_pthread_sigmask_impl(PyObject *module, int how, sigset_t mask)
973
/*[clinic end generated code: output=0562c0fb192981a8 input=85bcebda442fa77f]*/
974
0
{
975
0
    sigset_t previous;
976
0
    int err;
977
978
0
    err = pthread_sigmask(how, &mask, &previous);
979
0
    if (err != 0) {
980
0
        errno = err;
981
0
        PyErr_SetFromErrno(PyExc_OSError);
982
0
        return NULL;
983
0
    }
984
985
    /* if signals was unblocked, signal handlers have been called */
986
0
    if (PyErr_CheckSignals())
987
0
        return NULL;
988
989
0
    return sigset_to_set(previous);
990
0
}
991
992
#endif   /* #ifdef PYPTHREAD_SIGMASK */
993
994
995
#ifdef HAVE_SIGPENDING
996
997
/*[clinic input]
998
signal.sigpending
999
1000
Examine pending signals.
1001
1002
Returns a set of signal numbers that are pending for delivery to
1003
the calling thread.
1004
[clinic start generated code]*/
1005
1006
static PyObject *
1007
signal_sigpending_impl(PyObject *module)
1008
/*[clinic end generated code: output=53375ffe89325022 input=e0036c016f874e29]*/
1009
0
{
1010
0
    int err;
1011
0
    sigset_t mask;
1012
0
    err = sigpending(&mask);
1013
0
    if (err)
1014
0
        return PyErr_SetFromErrno(PyExc_OSError);
1015
0
    return sigset_to_set(mask);
1016
0
}
1017
1018
#endif   /* #ifdef HAVE_SIGPENDING */
1019
1020
1021
#ifdef HAVE_SIGWAIT
1022
1023
/*[clinic input]
1024
signal.sigwait
1025
1026
    sigset: sigset_t
1027
    /
1028
1029
Wait for a signal.
1030
1031
Suspend execution of the calling thread until the delivery of one of the
1032
signals specified in the signal set sigset.  The function accepts the signal
1033
and returns the signal number.
1034
[clinic start generated code]*/
1035
1036
static PyObject *
1037
signal_sigwait_impl(PyObject *module, sigset_t sigset)
1038
/*[clinic end generated code: output=f43770699d682f96 input=a6fbd47b1086d119]*/
1039
0
{
1040
0
    int err, signum;
1041
1042
0
    Py_BEGIN_ALLOW_THREADS
1043
0
    err = sigwait(&sigset, &signum);
1044
0
    Py_END_ALLOW_THREADS
1045
0
    if (err) {
1046
0
        errno = err;
1047
0
        return PyErr_SetFromErrno(PyExc_OSError);
1048
0
    }
1049
1050
0
    return PyLong_FromLong(signum);
1051
0
}
1052
1053
#endif   /* #ifdef HAVE_SIGWAIT */
1054
#endif   /* #ifdef HAVE_SIGSET_T */
1055
1056
#if (defined(HAVE_SIGFILLSET) && defined(HAVE_SIGSET_T)) || defined(MS_WINDOWS)
1057
1058
/*[clinic input]
1059
signal.valid_signals
1060
1061
Return a set of valid signal numbers on this platform.
1062
1063
The signal numbers returned by this function can be safely passed to
1064
functions like `pthread_sigmask`.
1065
[clinic start generated code]*/
1066
1067
static PyObject *
1068
signal_valid_signals_impl(PyObject *module)
1069
/*[clinic end generated code: output=1609cffbcfcf1314 input=86a3717ff25288f2]*/
1070
0
{
1071
#ifdef MS_WINDOWS
1072
#ifdef SIGBREAK
1073
    PyObject *tup = Py_BuildValue("(iiiiiii)", SIGABRT, SIGBREAK, SIGFPE,
1074
                                  SIGILL, SIGINT, SIGSEGV, SIGTERM);
1075
#else
1076
    PyObject *tup = Py_BuildValue("(iiiiii)", SIGABRT, SIGFPE, SIGILL,
1077
                                  SIGINT, SIGSEGV, SIGTERM);
1078
#endif
1079
    if (tup == NULL) {
1080
        return NULL;
1081
    }
1082
    PyObject *set = PySet_New(tup);
1083
    Py_DECREF(tup);
1084
    return set;
1085
#else
1086
0
    sigset_t mask;
1087
0
    if (sigemptyset(&mask) || sigfillset(&mask)) {
1088
0
        return PyErr_SetFromErrno(PyExc_OSError);
1089
0
    }
1090
0
    return sigset_to_set(mask);
1091
0
#endif
1092
0
}
1093
1094
#endif   /* #if (defined(HAVE_SIGFILLSET) && defined(HAVE_SIGSET_T)) || defined(MS_WINDOWS) */
1095
1096
1097
1098
#if defined(HAVE_SIGWAITINFO) || defined(HAVE_SIGTIMEDWAIT)
1099
static PyStructSequence_Field struct_siginfo_fields[] = {
1100
    {"si_signo",        "signal number"},
1101
    {"si_code",         "signal code"},
1102
    {"si_errno",        "errno associated with this signal"},
1103
    {"si_pid",          "sending process ID"},
1104
    {"si_uid",          "real user ID of sending process"},
1105
    {"si_status",       "exit value or signal"},
1106
    {"si_band",         "band event for SIGPOLL"},
1107
    {0}
1108
};
1109
1110
PyDoc_STRVAR(struct_siginfo__doc__,
1111
"struct_siginfo: Result from sigwaitinfo or sigtimedwait.\n\n\
1112
This object may be accessed either as a tuple of\n\
1113
(si_signo, si_code, si_errno, si_pid, si_uid, si_status, si_band),\n\
1114
or via the attributes si_signo, si_code, and so on.");
1115
1116
static PyStructSequence_Desc struct_siginfo_desc = {
1117
    "signal.struct_siginfo",           /* name */
1118
    struct_siginfo__doc__,       /* doc */
1119
    struct_siginfo_fields,       /* fields */
1120
    7          /* n_in_sequence */
1121
};
1122
1123
1124
static PyObject *
1125
fill_siginfo(_signal_module_state *state, siginfo_t *si)
1126
0
{
1127
0
    PyObject *result = PyStructSequence_New(state->siginfo_type);
1128
0
    if (!result)
1129
0
        return NULL;
1130
1131
0
    PyStructSequence_SET_ITEM(result, 0, PyLong_FromLong((long)(si->si_signo)));
1132
0
    PyStructSequence_SET_ITEM(result, 1, PyLong_FromLong((long)(si->si_code)));
1133
#ifdef __VXWORKS__
1134
    PyStructSequence_SET_ITEM(result, 2, PyLong_FromLong(0L));
1135
    PyStructSequence_SET_ITEM(result, 3, PyLong_FromLong(0L));
1136
    PyStructSequence_SET_ITEM(result, 4, PyLong_FromLong(0L));
1137
    PyStructSequence_SET_ITEM(result, 5, PyLong_FromLong(0L));
1138
#else
1139
0
    PyStructSequence_SET_ITEM(result, 2, PyLong_FromLong((long)(si->si_errno)));
1140
0
    PyStructSequence_SET_ITEM(result, 3, PyLong_FromPid(si->si_pid));
1141
0
    PyStructSequence_SET_ITEM(result, 4, _PyLong_FromUid(si->si_uid));
1142
0
    PyStructSequence_SET_ITEM(result, 5,
1143
0
                                PyLong_FromLong((long)(si->si_status)));
1144
0
#endif
1145
0
#ifdef HAVE_SIGINFO_T_SI_BAND
1146
0
    PyStructSequence_SET_ITEM(result, 6, PyLong_FromLong(si->si_band));
1147
#else
1148
    PyStructSequence_SET_ITEM(result, 6, PyLong_FromLong(0L));
1149
#endif
1150
0
    if (PyErr_Occurred()) {
1151
0
        Py_DECREF(result);
1152
0
        return NULL;
1153
0
    }
1154
1155
0
    return result;
1156
0
}
1157
#endif
1158
1159
#ifdef HAVE_SIGSET_T
1160
#ifdef HAVE_SIGWAITINFO
1161
1162
/*[clinic input]
1163
signal.sigwaitinfo
1164
1165
    sigset: sigset_t
1166
    /
1167
1168
Wait synchronously until one of the signals in *sigset* is delivered.
1169
1170
Returns a struct_siginfo containing information about the signal.
1171
[clinic start generated code]*/
1172
1173
static PyObject *
1174
signal_sigwaitinfo_impl(PyObject *module, sigset_t sigset)
1175
/*[clinic end generated code: output=1eb2f1fa236fdbca input=3d1a7e1f27fc664c]*/
1176
0
{
1177
0
    siginfo_t si;
1178
0
    int err;
1179
0
    int async_err = 0;
1180
1181
0
    do {
1182
0
        Py_BEGIN_ALLOW_THREADS
1183
0
        err = sigwaitinfo(&sigset, &si);
1184
0
        Py_END_ALLOW_THREADS
1185
0
    } while (err == -1
1186
0
             && (errno == EINTR
1187
#if defined(__NetBSD__)
1188
                 /* NetBSD's implementation violates POSIX by setting
1189
                  * errno to ECANCELED instead of EINTR. */
1190
                 || errno == ECANCELED
1191
#endif
1192
0
            ) && !(async_err = PyErr_CheckSignals()));
1193
0
    if (err == -1)
1194
0
        return (!async_err) ? PyErr_SetFromErrno(PyExc_OSError) : NULL;
1195
1196
0
    _signal_module_state *state = get_signal_state(module);
1197
0
    return fill_siginfo(state, &si);
1198
0
}
1199
1200
#endif   /* #ifdef HAVE_SIGWAITINFO */
1201
1202
#ifdef HAVE_SIGTIMEDWAIT
1203
1204
/*[clinic input]
1205
signal.sigtimedwait
1206
1207
    sigset: sigset_t
1208
    timeout as timeout_obj: object
1209
    /
1210
1211
Like sigwaitinfo(), but with a timeout.
1212
1213
The timeout is specified in seconds, rounded up to nanoseconds.
1214
[clinic start generated code]*/
1215
1216
static PyObject *
1217
signal_sigtimedwait_impl(PyObject *module, sigset_t sigset,
1218
                         PyObject *timeout_obj)
1219
/*[clinic end generated code: output=59c8971e8ae18a64 input=f89af57d645e48e0]*/
1220
0
{
1221
0
    PyTime_t timeout;
1222
0
    if (_PyTime_FromSecondsObject(&timeout,
1223
0
                                  timeout_obj, _PyTime_ROUND_CEILING) < 0)
1224
0
        return NULL;
1225
1226
0
    if (timeout < 0) {
1227
0
        PyErr_SetString(PyExc_ValueError, "timeout must be non-negative");
1228
0
        return NULL;
1229
0
    }
1230
1231
0
    PyTime_t deadline = _PyDeadline_Init(timeout);
1232
0
    siginfo_t si;
1233
1234
0
    do {
1235
0
        struct timespec ts;
1236
0
        if (_PyTime_AsTimespec(timeout, &ts) < 0) {
1237
0
            return NULL;
1238
0
        }
1239
1240
0
        int res;
1241
0
        Py_BEGIN_ALLOW_THREADS
1242
0
        res = sigtimedwait(&sigset, &si, &ts);
1243
0
        Py_END_ALLOW_THREADS
1244
1245
0
        if (res != -1)
1246
0
            break;
1247
1248
0
        if (errno != EINTR) {
1249
0
            if (errno == EAGAIN)
1250
0
                Py_RETURN_NONE;
1251
0
            else
1252
0
                return PyErr_SetFromErrno(PyExc_OSError);
1253
0
        }
1254
1255
        /* sigtimedwait() was interrupted by a signal (EINTR) */
1256
0
        if (PyErr_CheckSignals())
1257
0
            return NULL;
1258
1259
0
        timeout = _PyDeadline_Get(deadline);
1260
0
        if (timeout < 0) {
1261
0
            break;
1262
0
        }
1263
0
    } while (1);
1264
1265
0
    _signal_module_state *state = get_signal_state(module);
1266
0
    return fill_siginfo(state, &si);
1267
0
}
1268
1269
#endif   /* #ifdef HAVE_SIGTIMEDWAIT */
1270
#endif   /* #ifdef HAVE_SIGSET_T */
1271
1272
1273
#if defined(HAVE_PTHREAD_KILL)
1274
1275
/*[clinic input]
1276
signal.pthread_kill
1277
1278
    thread_id:  unsigned_long(bitwise=True)
1279
    signalnum:  int
1280
    /
1281
1282
Send a signal to a thread.
1283
[clinic start generated code]*/
1284
1285
static PyObject *
1286
signal_pthread_kill_impl(PyObject *module, unsigned long thread_id,
1287
                         int signalnum)
1288
/*[clinic end generated code: output=7629919b791bc27f input=1d901f2c7bb544ff]*/
1289
0
{
1290
0
    int err;
1291
1292
0
    if (PySys_Audit("signal.pthread_kill", "ki", thread_id, signalnum) < 0) {
1293
0
        return NULL;
1294
0
    }
1295
1296
0
    err = pthread_kill((pthread_t)thread_id, signalnum);
1297
0
    if (err != 0) {
1298
0
        errno = err;
1299
0
        PyErr_SetFromErrno(PyExc_OSError);
1300
0
        return NULL;
1301
0
    }
1302
1303
    /* the signal may have been send to the current thread */
1304
0
    if (PyErr_CheckSignals())
1305
0
        return NULL;
1306
1307
0
    Py_RETURN_NONE;
1308
0
}
1309
1310
#endif   /* #if defined(HAVE_PTHREAD_KILL) */
1311
1312
1313
// This system call always crashes on older Android versions.
1314
#if defined(__linux__) && defined(__NR_pidfd_send_signal) && \
1315
    !(defined(__ANDROID__) && __ANDROID_API__ < 31)
1316
/*[clinic input]
1317
signal.pidfd_send_signal
1318
1319
    pidfd: int
1320
    signalnum: int
1321
    siginfo: object = None
1322
    flags: int = 0
1323
    /
1324
1325
Send a signal to a process referred to by a pid file descriptor.
1326
[clinic start generated code]*/
1327
1328
static PyObject *
1329
signal_pidfd_send_signal_impl(PyObject *module, int pidfd, int signalnum,
1330
                              PyObject *siginfo, int flags)
1331
/*[clinic end generated code: output=2d59f04a75d9cbdf input=2a6543a1f4ac2000]*/
1332
1333
0
{
1334
0
    if (siginfo != Py_None) {
1335
0
        PyErr_SetString(PyExc_TypeError, "siginfo must be None");
1336
0
        return NULL;
1337
0
    }
1338
0
    if (syscall(__NR_pidfd_send_signal, pidfd, signalnum, NULL, flags) < 0) {
1339
0
        PyErr_SetFromErrno(PyExc_OSError);
1340
0
        return NULL;
1341
0
    }
1342
0
    Py_RETURN_NONE;
1343
0
}
1344
#endif
1345
1346
1347
1348
/* List of functions defined in the module -- some of the methoddefs are
1349
   defined to nothing if the corresponding C function is not available. */
1350
static PyMethodDef signal_methods[] = {
1351
    SIGNAL_DEFAULT_INT_HANDLER_METHODDEF
1352
    SIGNAL_ALARM_METHODDEF
1353
    SIGNAL_SETITIMER_METHODDEF
1354
    SIGNAL_GETITIMER_METHODDEF
1355
    SIGNAL_SIGNAL_METHODDEF
1356
    SIGNAL_RAISE_SIGNAL_METHODDEF
1357
    SIGNAL_STRSIGNAL_METHODDEF
1358
    SIGNAL_GETSIGNAL_METHODDEF
1359
    SIGNAL_SET_WAKEUP_FD_METHODDEF
1360
    SIGNAL_SIGINTERRUPT_METHODDEF
1361
    SIGNAL_PAUSE_METHODDEF
1362
    SIGNAL_PIDFD_SEND_SIGNAL_METHODDEF
1363
    SIGNAL_PTHREAD_KILL_METHODDEF
1364
    SIGNAL_PTHREAD_SIGMASK_METHODDEF
1365
    SIGNAL_SIGPENDING_METHODDEF
1366
    SIGNAL_SIGWAIT_METHODDEF
1367
    SIGNAL_SIGWAITINFO_METHODDEF
1368
    SIGNAL_SIGTIMEDWAIT_METHODDEF
1369
#if defined(HAVE_SIGFILLSET) || defined(MS_WINDOWS)
1370
    SIGNAL_VALID_SIGNALS_METHODDEF
1371
#endif
1372
    {NULL, NULL}           /* sentinel */
1373
};
1374
1375
1376
PyDoc_STRVAR(module_doc,
1377
"This module provides mechanisms to use signal handlers in Python.\n\
1378
\n\
1379
Functions:\n\
1380
\n\
1381
alarm() -- cause SIGALRM after a specified time [Unix only]\n\
1382
setitimer() -- cause a signal (described below) after a specified\n\
1383
               float time and the timer may restart then [Unix only]\n\
1384
getitimer() -- get current value of timer [Unix only]\n\
1385
signal() -- set the action for a given signal\n\
1386
getsignal() -- get the signal action for a given signal\n\
1387
pause() -- wait until a signal arrives [Unix only]\n\
1388
default_int_handler() -- default SIGINT handler\n\
1389
\n\
1390
signal constants:\n\
1391
SIG_DFL -- used to refer to the system default handler\n\
1392
SIG_IGN -- used to ignore the signal\n\
1393
NSIG -- number of defined signals\n\
1394
SIGINT, SIGTERM, etc. -- signal numbers\n\
1395
\n\
1396
itimer constants:\n\
1397
ITIMER_REAL -- decrements in real time, and delivers SIGALRM upon\n\
1398
               expiration\n\
1399
ITIMER_VIRTUAL -- decrements only when the process is executing,\n\
1400
               and delivers SIGVTALRM upon expiration\n\
1401
ITIMER_PROF -- decrements both when the process is executing and\n\
1402
               when the system is executing on behalf of the process.\n\
1403
               Coupled with ITIMER_VIRTUAL, this timer is usually\n\
1404
               used to profile the time spent by the application\n\
1405
               in user and kernel space. SIGPROF is delivered upon\n\
1406
               expiration.\n\
1407
\n\n\
1408
*** IMPORTANT NOTICE ***\n\
1409
A signal handler function is called with two arguments:\n\
1410
the first is the signal number, the second is the interrupted stack frame.");
1411
1412
1413
1414
static int
1415
signal_add_constants(PyObject *module)
1416
16
{
1417
16
    if (PyModule_AddIntConstant(module, "NSIG", Py_NSIG) < 0) {
1418
0
        return -1;
1419
0
    }
1420
1421
16
#define ADD_INT_MACRO(macro) \
1422
672
    if (PyModule_AddIntConstant(module, #macro, macro) < 0) { \
1423
0
        return -1; \
1424
0
    }
1425
1426
    // SIG_xxx pthread_sigmask() constants
1427
16
#ifdef SIG_BLOCK
1428
16
    ADD_INT_MACRO(SIG_BLOCK);
1429
16
#endif
1430
16
#ifdef SIG_UNBLOCK
1431
16
    ADD_INT_MACRO(SIG_UNBLOCK);
1432
16
#endif
1433
16
#ifdef SIG_SETMASK
1434
16
    ADD_INT_MACRO(SIG_SETMASK);
1435
16
#endif
1436
1437
    // SIGxxx signal number constants
1438
16
#ifdef SIGHUP
1439
16
    ADD_INT_MACRO(SIGHUP);
1440
16
#endif
1441
16
#ifdef SIGINT
1442
16
    ADD_INT_MACRO(SIGINT);
1443
16
#endif
1444
#ifdef SIGBREAK
1445
    ADD_INT_MACRO(SIGBREAK);
1446
#endif
1447
16
#ifdef SIGQUIT
1448
16
    ADD_INT_MACRO(SIGQUIT);
1449
16
#endif
1450
16
#ifdef SIGILL
1451
16
    ADD_INT_MACRO(SIGILL);
1452
16
#endif
1453
16
#ifdef SIGTRAP
1454
16
    ADD_INT_MACRO(SIGTRAP);
1455
16
#endif
1456
16
#ifdef SIGIOT
1457
16
    ADD_INT_MACRO(SIGIOT);
1458
16
#endif
1459
16
#ifdef SIGABRT
1460
16
    ADD_INT_MACRO(SIGABRT);
1461
16
#endif
1462
#ifdef SIGEMT
1463
    ADD_INT_MACRO(SIGEMT);
1464
#endif
1465
16
#ifdef SIGFPE
1466
16
    ADD_INT_MACRO(SIGFPE);
1467
16
#endif
1468
16
#ifdef SIGKILL
1469
16
    ADD_INT_MACRO(SIGKILL);
1470
16
#endif
1471
16
#ifdef SIGBUS
1472
16
    ADD_INT_MACRO(SIGBUS);
1473
16
#endif
1474
16
#ifdef SIGSEGV
1475
16
    ADD_INT_MACRO(SIGSEGV);
1476
16
#endif
1477
16
#ifdef SIGSYS
1478
16
    ADD_INT_MACRO(SIGSYS);
1479
16
#endif
1480
16
#ifdef SIGPIPE
1481
16
    ADD_INT_MACRO(SIGPIPE);
1482
16
#endif
1483
16
#ifdef SIGALRM
1484
16
    ADD_INT_MACRO(SIGALRM);
1485
16
#endif
1486
16
#ifdef SIGTERM
1487
16
    ADD_INT_MACRO(SIGTERM);
1488
16
#endif
1489
16
#ifdef SIGUSR1
1490
16
    ADD_INT_MACRO(SIGUSR1);
1491
16
#endif
1492
16
#ifdef SIGUSR2
1493
16
    ADD_INT_MACRO(SIGUSR2);
1494
16
#endif
1495
16
#ifdef SIGCLD
1496
16
    ADD_INT_MACRO(SIGCLD);
1497
16
#endif
1498
16
#ifdef SIGCHLD
1499
16
    ADD_INT_MACRO(SIGCHLD);
1500
16
#endif
1501
16
#ifdef SIGPWR
1502
16
    ADD_INT_MACRO(SIGPWR);
1503
16
#endif
1504
16
#ifdef SIGIO
1505
16
    ADD_INT_MACRO(SIGIO);
1506
16
#endif
1507
16
#ifdef SIGURG
1508
16
    ADD_INT_MACRO(SIGURG);
1509
16
#endif
1510
16
#ifdef SIGWINCH
1511
16
    ADD_INT_MACRO(SIGWINCH);
1512
16
#endif
1513
16
#ifdef SIGPOLL
1514
16
    ADD_INT_MACRO(SIGPOLL);
1515
16
#endif
1516
16
#ifdef SIGSTOP
1517
16
    ADD_INT_MACRO(SIGSTOP);
1518
16
#endif
1519
16
#ifdef SIGTSTP
1520
16
    ADD_INT_MACRO(SIGTSTP);
1521
16
#endif
1522
16
#ifdef SIGCONT
1523
16
    ADD_INT_MACRO(SIGCONT);
1524
16
#endif
1525
16
#ifdef SIGTTIN
1526
16
    ADD_INT_MACRO(SIGTTIN);
1527
16
#endif
1528
16
#ifdef SIGTTOU
1529
16
    ADD_INT_MACRO(SIGTTOU);
1530
16
#endif
1531
16
#ifdef SIGVTALRM
1532
16
    ADD_INT_MACRO(SIGVTALRM);
1533
16
#endif
1534
16
#ifdef SIGPROF
1535
16
    ADD_INT_MACRO(SIGPROF);
1536
16
#endif
1537
16
#ifdef SIGXCPU
1538
16
    ADD_INT_MACRO(SIGXCPU);
1539
16
#endif
1540
16
#ifdef SIGXFSZ
1541
16
    ADD_INT_MACRO(SIGXFSZ);
1542
16
#endif
1543
16
#ifdef SIGRTMIN
1544
16
    ADD_INT_MACRO(SIGRTMIN);
1545
16
#endif
1546
16
#ifdef SIGRTMAX
1547
16
    ADD_INT_MACRO(SIGRTMAX);
1548
16
#endif
1549
#ifdef SIGINFO
1550
    ADD_INT_MACRO(SIGINFO);
1551
#endif
1552
16
#ifdef SIGSTKFLT
1553
16
    ADD_INT_MACRO(SIGSTKFLT);
1554
16
#endif
1555
1556
    // ITIMER_xxx constants
1557
16
#ifdef ITIMER_REAL
1558
16
    ADD_INT_MACRO(ITIMER_REAL);
1559
16
#endif
1560
16
#ifdef ITIMER_VIRTUAL
1561
16
    ADD_INT_MACRO(ITIMER_VIRTUAL);
1562
16
#endif
1563
16
#ifdef ITIMER_PROF
1564
16
    ADD_INT_MACRO(ITIMER_PROF);
1565
16
#endif
1566
1567
    // CTRL_xxx Windows signals
1568
#ifdef CTRL_C_EVENT
1569
    ADD_INT_MACRO(CTRL_C_EVENT);
1570
#endif
1571
#ifdef CTRL_BREAK_EVENT
1572
    ADD_INT_MACRO(CTRL_BREAK_EVENT);
1573
#endif
1574
1575
16
    return 0;
1576
1577
16
#undef ADD_INT_MACRO
1578
16
}
1579
1580
1581
static int
1582
signal_get_set_handlers(signal_state_t *state, PyObject *mod_dict)
1583
16
{
1584
    // Get signal handlers
1585
1.04k
    for (int signum = 1; signum < Py_NSIG; signum++) {
1586
1.02k
        void (*c_handler)(int) = PyOS_getsig(signum);
1587
1.02k
        PyObject *func;
1588
1.02k
        if (c_handler == SIG_DFL) {
1589
912
            func = state->default_handler;
1590
912
        }
1591
112
        else if (c_handler == SIG_IGN) {
1592
32
            func = state->ignore_handler;
1593
32
        }
1594
80
        else {
1595
80
            func = Py_None; // None of our business
1596
80
        }
1597
        // If signal_module_exec() is called more than one, we must
1598
        // clear the strong reference to the previous function.
1599
1.02k
        PyObject* old_func = get_handler(signum);
1600
1.02k
        set_handler(signum, Py_NewRef(func));
1601
1.02k
        Py_XDECREF(old_func);
1602
1.02k
    }
1603
1604
    // Install Python SIGINT handler which raises KeyboardInterrupt
1605
16
    PyObject* sigint_func = get_handler(SIGINT);
1606
16
    if (sigint_func == state->default_handler) {
1607
16
        PyObject *int_handler = PyMapping_GetItemString(mod_dict,
1608
16
                                                        "default_int_handler");
1609
16
        if (!int_handler) {
1610
0
            return -1;
1611
0
        }
1612
1613
16
        set_handler(SIGINT, int_handler);
1614
16
        Py_DECREF(sigint_func);
1615
16
        PyOS_setsig(SIGINT, signal_handler);
1616
16
    }
1617
16
    return 0;
1618
16
}
1619
1620
1621
static int
1622
signal_module_exec(PyObject *m)
1623
16
{
1624
16
    assert(!PyErr_Occurred());
1625
1626
16
    signal_state_t *state = &signal_global_state;
1627
16
    _signal_module_state *modstate = get_signal_state(m);
1628
1629
    // XXX For proper isolation, these values must be guaranteed
1630
    // to be effectively const (e.g. immortal).
1631
16
    modstate->default_handler = state->default_handler;  // borrowed ref
1632
16
    modstate->ignore_handler = state->ignore_handler;  // borrowed ref
1633
1634
16
#ifdef PYHAVE_ITIMER_ERROR
1635
16
    modstate->itimer_error = PyErr_NewException("signal.ItimerError",
1636
16
                                                PyExc_OSError, NULL);
1637
16
    if (modstate->itimer_error == NULL) {
1638
0
        return -1;
1639
0
    }
1640
16
#endif
1641
1642
16
    if (signal_add_constants(m) < 0) {
1643
0
        return -1;
1644
0
    }
1645
1646
    /* Add some symbolic constants to the module */
1647
16
    PyObject *d = PyModule_GetDict(m);
1648
16
    if (PyDict_SetItemString(d, "SIG_DFL", state->default_handler) < 0) {
1649
0
        return -1;
1650
0
    }
1651
16
    if (PyDict_SetItemString(d, "SIG_IGN", state->ignore_handler) < 0) {
1652
0
        return -1;
1653
0
    }
1654
16
#ifdef PYHAVE_ITIMER_ERROR
1655
16
    if (PyDict_SetItemString(d, "ItimerError", modstate->itimer_error) < 0) {
1656
0
        return -1;
1657
0
    }
1658
16
#endif
1659
1660
16
#if defined(HAVE_SIGWAITINFO) || defined(HAVE_SIGTIMEDWAIT)
1661
16
    modstate->siginfo_type = PyStructSequence_NewType(&struct_siginfo_desc);
1662
16
    if (modstate->siginfo_type == NULL) {
1663
0
        return -1;
1664
0
    }
1665
16
#endif
1666
16
#if defined(HAVE_SIGWAITINFO) || defined(HAVE_SIGTIMEDWAIT)
1667
16
    if (PyModule_AddType(m, modstate->siginfo_type) < 0) {
1668
0
        return -1;
1669
0
    }
1670
16
#endif
1671
1672
16
    PyThreadState *tstate = _PyThreadState_GET();
1673
16
    if (_Py_IsMainInterpreter(tstate->interp)) {
1674
16
        if (signal_get_set_handlers(state, d) < 0) {
1675
0
            return -1;
1676
0
        }
1677
16
    }
1678
1679
16
    assert(!PyErr_Occurred());
1680
16
    return 0;
1681
16
}
1682
1683
1684
#ifdef PYHAVE_ITIMER_ERROR
1685
static int
1686
_signal_module_traverse(PyObject *module, visitproc visit, void *arg)
1687
3.70k
{
1688
3.70k
    _signal_module_state *state = get_signal_state(module);
1689
3.70k
    Py_VISIT(state->itimer_error);
1690
3.70k
    Py_VISIT(state->siginfo_type);
1691
3.70k
    return 0;
1692
3.70k
}
1693
1694
static int
1695
_signal_module_clear(PyObject *module)
1696
0
{
1697
0
    _signal_module_state *state = get_signal_state(module);
1698
0
    Py_CLEAR(state->itimer_error);
1699
0
    Py_CLEAR(state->siginfo_type);
1700
0
    return 0;
1701
0
}
1702
1703
static void
1704
_signal_module_free(void *module)
1705
0
{
1706
0
    _signal_module_clear((PyObject *)module);
1707
0
}
1708
#endif  // PYHAVE_ITIMER_ERROR
1709
1710
1711
static PyModuleDef_Slot signal_slots[] = {
1712
    {Py_mod_exec, signal_module_exec},
1713
    {Py_mod_multiple_interpreters, Py_MOD_PER_INTERPRETER_GIL_SUPPORTED},
1714
    {Py_mod_gil, Py_MOD_GIL_NOT_USED},
1715
    {0, NULL}
1716
};
1717
1718
static struct PyModuleDef signal_module = {
1719
    PyModuleDef_HEAD_INIT,
1720
    "_signal",
1721
    .m_doc = module_doc,
1722
    .m_size = sizeof(_signal_module_state),
1723
    .m_methods = signal_methods,
1724
    .m_slots = signal_slots,
1725
#ifdef PYHAVE_ITIMER_ERROR
1726
    .m_traverse = _signal_module_traverse,
1727
    .m_clear = _signal_module_clear,
1728
    .m_free = _signal_module_free,
1729
#endif
1730
};
1731
1732
1733
PyMODINIT_FUNC
1734
PyInit__signal(void)
1735
16
{
1736
16
    return PyModuleDef_Init(&signal_module);
1737
16
}
1738
1739
1740
void
1741
_PySignal_Fini(void)
1742
0
{
1743
0
    signal_state_t *state = &signal_global_state;
1744
1745
    // Restore default signals and clear handlers
1746
0
    for (int signum = 1; signum < Py_NSIG; signum++) {
1747
0
        PyObject *func = get_handler(signum);
1748
0
        _Py_atomic_store_int_relaxed(&Handlers[signum].tripped, 0);
1749
0
        set_handler(signum, NULL);
1750
0
        if (func != NULL
1751
0
            && func != Py_None
1752
0
            && !compare_handler(func, state->default_handler)
1753
0
            && !compare_handler(func, state->ignore_handler))
1754
0
        {
1755
0
            PyOS_setsig(signum, SIG_DFL);
1756
0
        }
1757
0
        Py_XDECREF(func);
1758
0
    }
1759
1760
#ifdef MS_WINDOWS
1761
    if (state->sigint_event != NULL) {
1762
        CloseHandle((HANDLE)state->sigint_event);
1763
        state->sigint_event = NULL;
1764
    }
1765
#endif
1766
1767
0
    Py_CLEAR(state->default_handler);
1768
0
    Py_CLEAR(state->ignore_handler);
1769
0
}
1770
1771
1772
/* Declared in pyerrors.h */
1773
int
1774
PyErr_CheckSignals(void)
1775
62.7M
{
1776
62.7M
    PyThreadState *tstate = _PyThreadState_GET();
1777
1778
    /* Opportunistically check if the GC is scheduled to run and run it
1779
       if we have a request. This is done here because native code needs
1780
       to call this API if is going to run for some time without executing
1781
       Python code to ensure signals are handled. Checking for the GC here
1782
       allows long running native code to clean cycles created using the C-API
1783
       even if it doesn't run the evaluation loop */
1784
62.7M
    if (_Py_eval_breaker_bit_is_set(tstate, _PY_GC_SCHEDULED_BIT)) {
1785
10
        _Py_unset_eval_breaker_bit(tstate, _PY_GC_SCHEDULED_BIT);
1786
10
        _Py_RunGC(tstate);
1787
10
    }
1788
1789
62.7M
#if defined(Py_REMOTE_DEBUG) && defined(Py_SUPPORTS_REMOTE_DEBUG)
1790
62.7M
    _PyRunRemoteDebugger(tstate);
1791
62.7M
#endif
1792
1793
62.7M
    if (!_Py_ThreadCanHandleSignals(tstate->interp)) {
1794
0
        return 0;
1795
0
    }
1796
1797
62.7M
    return _PyErr_CheckSignalsTstate(tstate);
1798
62.7M
}
1799
1800
1801
/* Declared in cpython/pyerrors.h */
1802
int
1803
_PyErr_CheckSignalsTstate(PyThreadState *tstate)
1804
62.7M
{
1805
62.7M
    _Py_CHECK_EMSCRIPTEN_SIGNALS();
1806
62.7M
    if (!_Py_atomic_load_int(&is_tripped)) {
1807
62.7M
        return 0;
1808
62.7M
    }
1809
1810
    /*
1811
     * The is_tripped variable is meant to speed up the calls to
1812
     * PyErr_CheckSignals (both directly or via pending calls) when no
1813
     * signal has arrived. This variable is set to 1 when a signal arrives
1814
     * and it is set to 0 here, when we know some signals arrived. This way
1815
     * we can run the registered handlers with no signals blocked.
1816
     *
1817
     * NOTE: with this approach we can have a situation where is_tripped is
1818
     *       1 but we have no more signals to handle (Handlers[i].tripped
1819
     *       is 0 for every signal i). This won't do us any harm (except
1820
     *       we're gonna spent some cycles for nothing). This happens when
1821
     *       we receive a signal i after we zero is_tripped and before we
1822
     *       check Handlers[i].tripped.
1823
     */
1824
0
    _Py_atomic_store_int(&is_tripped, 0);
1825
1826
0
    _PyInterpreterFrame *frame = _PyThreadState_GetFrame(tstate);
1827
0
    signal_state_t *state = &signal_global_state;
1828
0
    for (int i = 1; i < Py_NSIG; i++) {
1829
0
        if (!_Py_atomic_load_int_relaxed(&Handlers[i].tripped)) {
1830
0
            continue;
1831
0
        }
1832
0
        _Py_atomic_store_int_relaxed(&Handlers[i].tripped, 0);
1833
1834
        /* Signal handlers can be modified while a signal is received,
1835
         * and therefore the fact that trip_signal() or PyErr_SetInterrupt()
1836
         * was called doesn't guarantee that there is still a Python
1837
         * signal handler for it by the time PyErr_CheckSignals() is called
1838
         * (see bpo-43406).
1839
         */
1840
0
        PyObject *func = get_handler(i);
1841
0
        if (func == NULL || func == Py_None ||
1842
0
            compare_handler(func, state->ignore_handler) ||
1843
0
            compare_handler(func, state->default_handler)) {
1844
            /* No Python signal handler due to aforementioned race condition.
1845
             * We can't call raise() as it would break the assumption
1846
             * that PyErr_SetInterrupt() only *simulates* an incoming
1847
             * signal (i.e. it will never kill the process).
1848
             * We also don't want to interrupt user code with a cryptic
1849
             * asynchronous exception, so instead just write out an
1850
             * unraisable error.
1851
             */
1852
0
            PyErr_Format(PyExc_OSError,
1853
0
                         "Signal %i ignored due to race condition",
1854
0
                         i);
1855
0
            PyErr_FormatUnraisable("Exception ignored while "
1856
0
                                   "calling signal handler");
1857
0
            continue;
1858
0
        }
1859
0
        PyObject *arglist = NULL;
1860
0
        if (frame == NULL) {
1861
0
            arglist = Py_BuildValue("(iO)", i, Py_None);
1862
0
        }
1863
0
        else {
1864
0
            PyFrameObject *f = _PyFrame_GetFrameObject(frame);
1865
0
            if (f != NULL) {
1866
0
                arglist = Py_BuildValue("(iO)", i, f);
1867
0
            }
1868
0
        }
1869
0
        PyObject *result;
1870
0
        if (arglist) {
1871
0
            result = _PyObject_Call(tstate, func, arglist, NULL);
1872
0
            Py_DECREF(arglist);
1873
0
        }
1874
0
        else {
1875
0
            result = NULL;
1876
0
        }
1877
0
        if (!result) {
1878
            /* On error, re-schedule a call to _PyErr_CheckSignalsTstate() */
1879
0
            _Py_atomic_store_int(&is_tripped, 1);
1880
0
            return -1;
1881
0
        }
1882
1883
0
        Py_DECREF(result);
1884
0
    }
1885
1886
0
    return 0;
1887
0
}
1888
1889
1890
1891
int
1892
_PyErr_CheckSignals(void)
1893
0
{
1894
0
    PyThreadState *tstate = _PyThreadState_GET();
1895
0
    return _PyErr_CheckSignalsTstate(tstate);
1896
0
}
1897
1898
1899
/* Simulate the effect of a signal arriving. The next time PyErr_CheckSignals
1900
   is called,  the corresponding Python signal handler will be raised.
1901
1902
   Missing signal handler for the given signal number is silently ignored. */
1903
int
1904
PyErr_SetInterruptEx(int signum)
1905
0
{
1906
0
    if (signum < 1 || signum >= Py_NSIG) {
1907
0
        return -1;
1908
0
    }
1909
1910
0
    signal_state_t *state = &signal_global_state;
1911
0
    PyObject *func = get_handler(signum);
1912
0
    if (!compare_handler(func, state->ignore_handler)
1913
0
            && !compare_handler(func, state->default_handler)) {
1914
0
        trip_signal(signum);
1915
0
    }
1916
0
    return 0;
1917
0
}
1918
1919
void
1920
PyErr_SetInterrupt(void)
1921
0
{
1922
0
    (void) PyErr_SetInterruptEx(SIGINT);
1923
0
}
1924
1925
static int
1926
signal_install_handlers(void)
1927
16
{
1928
16
#ifdef SIGPIPE
1929
16
    PyOS_setsig(SIGPIPE, SIG_IGN);
1930
16
#endif
1931
#ifdef SIGXFZ
1932
    PyOS_setsig(SIGXFZ, SIG_IGN);
1933
#endif
1934
16
#ifdef SIGXFSZ
1935
16
    PyOS_setsig(SIGXFSZ, SIG_IGN);
1936
16
#endif
1937
1938
    // Import _signal to install the Python SIGINT handler
1939
16
    PyObject *module = PyImport_ImportModule("_signal");
1940
16
    if (!module) {
1941
0
        return -1;
1942
0
    }
1943
16
    Py_DECREF(module);
1944
1945
16
    return 0;
1946
16
}
1947
1948
1949
/* Restore signals that the interpreter has called SIG_IGN on to SIG_DFL.
1950
 *
1951
 * All of the code in this function must only use async-signal-safe functions,
1952
 * listed at `man 7 signal-safety` or
1953
 * http://www.opengroup.org/onlinepubs/009695399/functions/xsh_chap02_04.html.
1954
 *
1955
 * If this function is updated, update also _posix_spawn() of subprocess.py.
1956
 */
1957
void
1958
_Py_RestoreSignals(void)
1959
0
{
1960
0
#ifdef SIGPIPE
1961
0
    PyOS_setsig(SIGPIPE, SIG_DFL);
1962
0
#endif
1963
#ifdef SIGXFZ
1964
    PyOS_setsig(SIGXFZ, SIG_DFL);
1965
#endif
1966
0
#ifdef SIGXFSZ
1967
0
    PyOS_setsig(SIGXFSZ, SIG_DFL);
1968
0
#endif
1969
0
}
1970
1971
1972
int
1973
_PySignal_Init(int install_signal_handlers)
1974
16
{
1975
16
    signal_state_t *state = &signal_global_state;
1976
1977
16
    state->default_handler = PyLong_FromVoidPtr((void *)SIG_DFL);
1978
16
    if (state->default_handler == NULL) {
1979
0
        return -1;
1980
0
    }
1981
1982
16
    state->ignore_handler = PyLong_FromVoidPtr((void *)SIG_IGN);
1983
16
    if (state->ignore_handler == NULL) {
1984
0
        return -1;
1985
0
    }
1986
1987
#ifdef MS_WINDOWS
1988
    /* Create manual-reset event, initially unset */
1989
    state->sigint_event = (void *)CreateEvent(NULL, TRUE, FALSE, FALSE);
1990
    if (state->sigint_event == NULL) {
1991
        PyErr_SetFromWindowsErr(0);
1992
        return -1;
1993
    }
1994
#endif
1995
1996
1.04k
    for (int signum = 1; signum < Py_NSIG; signum++) {
1997
1.02k
        _Py_atomic_store_int_relaxed(&Handlers[signum].tripped, 0);
1998
1.02k
    }
1999
2000
16
    if (install_signal_handlers) {
2001
16
        if (signal_install_handlers() < 0) {
2002
0
            return -1;
2003
0
        }
2004
16
    }
2005
2006
16
    return 0;
2007
16
}
2008
2009
2010
// The caller doesn't have to hold the GIL
2011
int
2012
_PyOS_InterruptOccurred(PyThreadState *tstate)
2013
0
{
2014
0
    _Py_EnsureTstateNotNULL(tstate);
2015
0
    if (!_Py_ThreadCanHandleSignals(tstate->interp)) {
2016
0
        return 0;
2017
0
    }
2018
2019
0
    if (!_Py_atomic_load_int_relaxed(&Handlers[SIGINT].tripped)) {
2020
0
        return 0;
2021
0
    }
2022
2023
0
    _Py_atomic_store_int_relaxed(&Handlers[SIGINT].tripped, 0);
2024
0
    return 1;
2025
0
}
2026
2027
2028
// The caller must to hold the GIL
2029
int
2030
PyOS_InterruptOccurred(void)
2031
0
{
2032
0
    PyThreadState *tstate = _PyThreadState_GET();
2033
0
    return _PyOS_InterruptOccurred(tstate);
2034
0
}
2035
2036
2037
#ifdef HAVE_FORK
2038
static void
2039
_clear_pending_signals(void)
2040
0
{
2041
0
    if (!_Py_atomic_load_int(&is_tripped)) {
2042
0
        return;
2043
0
    }
2044
2045
0
    _Py_atomic_store_int(&is_tripped, 0);
2046
0
    for (int i = 1; i < Py_NSIG; ++i) {
2047
0
        _Py_atomic_store_int_relaxed(&Handlers[i].tripped, 0);
2048
0
    }
2049
0
}
2050
2051
void
2052
_PySignal_AfterFork(void)
2053
0
{
2054
    /* Clear the signal flags after forking so that they aren't handled
2055
     * in both processes if they came in just before the fork() but before
2056
     * the interpreter had an opportunity to call the handlers.  issue9535. */
2057
0
    _clear_pending_signals();
2058
0
}
2059
#endif   /* HAVE_FORK */
2060
2061
2062
int
2063
_PyOS_IsMainThread(void)
2064
0
{
2065
0
    PyInterpreterState *interp = _PyInterpreterState_GET();
2066
0
    return _Py_ThreadCanHandleSignals(interp);
2067
0
}
2068
2069
#ifdef MS_WINDOWS
2070
/* Returns a manual-reset event which gets tripped whenever
2071
   SIGINT is received.
2072
2073
   Python.h does not include windows.h so we do cannot use HANDLE
2074
   as the return type of this function.  We use void* instead. */
2075
void *_PyOS_SigintEvent(void)
2076
{
2077
    signal_state_t *state = &signal_global_state;
2078
    return state->sigint_event;
2079
}
2080
#endif