Coverage Report

Created: 2026-04-12 06:54

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
6.98k
#define Handlers _PyRuntime.signals.handlers
107
0
#define wakeup _PyRuntime.signals.wakeup
108
74.7M
#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
72
#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.34k
{
131
2.34k
    return (PyObject *)_Py_atomic_load_ptr(&Handlers[i].func);
132
2.34k
}
133
134
Py_LOCAL_INLINE(void)
135
set_handler(int i, PyObject* func)
136
2.34k
{
137
    /* Store func with atomic operation to ensure
138
       that PyErr_SetInterrupt is async-signal-safe. */
139
2.34k
    _Py_atomic_store_ptr(&Handlers[i].func, func);
140
2.34k
}
141
142
143
static inline _signal_module_state*
144
get_signal_state(PyObject *module)
145
1.84k
{
146
1.84k
    void *state = _PyModule_GetState(module);
147
1.84k
    assert(state != NULL);
148
1.84k
    return (_signal_module_state *)state;
149
1.84k
}
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
@permit_long_docstring_body
454
signal.signal
455
456
    signalnum: int
457
    handler:   object
458
    /
459
460
Set the action for the given signal.
461
462
The action can be SIG_DFL, SIG_IGN, or a callable Python object.
463
The previous action is returned.  See getsignal() for possible return values.
464
465
*** IMPORTANT NOTICE ***
466
A signal handler function is called with two arguments:
467
the first is 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=7608656f34fa378b]*/
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
@permit_long_docstring_body
843
signal.setitimer
844
845
    which:    int
846
    seconds:  object
847
    interval: object(c_default="NULL") = 0.0
848
    /
849
850
Sets given itimer (one of ITIMER_REAL, ITIMER_VIRTUAL or ITIMER_PROF).
851
852
The timer will fire after value seconds and after that every interval seconds.
853
The itimer can be cleared by setting seconds to zero.
854
855
Returns old values as a tuple: (delay, interval).
856
[clinic start generated code]*/
857
858
static PyObject *
859
signal_setitimer_impl(PyObject *module, int which, PyObject *seconds,
860
                      PyObject *interval)
