Coverage Report

Created: 2025-08-26 06:57

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