Coverage Report

Created: 2026-05-30 06:18

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