861
/*[clinic end generated code: output=65f9dcbddc35527b input=ab5bf2b8f5cff3f4]*/
862
0
{
863
0
    _signal_module_state *modstate = get_signal_state(module);
864
865
0
    struct itimerval new;
866
0
    if (timeval_from_double(seconds, &new.it_value) < 0) {
867
0
        return NULL;
868
0
    }
869
0
    if (timeval_from_double(interval, &new.it_interval) < 0) {
870
0
        return NULL;
871
0
    }
872
873
    /* Let OS check "which" value */
874
0
    struct itimerval old;
875
0
    if (setitimer(which, &new, &old) != 0) {
876
0
        PyErr_SetFromErrno(modstate->itimer_error);
877
0
        return NULL;
878
0
    }
879
880
0
    return itimer_retval(&old);
881
0
}
882
#endif  // HAVE_SETITIMER
883
884
885
#ifdef HAVE_GETITIMER
886
/*[clinic input]
887
signal.getitimer
888
889
    which:    int
890
    /
891
892
Returns current value of given itimer.
893
[clinic start generated code]*/
894
895
static PyObject *
896
signal_getitimer_impl(PyObject *module, int which)
897
/*[clinic end generated code: output=9e053175d517db40 input=f7d21d38f3490627]*/
898
0
{
899
0
    _signal_module_state *modstate = get_signal_state(module);
900
901
0
    struct itimerval old;
902
0
    if (getitimer(which, &old) != 0) {
903
0
        PyErr_SetFromErrno(modstate->itimer_error);
904
0
        return NULL;
905
0
    }
906
907
0
    return itimer_retval(&old);
908
0
}
909
#endif // HAVE_GETITIMER
910
911
912
#ifdef HAVE_SIGSET_T
913
#if defined(PYPTHREAD_SIGMASK) || defined(HAVE_SIGPENDING)
914
static PyObject*
915
sigset_to_set(sigset_t mask)
916
0
{
917
0
    PyObject *signum, *result;
918
0
    int sig;
919
920
0
    result = PySet_New(0);
921
0
    if (result == NULL)
922
0
        return NULL;
923
924
0
    for (sig = 1; sig < Py_NSIG; sig++) {
925
0
        if (sigismember(&mask, sig) != 1)
926
0
            continue;
927
928
        /* Handle the case where it is a member by adding the signal to
929
           the result list.  Ignore the other cases because they mean the
930
           signal isn't a member of the mask or the signal was invalid,
931
           and an invalid signal must have been our fault in constructing
932
           the loop boundaries. */
933
0
        signum = PyLong_FromLong(sig);
934
0
        if (signum == NULL) {
935
0
            Py_DECREF(result);
936
0
            return NULL;
937
0
        }
938
0
        if (PySet_Add(result, signum) == -1) {
939
0
            Py_DECREF(signum);
940
0
            Py_DECREF(result);
941
0
            return NULL;
942
0
        }
943
0
        Py_DECREF(signum);
944
0
    }
945
0
    return result;
946
0
}
947
#endif
948
949
#ifdef PYPTHREAD_SIGMASK
950
951
/*[clinic input]
952
signal.pthread_sigmask
953
954
    how:  int
955
    mask: sigset_t
956
    /
957
958
Fetch and/or change the signal mask of the calling thread.
959
[clinic start generated code]*/
960
961
static PyObject *
962
signal_pthread_sigmask_impl(PyObject *module, int how, sigset_t mask)
963
/*[clinic end generated code: output=0562c0fb192981a8 input=85bcebda442fa77f]*/
964
0
{
965
0
    sigset_t previous;
966
0
    int err;
967
968
0
    err = pthread_sigmask(how, &mask, &previous);
969
0
    if (err != 0) {
970
0
        errno = err;
971
0
        PyErr_SetFromErrno(PyExc_OSError);
972
0
        return NULL;
973
0
    }
974
975
    /* if signals was unblocked, signal handlers have been called */
976
0
    if (PyErr_CheckSignals())
977
0
        return NULL;
978
979
0
    return sigset_to_set(previous);
980
0
}
981
982
#endif   /* #ifdef PYPTHREAD_SIGMASK */
983
984
985
#ifdef HAVE_SIGPENDING
986
987
/*[clinic input]
988
signal.sigpending
989
990
Examine pending signals.
991
992
Returns a set of signal numbers that are pending for delivery to
993
the calling thread.
994
[clinic start generated code]*/
995
996
static PyObject *
997
signal_sigpending_impl(PyObject *module)
998
/*[clinic end generated code: output=53375ffe89325022 input=e0036c016f874e29]*/
999
0
{
1000
0
    int err;
1001
0
    sigset_t mask;
1002
0
    err = sigpending(&mask);
1003
0
    if (err)
1004
0
        return PyErr_SetFromErrno(PyExc_OSError);
1005
0
    return sigset_to_set(mask);
1006
0
}
1007
1008
#endif   /* #ifdef HAVE_SIGPENDING */
1009
1010
1011
#ifdef HAVE_SIGWAIT
1012
1013
/*[clinic input]
1014
signal.sigwait
1015
1016
    sigset: sigset_t
1017
    /
1018
1019
Wait for a signal.
1020
1021
Suspend execution of the calling thread until the delivery of one of the
1022
signals specified in the signal set sigset.  The function accepts the signal
1023
and returns the signal number.
1024
[clinic start generated code]*/
1025
1026
static PyObject *
1027
signal_sigwait_impl(PyObject *module, sigset_t sigset)
1028
/*[clinic end generated code: output=f43770699d682f96 input=a6fbd47b1086d119]*/
1029
0
{
1030
0
    int err, signum;
1031
1032
0
    Py_BEGIN_ALLOW_THREADS
1033
0
    err = sigwait(&sigset, &signum);
1034
0
    Py_END_ALLOW_THREADS
1035
0
    if (err) {
1036
0
        errno = err;
1037
0
        return PyErr_SetFromErrno(PyExc_OSError);
1038
0
    }
1039
1040
0
    return PyLong_FromLong(signum);
1041
0
}
1042
1043
#endif   /* #ifdef HAVE_SIGWAIT */
1044
#endif   /* #ifdef HAVE_SIGSET_T */
1045
1046
#if (defined(HAVE_SIGFILLSET) && defined(HAVE_SIGSET_T)) || defined(MS_WINDOWS)
1047
1048
/*[clinic input]
1049
signal.valid_signals
1050
1051
Return a set of valid signal numbers on this platform.
1052
1053
The signal numbers returned by this function can be safely passed to
1054
functions like `pthread_sigmask`.
1055
[clinic start generated code]*/
1056
1057
static PyObject *
1058
signal_valid_signals_impl(PyObject *module)
1059
/*[clinic end generated code: output=1609cffbcfcf1314 input=86a3717ff25288f2]*/
1060
0
{
1061
#ifdef MS_WINDOWS
1062
#ifdef SIGBREAK
1063
    PyObject *tup = Py_BuildValue("(iiiiiii)", SIGABRT, SIGBREAK, SIGFPE,
1064
                                  SIGILL, SIGINT, SIGSEGV, SIGTERM);
1065
#else
1066
    PyObject *tup = Py_BuildValue("(iiiiii)", SIGABRT, SIGFPE, SIGILL,
1067
                                  SIGINT, SIGSEGV, SIGTERM);
1068
#endif
1069
    if (tup == NULL) {
1070
        return NULL;
1071
    }
1072
    PyObject *set = PySet_New(tup);
1073
    Py_DECREF(tup);
1074
    return set;
1075
#else
1076
0
    sigset_t mask;
1077
0
    if (sigemptyset(&mask) || sigfillset(&mask)) {
1078
0
        return PyErr_SetFromErrno(PyExc_OSError);
1079
0
    }
1080
0
    return sigset_to_set(mask);
1081
0
#endif
1082
0
}
1083
1084
#endif   /* #if (defined(HAVE_SIGFILLSET) && defined(HAVE_SIGSET_T)) || defined(MS_WINDOWS) */
1085
1086
1087
1088
#if defined(HAVE_SIGWAITINFO) || defined(HAVE_SIGTIMEDWAIT)
1089
static PyStructSequence_Field struct_siginfo_fields[] = {
1090
    {"si_signo",        "signal number"},
1091
    {"si_code",         "signal code"},
1092
    {"si_errno",        "errno associated with this signal"},
1093
    {"si_pid",          "sending process ID"},
1094
    {"si_uid",          "real user ID of sending process"},
1095
    {"si_status",       "exit value or signal"},
1096
    {"si_band",         "band event for SIGPOLL"},
1097
    {0}
1098
};
1099
1100
PyDoc_STRVAR(struct_siginfo__doc__,
1101
"struct_siginfo: Result from sigwaitinfo or sigtimedwait.\n\n\
1102
This object may be accessed either as a tuple of\n\
1103
(si_signo, si_code, si_errno, si_pid, si_uid, si_status, si_band),\n\
1104
or via the attributes si_signo, si_code, and so on.");
1105
1106
static PyStructSequence_Desc struct_siginfo_desc = {
1107
    "signal.struct_siginfo",           /* name */
1108
    struct_siginfo__doc__,       /* doc */
1109
    struct_siginfo_fields,       /* fields */
1110
    7          /* n_in_sequence */
1111
};
1112
1113
1114
static PyObject *
1115
fill_siginfo(_signal_module_state *state, siginfo_t *si)
1116
0
{
1117
0
    PyObject *result = PyStructSequence_New(state->siginfo_type);
1118
0
    if (!result)
1119
0
        return NULL;
1120
1121
0
    PyStructSequence_SET_ITEM(result, 0, PyLong_FromLong((long)(si->si_signo)));
1122
0
    PyStructSequence_SET_ITEM(result, 1, PyLong_FromLong((long)(si->si_code)));
1123
#ifdef __VXWORKS__
1124
    PyStructSequence_SET_ITEM(result, 2, PyLong_FromLong(0L));
1125
    PyStructSequence_SET_ITEM(result, 3, PyLong_FromLong(0L));
1126
    PyStructSequence_SET_ITEM(result, 4, PyLong_FromLong(0L));
1127
    PyStructSequence_SET_ITEM(result, 5, PyLong_FromLong(0L));
1128
#else
1129
0
    PyStructSequence_SET_ITEM(result, 2, PyLong_FromLong((long)(si->si_errno)));
1130
0
    PyStructSequence_SET_ITEM(result, 3, PyLong_FromPid(si->si_pid));
1131
0
    PyStructSequence_SET_ITEM(result, 4, _PyLong_FromUid(si->si_uid));
1132
0
    PyStructSequence_SET_ITEM(result, 5,
1133
0
                                PyLong_FromLong((long)(si->si_status)));
1134
0
#endif
1135
0
#ifdef HAVE_SIGINFO_T_SI_BAND
1136
0
    PyStructSequence_SET_ITEM(result, 6, PyLong_FromLong(si->si_band));
1137
#else
1138
    PyStructSequence_SET_ITEM(result, 6, PyLong_FromLong(0L));
1139
#endif
1140
0
    if (PyErr_Occurred()) {
1141
0
        Py_DECREF(result);
1142
0
        return NULL;
1143
0
    }
1144
1145
0
    return result;
1146
0
}
1147
#endif
1148
1149
#ifdef HAVE_SIGSET_T
1150
#ifdef HAVE_SIGWAITINFO
1151
1152
/*[clinic input]
1153
signal.sigwaitinfo
1154
1155
    sigset: sigset_t
1156
    /
1157
1158
Wait synchronously until one of the signals in *sigset* is delivered.
1159
1160
Returns a struct_siginfo containing information about the signal.
1161
[clinic start generated code]*/
1162
1163
static PyObject *
1164
signal_sigwaitinfo_impl(PyObject *module, sigset_t sigset)
1165
/*[clinic end generated code: output=1eb2f1fa236fdbca input=3d1a7e1f27fc664c]*/
1166
0
{
1167
0
    siginfo_t si;
1168
0
    int err;
1169
0
    int async_err = 0;
1170
1171
0
    do {
1172
0
        Py_BEGIN_ALLOW_THREADS
1173
0
        err = sigwaitinfo(&sigset, &si);
1174
0
        Py_END_ALLOW_THREADS
1175
0
    } while (err == -1
1176
0
             && (errno == EINTR
1177
#if defined(__NetBSD__)
1178
                 /* NetBSD's implementation violates POSIX by setting
1179
                  * errno to ECANCELED instead of EINTR. */
1180
                 || errno == ECANCELED
1181
#endif
1182
0
            ) && !(async_err = PyErr_CheckSignals()));
1183
0
    if (err == -1)
1184
0
        return (!async_err) ? PyErr_SetFromErrno(PyExc_OSError) : NULL;
1185
1186
0
    _signal_module_state *state = get_signal_state(module);
1187
0
    return fill_siginfo(state, &si);
1188
0
}
1189
1190
#endif   /* #ifdef HAVE_SIGWAITINFO */
1191
1192
#ifdef HAVE_SIGTIMEDWAIT
1193
1194
/*[clinic input]
1195
signal.sigtimedwait
1196
1197
    sigset: sigset_t
1198
    timeout as timeout_obj: object
1199
    /
1200
1201
Like sigwaitinfo(), but with a timeout.
1202
1203
The timeout is specified in seconds, rounded up to nanoseconds.
1204
[clinic start generated code]*/
1205
1206
static PyObject *
1207
signal_sigtimedwait_impl(PyObject *module, sigset_t sigset,
1208
                         PyObject *timeout_obj)
1209
/*[clinic end generated code: output=59c8971e8ae18a64 input=f89af57d645e48e0]*/
1210
0
{
1211
0
    PyTime_t timeout;
1212
0
    if (_PyTime_FromSecondsObject(&timeout,
1213
0
                                  timeout_obj, _PyTime_ROUND_CEILING) < 0)
1214
0
        return NULL;
1215
1216
0
    if (timeout < 0) {
1217
0
        PyErr_SetString(PyExc_ValueError, "timeout must be non-negative");
1218
0
        return NULL;
1219
0
    }
1220
1221
0
    PyTime_t deadline = _PyDeadline_Init(timeout);
1222
0
    siginfo_t si;
1223
1224
0
    do {
1225
0
        struct timespec ts;
1226
0
        if (_PyTime_AsTimespec(timeout, &ts) < 0) {
1227
0
            return NULL;
1228
0
        }
1229
1230
0
        int res;
1231
0
        Py_BEGIN_ALLOW_THREADS
1232
0
        res = sigtimedwait(&sigset, &si, &ts);
1233
0
        Py_END_ALLOW_THREADS
1234
1235
0
        if (res != -1)
1236
0
            break;
1237
1238
0
        if (errno != EINTR) {
1239
0
            if (errno == EAGAIN)
1240
0
                Py_RETURN_NONE;
1241
0
            else
1242
0
                return PyErr_SetFromErrno(PyExc_OSError);
1243
0
        }
1244
1245
        /* sigtimedwait() was interrupted by a signal (EINTR) */
1246
0
        if (PyErr_CheckSignals())
1247
0
            return NULL;
1248
1249
0
        timeout = _PyDeadline_Get(deadline);
1250
0
        if (timeout < 0) {
1251
0
            break;
1252
0
        }
1253
0
    } while (1);
1254
1255
0
    _signal_module_state *state = get_signal_state(module);
1256
0
    return fill_siginfo(state, &si);
1257
0
}
1258
1259
#endif   /* #ifdef HAVE_SIGTIMEDWAIT */
1260
#endif   /* #ifdef HAVE_SIGSET_T */
1261
1262
1263
#if defined(HAVE_PTHREAD_KILL)
1264
1265
/*[clinic input]
1266
signal.pthread_kill
1267
1268
    thread_id:  unsigned_long(bitwise=True)
1269
    signalnum:  int
1270
    /
1271
1272
Send a signal to a thread.
1273
[clinic start generated code]*/
1274
1275
static PyObject *
1276
signal_pthread_kill_impl(PyObject *module, unsigned long thread_id,
1277
                         int signalnum)
1278
/*[clinic end generated code: output=7629919b791bc27f input=1d901f2c7bb544ff]*/
1279
0
{
1280
0
    int err;
1281
1282
0
    if (PySys_Audit("signal.pthread_kill", "ki", thread_id, signalnum) < 0) {
1283
0
        return NULL;
1284
0
    }
1285
1286
0
    err = pthread_kill((pthread_t)thread_id, signalnum);
1287
0
    if (err != 0) {
1288
0
        errno = err;
1289
0
        PyErr_SetFromErrno(PyExc_OSError);
1290
0
        return NULL;
1291
0
    }
1292
1293
    /* the signal may have been send to the current thread */
1294
0
    if (PyErr_CheckSignals())
1295
0
        return NULL;
1296
1297
0
    Py_RETURN_NONE;
1298
0
}
1299
1300
#endif   /* #if defined(HAVE_PTHREAD_KILL) */
1301
1302
1303
// This system call always crashes on older Android versions.
1304
#if defined(__linux__) && defined(__NR_pidfd_send_signal) && \
1305
    !(defined(__ANDROID__) && __ANDROID_API__ < 31)
1306
/*[clinic input]
1307
signal.pidfd_send_signal
1308
1309
    pidfd: int
1310
    signalnum: int
1311
    siginfo: object = None
1312
    flags: int = 0
1313
    /
1314
1315
Send a signal to a process referred to by a pid file descriptor.
1316
[clinic start generated code]*/
1317
1318
static PyObject *
1319
signal_pidfd_send_signal_impl(PyObject *module, int pidfd, int signalnum,
1320
                              PyObject *siginfo, int flags)
1321
/*[clinic end generated code: output=2d59f04a75d9cbdf input=2a6543a1f4ac2000]*/
1322
1323
0
{
1324
0
    if (siginfo != Py_None) {
1325
0
        PyErr_SetString(PyExc_TypeError, "siginfo must be None");
1326
0
        return NULL;
1327
0
    }
1328
0
    if (syscall(__NR_pidfd_send_signal, pidfd, signalnum, NULL, flags) < 0) {
1329
0
        PyErr_SetFromErrno(PyExc_OSError);
1330
0
        return NULL;
1331
0
    }
1332
0
    Py_RETURN_NONE;
1333
0
}
1334
#endif
1335
1336
1337
1338
/* List of functions defined in the module -- some of the methoddefs are
1339
   defined to nothing if the corresponding C function is not available. */
1340
static PyMethodDef signal_methods[] = {
1341
    SIGNAL_DEFAULT_INT_HANDLER_METHODDEF
1342
    SIGNAL_ALARM_METHODDEF
1343
    SIGNAL_SETITIMER_METHODDEF
1344
    SIGNAL_GETITIMER_METHODDEF
1345
    SIGNAL_SIGNAL_METHODDEF
1346
    SIGNAL_RAISE_SIGNAL_METHODDEF
1347
    SIGNAL_STRSIGNAL_METHODDEF
1348
    SIGNAL_GETSIGNAL_METHODDEF
1349
    SIGNAL_SET_WAKEUP_FD_METHODDEF
1350
    SIGNAL_SIGINTERRUPT_METHODDEF
1351
    SIGNAL_PAUSE_METHODDEF
1352
    SIGNAL_PIDFD_SEND_SIGNAL_METHODDEF
1353
    SIGNAL_PTHREAD_KILL_METHODDEF
1354
    SIGNAL_PTHREAD_SIGMASK_METHODDEF
1355
    SIGNAL_SIGPENDING_METHODDEF
1356
    SIGNAL_SIGWAIT_METHODDEF
1357
    SIGNAL_SIGWAITINFO_METHODDEF
1358
    SIGNAL_SIGTIMEDWAIT_METHODDEF
1359
#if defined(HAVE_SIGFILLSET) || defined(MS_WINDOWS)
1360
    SIGNAL_VALID_SIGNALS_METHODDEF
1361
#endif
1362
    {NULL, NULL}           /* sentinel */
1363
};
1364
1365
1366
PyDoc_STRVAR(module_doc,
1367
"This module provides mechanisms to use signal handlers in Python.\n\
1368
\n\
1369
Functions:\n\
1370
\n\
1371
alarm() -- cause SIGALRM after a specified time [Unix only]\n\
1372
setitimer() -- cause a signal (described below) after a specified\n\
1373
               float time and the timer may restart then [Unix only]\n\
1374
getitimer() -- get current value of timer [Unix only]\n\
1375
signal() -- set the action for a given signal\n\
1376
getsignal() -- get the signal action for a given signal\n\
1377
pause() -- wait until a signal arrives [Unix only]\n\
1378
default_int_handler() -- default SIGINT handler\n\
1379
\n\
1380
signal constants:\n\
1381
SIG_DFL -- used to refer to the system default handler\n\
1382
SIG_IGN -- used to ignore the signal\n\
1383
NSIG -- number of defined signals\n\
1384
SIGINT, SIGTERM, etc. -- signal numbers\n\
1385
\n\
1386
itimer constants:\n\
1387
ITIMER_REAL -- decrements in real time, and delivers SIGALRM upon\n\
1388
               expiration\n\
1389
ITIMER_VIRTUAL -- decrements only when the process is executing,\n\
1390
               and delivers SIGVTALRM upon expiration\n\
1391
ITIMER_PROF -- decrements both when the process is executing and\n\
1392
               when the system is executing on behalf of the process.\n\
1393
               Coupled with ITIMER_VIRTUAL, this timer is usually\n\
1394
               used to profile the time spent by the application\n\
1395
               in user and kernel space. SIGPROF is delivered upon\n\
1396
               expiration.\n\
1397
\n\n\
1398
*** IMPORTANT NOTICE ***\n\
1399
A signal handler function is called with two arguments:\n\
1400
the first is the signal number, the second is the interrupted stack frame.");
1401
1402
1403
1404
static int
1405
signal_add_constants(PyObject *module)
1406
36
{
1407
36
    if (PyModule_AddIntConstant(module, "NSIG", Py_NSIG) < 0) {
1408
0
        return -1;
1409
0
    }
1410
1411
36
#define ADD_INT_MACRO(macro) \
1412
1.51k
    if (PyModule_AddIntConstant(module, #macro, macro) < 0) { \
1413
0
        return -1; \
1414
0
    }
1415
1416
    // SIG_xxx pthread_sigmask() constants
1417
36
#ifdef SIG_BLOCK
1418
36
    ADD_INT_MACRO(SIG_BLOCK);
1419
36
#endif
1420
36
#ifdef SIG_UNBLOCK
1421
36
    ADD_INT_MACRO(SIG_UNBLOCK);
1422
36
#endif
1423
36
#ifdef SIG_SETMASK
1424
36
    ADD_INT_MACRO(SIG_SETMASK);
1425
36
#endif
1426
1427
    // SIGxxx signal number constants
1428
36
#ifdef SIGHUP
1429
36
    ADD_INT_MACRO(SIGHUP);
1430
36
#endif
1431
36
#ifdef SIGINT
1432
36
    ADD_INT_MACRO(SIGINT);
1433
36
#endif
1434
#ifdef SIGBREAK
1435
    ADD_INT_MACRO(SIGBREAK);
1436
#endif
1437
36
#ifdef SIGQUIT
1438
36
    ADD_INT_MACRO(SIGQUIT);
1439
36
#endif
1440
36
#ifdef SIGILL
1441
36
    ADD_INT_MACRO(SIGILL);
1442
36
#endif
1443
36
#ifdef SIGTRAP
1444
36
    ADD_INT_MACRO(SIGTRAP);
1445
36
#endif
1446
36
#ifdef SIGIOT
1447
36
    ADD_INT_MACRO(SIGIOT);
1448
36
#endif
1449
36
#ifdef SIGABRT
1450
36
    ADD_INT_MACRO(SIGABRT);
1451
36
#endif
1452
#ifdef SIGEMT
1453
    ADD_INT_MACRO(SIGEMT);
1454
#endif
1455
36
#ifdef SIGFPE
1456
36
    ADD_INT_MACRO(SIGFPE);
1457
36
#endif
1458
36
#ifdef SIGKILL
1459
36
    ADD_INT_MACRO(SIGKILL);
1460
36
#endif
1461
36
#ifdef SIGBUS
1462
36
    ADD_INT_MACRO(SIGBUS);
1463
36
#endif
1464
36
#ifdef SIGSEGV
1465
36
    ADD_INT_MACRO(SIGSEGV);
1466
36
#endif
1467
36
#ifdef SIGSYS
1468
36
    ADD_INT_MACRO(SIGSYS);
1469
36
#endif
1470
36
#ifdef SIGPIPE
1471
36
    ADD_INT_MACRO(SIGPIPE);
1472
36
#endif
1473
36
#ifdef SIGALRM
1474
36
    ADD_INT_MACRO(SIGALRM);
1475
36
#endif
1476
36
#ifdef SIGTERM
1477
36
    ADD_INT_MACRO(SIGTERM);
1478
36
#endif
1479
36
#ifdef SIGUSR1
1480
36
    ADD_INT_MACRO(SIGUSR1);
1481
36
#endif
1482
36
#ifdef SIGUSR2
1483
36
    ADD_INT_MACRO(SIGUSR2);
1484
36
#endif
1485
36
#ifdef SIGCLD
1486
36
    ADD_INT_MACRO(SIGCLD);
1487
36
#endif
1488
36
#ifdef SIGCHLD
1489
36
    ADD_INT_MACRO(SIGCHLD);
1490
36
#endif
1491
36
#ifdef SIGPWR
1492
36
    ADD_INT_MACRO(SIGPWR);
1493
36
#endif
1494
36
#ifdef SIGIO
1495
36
    ADD_INT_MACRO(SIGIO);
1496
36
#endif
1497
36
#ifdef SIGURG
1498
36
    ADD_INT_MACRO(SIGURG);
1499
36
#endif
1500
36
#ifdef SIGWINCH
1501
36
    ADD_INT_MACRO(SIGWINCH);
1502
36
#endif
1503
36
#ifdef SIGPOLL
1504
36
    ADD_INT_MACRO(SIGPOLL);
1505
36
#endif
1506
36
#ifdef SIGSTOP
1507
36
    ADD_INT_MACRO(SIGSTOP);
1508
36
#endif
1509
36
#ifdef SIGTSTP
1510
36
    ADD_INT_MACRO(SIGTSTP);
1511
36
#endif
1512
36
#ifdef SIGCONT
1513
36
    ADD_INT_MACRO(SIGCONT);
1514
36
#endif
1515
36
#ifdef SIGTTIN
1516
36
    ADD_INT_MACRO(SIGTTIN);
1517
36
#endif
1518
36
#ifdef SIGTTOU
1519
36
    ADD_INT_MACRO(SIGTTOU);
1520
36
#endif
1521
36
#ifdef SIGVTALRM
1522
36
    ADD_INT_MACRO(SIGVTALRM);
1523
36
#endif
1524
36
#ifdef SIGPROF
1525
36
    ADD_INT_MACRO(SIGPROF);
1526
36
#endif
1527
36
#ifdef SIGXCPU
1528
36
    ADD_INT_MACRO(SIGXCPU);
1529
36
#endif
1530
36
#ifdef SIGXFSZ
1531
36
    ADD_INT_MACRO(SIGXFSZ);
1532
36
#endif
1533
36
#ifdef SIGRTMIN
1534
36
    ADD_INT_MACRO(SIGRTMIN);
1535
36
#endif
1536
36
#ifdef SIGRTMAX
1537
36
    ADD_INT_MACRO(SIGRTMAX);
1538
36
#endif
1539
#ifdef SIGINFO
1540
    ADD_INT_MACRO(SIGINFO);
1541
#endif
1542
36
#ifdef SIGSTKFLT
1543
36
    ADD_INT_MACRO(SIGSTKFLT);
1544
36
#endif
1545
1546
    // ITIMER_xxx constants
1547
36
#ifdef ITIMER_REAL
1548
36
    ADD_INT_MACRO(ITIMER_REAL);
1549
36
#endif
1550
36
#ifdef ITIMER_VIRTUAL
1551
36
    ADD_INT_MACRO(ITIMER_VIRTUAL);
1552
36
#endif
1553
36
#ifdef ITIMER_PROF
1554
36
    ADD_INT_MACRO(ITIMER_PROF);
1555
36
#endif
1556
1557
    // CTRL_xxx Windows signals
1558
#ifdef CTRL_C_EVENT
1559
    ADD_INT_MACRO(CTRL_C_EVENT);
1560
#endif
1561
#ifdef CTRL_BREAK_EVENT
1562
    ADD_INT_MACRO(CTRL_BREAK_EVENT);
1563
#endif
1564
1565
36
    return 0;
1566
1567
36
#undef ADD_INT_MACRO
1568
36
}
1569
1570
1571
static int
1572
signal_get_set_handlers(signal_state_t *state, PyObject *mod_dict)
1573
36
{
1574
    // Get signal handlers
1575
2.34k
    for (int signum = 1; signum < Py_NSIG; signum++) {
1576
2.30k
        void (*c_handler)(int) = PyOS_getsig(signum);
1577
2.30k
        PyObject *func;
1578
2.30k
        if (c_handler == SIG_DFL) {
1579
2.05k
            func = state->default_handler;
1580
2.05k
        }
1581
252
        else if (c_handler == SIG_IGN) {
1582
72
            func = state->ignore_handler;
1583
72
        }
1584
180
        else {
1585
180
            func = Py_None; // None of our business
1586
180
        }
1587
        // If signal_module_exec() is called more than one, we must
1588
        // clear the strong reference to the previous function.
1589
2.30k
        PyObject* old_func = get_handler(signum);
1590
2.30k
        set_handler(signum, Py_NewRef(func));
1591
2.30k
        Py_XDECREF(old_func);
1592
2.30k
    }
1593
1594
    // Install Python SIGINT handler which raises KeyboardInterrupt
1595
36
    PyObject* sigint_func = get_handler(SIGINT);
1596
36
    if (sigint_func == state->default_handler) {
1597
36
        PyObject *int_handler = PyMapping_GetItemString(mod_dict,
1598
36
                                                        "default_int_handler");
1599
36
        if (!int_handler) {
1600
0
            return -1;
1601
0
        }
1602
1603
36
        set_handler(SIGINT, int_handler);
1604
36
        Py_DECREF(sigint_func);
1605
36
        PyOS_setsig(SIGINT, signal_handler);
1606
36
    }
1607
36
    return 0;
1608
36
}
1609
1610
1611
static int
1612
signal_module_exec(PyObject *m)
1613
36
{
1614
36
    assert(!PyErr_Occurred());
1615
1616
36
    signal_state_t *state = &signal_global_state;
1617
36
    _signal_module_state *modstate = get_signal_state(m);
1618
1619
    // XXX For proper isolation, these values must be guaranteed
1620
    // to be effectively const (e.g. immortal).
1621
36
    modstate->default_handler = state->default_handler;  // borrowed ref
1622
36
    modstate->ignore_handler = state->ignore_handler;  // borrowed ref
1623
1624
36
#ifdef PYHAVE_ITIMER_ERROR
1625
36
    modstate->itimer_error = PyErr_NewException("signal.ItimerError",
1626
36
                                                PyExc_OSError, NULL);
1627
36
    if (modstate->itimer_error == NULL) {
1628
0
        return -1;
1629
0
    }
1630
36
#endif
1631
1632
36
    if (signal_add_constants(m) < 0) {
1633
0
        return -1;
1634
0
    }
1635
1636
    /* Add some symbolic constants to the module */
1637
36
    PyObject *d = PyModule_GetDict(m);
1638
36
    if (PyDict_SetItemString(d, "SIG_DFL", state->default_handler) < 0) {
1639
0
        return -1;
1640
0
    }
1641
36
    if (PyDict_SetItemString(d, "SIG_IGN", state->ignore_handler) < 0) {
1642
0
        return -1;
1643
0
    }
1644
36
#ifdef PYHAVE_ITIMER_ERROR
1645
36
    if (PyDict_SetItemString(d, "ItimerError", modstate->itimer_error) < 0) {
1646
0
        return -1;
1647
0
    }
1648
36
#endif
1649
1650
36
#if defined(HAVE_SIGWAITINFO) || defined(HAVE_SIGTIMEDWAIT)
1651
36
    modstate->siginfo_type = PyStructSequence_NewType(&struct_siginfo_desc);
1652
36
    if (modstate->siginfo_type == NULL) {
1653
0
        return -1;
1654
0
    }
1655
36
#endif
1656
36
#if defined(HAVE_SIGWAITINFO) || defined(HAVE_SIGTIMEDWAIT)
1657
36
    if (PyModule_AddType(m, modstate->siginfo_type) < 0) {
1658
0
        return -1;
1659
0
    }
1660
36
#endif
1661
1662
36
    PyThreadState *tstate = _PyThreadState_GET();
1663
36
    if (_Py_IsMainInterpreter(tstate->interp)) {
1664
36
        if (signal_get_set_handlers(state, d) < 0) {
1665
0
            return -1;
1666
0
        }
1667
36
    }
1668
1669
36
    assert(!PyErr_Occurred());
1670
36
    return 0;
1671
36
}
1672
1673
1674
#ifdef PYHAVE_ITIMER_ERROR
1675
static int
1676
_signal_module_traverse(PyObject *module, visitproc visit, void *arg)
1677
1.80k
{
1678
1.80k
    _signal_module_state *state = get_signal_state(module);
1679
1.80k
    Py_VISIT(state->itimer_error);
1680
1.80k
    Py_VISIT(state->siginfo_type);
1681
1.80k
    return 0;
1682
1.80k
}
1683
1684
static int
1685
_signal_module_clear(PyObject *module)
1686
0
{
1687
0
    _signal_module_state *state = get_signal_state(module);
1688
0
    Py_CLEAR(state->itimer_error);
1689
0
    Py_CLEAR(state->siginfo_type);
1690
0
    return 0;
1691
0
}
1692
1693
static void
1694
_signal_module_free(void *module)
1695
0
{
1696
0
    _signal_module_clear((PyObject *)module);
1697
0
}
1698
#endif  // PYHAVE_ITIMER_ERROR
1699
1700
1701
static PyModuleDef_Slot signal_slots[] = {
1702
    _Py_ABI_SLOT,
1703
    {Py_mod_exec, signal_module_exec},
1704
    {Py_mod_multiple_interpreters, Py_MOD_PER_INTERPRETER_GIL_SUPPORTED},
1705
    {Py_mod_gil, Py_MOD_GIL_NOT_USED},
1706
    {0, NULL}
1707
};
1708
1709
static struct PyModuleDef signal_module = {
1710
    PyModuleDef_HEAD_INIT,
1711
    "_signal",
1712
    .m_doc = module_doc,
1713
    .m_size = sizeof(_signal_module_state),
1714
    .m_methods = signal_methods,
1715
    .m_slots = signal_slots,
1716
#ifdef PYHAVE_ITIMER_ERROR
1717
    .m_traverse = _signal_module_traverse,
1718
    .m_clear = _signal_module_clear,
1719
    .m_free = _signal_module_free,
1720
#endif
1721
};
1722
1723
1724
PyMODINIT_FUNC
1725
PyInit__signal(void)
1726
36
{
1727
36
    return PyModuleDef_Init(&signal_module);
1728
36
}
1729
1730
1731
void
1732
_PySignal_Fini(void)
1733
0
{
1734
0
    signal_state_t *state = &signal_global_state;
1735
1736
    // Restore default signals and clear handlers
1737
0
    for (int signum = 1; signum < Py_NSIG; signum++) {
1738
0
        PyObject *func = get_handler(signum);
1739
0
        _Py_atomic_store_int_relaxed(&Handlers[signum].tripped, 0);
1740
0
        set_handler(signum, NULL);
1741
0
        if (func != NULL
1742
0
            && func != Py_None
1743
0
            && !compare_handler(func, state->default_handler)
1744
0
            && !compare_handler(func, state->ignore_handler))
1745
0
        {
1746
0
            PyOS_setsig(signum, SIG_DFL);
1747
0
        }
1748
0
        Py_XDECREF(func);
1749
0
    }
1750
1751
#ifdef MS_WINDOWS
1752
    if (state->sigint_event != NULL) {
1753
        CloseHandle((HANDLE)state->sigint_event);
1754
        state->sigint_event = NULL;
1755
    }
1756
#endif
1757
1758
0
    Py_CLEAR(state->default_handler);
1759
0
    Py_CLEAR(state->ignore_handler);
1760
0
}
1761
1762
1763
/* Declared in pyerrors.h */
1764
int
1765
PyErr_CheckSignals(void)
1766
74.7M
{
1767
74.7M
    PyThreadState *tstate = _PyThreadState_GET();
1768
1769
    /* Opportunistically check if the GC is scheduled to run and run it
1770
       if we have a request. This is done here because native code needs
1771
       to call this API if is going to run for some time without executing
1772
       Python code to ensure signals are handled. Checking for the GC here
1773
       allows long running native code to clean cycles created using the C-API
1774
       even if it doesn't run the evaluation loop */
1775
74.7M
    uintptr_t breaker = _Py_atomic_load_uintptr_relaxed(&tstate->eval_breaker);
1776
74.7M
    if (breaker & _PY_GC_SCHEDULED_BIT) {
1777
1.80k
        _Py_unset_eval_breaker_bit(tstate, _PY_GC_SCHEDULED_BIT);
1778
1.80k
        _Py_RunGC(tstate);
1779
1.80k
    }
1780
74.7M
    if (breaker & _PY_ASYNC_EXCEPTION_BIT) {
1781
0
        if (_PyEval_RaiseAsyncExc(tstate) < 0) {
1782
0
            return -1;
1783
0
        }
1784
0
    }
1785
1786
74.7M
#if defined(Py_REMOTE_DEBUG) && defined(Py_SUPPORTS_REMOTE_DEBUG)
1787
74.7M
    _PyRunRemoteDebugger(tstate);
1788
74.7M
#endif
1789
1790
74.7M
    if (_Py_ThreadCanHandleSignals(tstate->interp)) {
1791
74.7M
        if (_PyErr_CheckSignalsTstate(tstate) < 0) {
1792
0
            return -1;
1793
0
        }
1794
74.7M
    }
1795
1796
74.7M
    return 0;
1797
74.7M
}
1798
1799
1800
/* Declared in cpython/pyerrors.h */
1801
int
1802
_PyErr_CheckSignalsTstate(PyThreadState *tstate)
1803
74.7M
{
1804
74.7M
    _Py_CHECK_EMSCRIPTEN_SIGNALS();
1805
74.7M
    if (!_Py_atomic_load_int(&is_tripped)) {
1806
74.7M
        return 0;
1807
74.7M
    }
1808
1809
    /*
1810
     * The is_tripped variable is meant to speed up the calls to
1811
     * PyErr_CheckSignals (both directly or via pending calls) when no
1812
     * signal has arrived. This variable is set to 1 when a signal arrives
1813
     * and it is set to 0 here, when we know some signals arrived. This way
1814
     * we can run the registered handlers with no signals blocked.
1815
     *
1816
     * NOTE: with this approach we can have a situation where is_tripped is
1817
     *       1 but we have no more signals to handle (Handlers[i].tripped
1818
     *       is 0 for every signal i). This won't do us any harm (except
1819
     *       we're gonna spent some cycles for nothing). This happens when
1820
     *       we receive a signal i after we zero is_tripped and before we
1821
     *       check Handlers[i].tripped.
1822
     */
1823
0
    _Py_atomic_store_int(&is_tripped, 0);
1824
1825
0
    _PyInterpreterFrame *frame = _PyThreadState_GetFrame(tstate);
1826
0
    signal_state_t *state = &signal_global_state;
1827
0
    for (int i = 1; i < Py_NSIG; i++) {
1828
0
        if (!_Py_atomic_load_int_relaxed(&Handlers[i].tripped)) {
1829
0
            continue;
1830
0
        }
1831
0
        _Py_atomic_store_int_relaxed(&Handlers[i].tripped, 0);
1832
1833
        /* Signal handlers can be modified while a signal is received,
1834
         * and therefore the fact that trip_signal() or PyErr_SetInterrupt()
1835
         * was called doesn't guarantee that there is still a Python
1836
         * signal handler for it by the time PyErr_CheckSignals() is called
1837
         * (see bpo-43406).
1838
         */
1839
0
        PyObject *func = get_handler(i);
1840
0
        if (func == NULL || func == Py_None ||
1841
0
            compare_handler(func, state->ignore_handler) ||
1842
0
            compare_handler(func, state->default_handler)) {
1843
            /* No Python signal handler due to aforementioned race condition.
1844
             * We can't call raise() as it would break the assumption
1845
             * that PyErr_SetInterrupt() only *simulates* an incoming
1846
             * signal (i.e. it will never kill the process).
1847
             * We also don't want to interrupt user code with a cryptic
1848
             * asynchronous exception, so instead just write out an
1849
             * unraisable error.
1850
             */
1851
0
            PyErr_Format(PyExc_OSError,
1852
0
                         "Signal %i ignored due to race condition",
1853
0
                         i);
1854
0
            PyErr_FormatUnraisable("Exception ignored while "
1855
0
                                   "calling signal handler");
1856
0
            continue;
1857
0
        }
1858
0
        PyObject *arglist = NULL;
1859
0
        if (frame == NULL) {
1860
0
            arglist = Py_BuildValue("(iO)", i, Py_None);
1861
0
        }
1862
0
        else {
1863
0
            PyFrameObject *f = _PyFrame_GetFrameObject(frame);
1864
0
            if (f != NULL) {
1865
0
                arglist = Py_BuildValue("(iO)", i, f);
1866
0
            }
1867
0
        }
1868
0
        PyObject *result;
1869
0
        if (arglist) {
1870
0
            result = _PyObject_Call(tstate, func, arglist, NULL);
1871
0
            Py_DECREF(arglist);
1872
0
        }
1873
0
        else {
1874
0
            result = NULL;
1875
0
        }
1876
0
        if (!result) {
1877
            /* On error, re-schedule a call to _PyErr_CheckSignalsTstate() */
1878
0
            _Py_atomic_store_int(&is_tripped, 1);
1879
0
            return -1;
1880
0
        }
1881
1882
0
        Py_DECREF(result);
1883
0
    }
1884
1885
0
    return 0;
1886
0
}
1887
1888
1889
1890
int
1891
_PyErr_CheckSignals(void)
1892
0
{
1893
0
    PyThreadState *tstate = _PyThreadState_GET();
1894
0
    return _PyErr_CheckSignalsTstate(tstate);
1895
0
}
1896
1897
1898
/* Simulate the effect of a signal arriving. The next time PyErr_CheckSignals
1899
   is called,  the corresponding Python signal handler will be raised.
1900
1901
   Missing signal handler for the given signal number is silently ignored. */
1902
int
1903
PyErr_SetInterruptEx(int signum)
1904
0
{
1905
0
    if (signum < 1 || signum >= Py_NSIG) {
1906
0
        return -1;
1907
0
    }
1908
1909
0
    signal_state_t *state = &signal_global_state;
1910
0
    PyObject *func = get_handler(signum);
1911
0
    if (!compare_handler(func, state->ignore_handler)
1912
0
            && !compare_handler(func, state->default_handler)) {
1913
0
        trip_signal(signum);
1914
0
    }
1915
0
    return 0;
1916
0
}
1917
1918
void
1919
PyErr_SetInterrupt(void)
1920
0
{
1921
0
    (void) PyErr_SetInterruptEx(SIGINT);
1922
0
}
1923
1924
static int
1925
signal_install_handlers(void)
1926
36
{
1927
36
#ifdef SIGPIPE
1928
36
    PyOS_setsig(SIGPIPE, SIG_IGN);
1929
36
#endif
1930
#ifdef SIGXFZ
1931
    PyOS_setsig(SIGXFZ, SIG_IGN);
1932
#endif
1933
36
#ifdef SIGXFSZ
1934
36
    PyOS_setsig(SIGXFSZ, SIG_IGN);
1935
36
#endif
1936
1937
    // Import _signal to install the Python SIGINT handler
1938
36
    PyObject *module = PyImport_ImportModule("_signal");
1939
36
    if (!module) {
1940
0
        return -1;
1941
0
    }
1942
36
    Py_DECREF(module);
1943
1944
36
    return 0;
1945
36
}
1946
1947
1948
/* Restore signals that the interpreter has called SIG_IGN on to SIG_DFL.
1949
 *
1950
 * All of the code in this function must only use async-signal-safe functions,
1951
 * listed at `man 7 signal-safety` or
1952
 * http://www.opengroup.org/onlinepubs/009695399/functions/xsh_chap02_04.html.
1953
 *
1954
 * If this function is updated, update also _posix_spawn() of subprocess.py.
1955
 */
1956
void
1957
_Py_RestoreSignals(void)
1958
0
{
1959
0
#ifdef SIGPIPE
1960
0
    PyOS_setsig(SIGPIPE, SIG_DFL);
1961
0
#endif
1962
#ifdef SIGXFZ
1963
    PyOS_setsig(SIGXFZ, SIG_DFL);
1964
#endif
1965
0
#ifdef SIGXFSZ
1966
0
    PyOS_setsig(SIGXFSZ, SIG_DFL);
1967
0
#endif
1968
0
}
1969
1970
1971
int
1972
_PySignal_Init(int install_signal_handlers)
1973
36
{
1974
36
    signal_state_t *state = &signal_global_state;
1975
1976
36
    state->default_handler = PyLong_FromVoidPtr((void *)SIG_DFL);
1977
36
    if (state->default_handler == NULL) {
1978
0
        return -1;
1979
0
    }
1980
1981
36
    state->ignore_handler = PyLong_FromVoidPtr((void *)SIG_IGN);
1982
36
    if (state->ignore_handler == NULL) {
1983
0
        return -1;
1984
0
    }
1985
1986
#ifdef MS_WINDOWS
1987
    /* Create manual-reset event, initially unset */
1988
    state->sigint_event = (void *)CreateEvent(NULL, TRUE, FALSE, FALSE);
1989
    if (state->sigint_event == NULL) {
1990
        PyErr_SetFromWindowsErr(0);
1991
        return -1;
1992
    }
1993
#endif
1994
1995
2.34k
    for (int signum = 1; signum < Py_NSIG; signum++) {
1996
2.30k
        _Py_atomic_store_int_relaxed(&Handlers[signum].tripped, 0);
1997
2.30k
    }
1998
1999
36
    if (install_signal_handlers) {
2000
36
        if (signal_install_handlers() < 0) {
2001
0
            return -1;
2002
0
        }
2003
36
    }
2004
2005
36
    return 0;
2006
36
}
2007
2008
2009
// The caller doesn't have to hold the GIL
2010
int
2011
_PyOS_InterruptOccurred(PyThreadState *tstate)
2012
0
{
2013
0
    _Py_EnsureTstateNotNULL(tstate);
2014
0
    if (!_Py_ThreadCanHandleSignals(tstate->interp)) {
2015
0
        return 0;
2016
0
    }
2017
2018
0
    if (!_Py_atomic_load_int_relaxed(&Handlers[SIGINT].tripped)) {
2019
0
        return 0;
2020
0
    }
2021
2022
0
    _Py_atomic_store_int_relaxed(&Handlers[SIGINT].tripped, 0);
2023
0
    return 1;
2024
0
}
2025
2026
2027
// The caller must to hold the GIL
2028
int
2029
PyOS_InterruptOccurred(void)
2030
0
{
2031
0
    PyThreadState *tstate = _PyThreadState_GET();
2032
0
    return _PyOS_InterruptOccurred(tstate);
2033
0
}
2034
2035
2036
#ifdef HAVE_FORK
2037
static void
2038
_clear_pending_signals(void)
2039
0
{
2040
0
    if (!_Py_atomic_load_int(&is_tripped)) {
2041
0
        return;
2042
0
    }
2043
2044
0
    _Py_atomic_store_int(&is_tripped, 0);
2045
0
    for (int i = 1; i < Py_NSIG; ++i) {
2046
0
        _Py_atomic_store_int_relaxed(&Handlers[i].tripped, 0);
2047
0
    }
2048
0
}
2049
2050
void
2051
_PySignal_AfterFork(void)
2052
0
{
2053
    /* Clear the signal flags after forking so that they aren't handled
2054
     * in both processes if they came in just before the fork() but before
2055
     * the interpreter had an opportunity to call the handlers.  issue9535. */
2056
0
    _clear_pending_signals();
2057
0
}
2058
#endif   /* HAVE_FORK */
2059
2060
2061
int
2062
_PyOS_IsMainThread(void)
2063
0
{
2064
0
    PyInterpreterState *interp = _PyInterpreterState_GET();
2065
0
    return _Py_ThreadCanHandleSignals(interp);
2066
0
}
2067
2068
#ifdef MS_WINDOWS
2069
/* Returns a manual-reset event which gets tripped whenever
2070
   SIGINT is received.
2071
2072
   Python.h does not include windows.h so we do cannot use HANDLE
2073
   as the return type of this function.  We use void* instead. */
2074
void *_PyOS_SigintEvent(void)
2075
{
2076
    signal_state_t *state = &signal_global_state;
2077
    return state->sigint_event;
2078
}
2079
#endif