Coverage Report

Created: 2026-10-17 06:15

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