Coverage Report

Created: 2025-07-04 06:49

/src/cpython/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
3.10k
#define Handlers _PyRuntime.signals.handlers
106
0
#define wakeup _PyRuntime.signals.wakeup
107
114M
#define is_tripped _PyRuntime.signals.is_tripped
108
109
// State shared by all Python interpreters
110
typedef struct _signals_runtime_state signal_state_t;
111
32
#define signal_global_state _PyRuntime.signals
112
113
#if defined(HAVE_GETITIMER) || defined(HAVE_SETITIMER)
114
#  define PYHAVE_ITIMER_ERROR
115
#endif
116
117
typedef struct {
118
    PyObject *default_handler;  // borrowed ref (signal_global_state)
119
    PyObject *ignore_handler;  // borrowed ref (signal_global_state)
120
#ifdef PYHAVE_ITIMER_ERROR
121
    PyObject *itimer_error;
122
#endif
123
    PyTypeObject *siginfo_type;
124
} _signal_module_state;
125
126
127
Py_LOCAL_INLINE(PyObject *)
128
get_handler(int i)
129
1.04k
{
130
1.04k
    return (PyObject *)_Py_atomic_load_ptr(&Handlers[i].func);
131
1.04k
}
132
133
Py_LOCAL_INLINE(void)
134
set_handler(int i, PyObject* func)
135
1.04k
{
136
    /* Store func with atomic operation to ensure
137
       that PyErr_SetInterrupt is async-signal-safe. */
138
1.04k
    _Py_atomic_store_ptr(&Handlers[i].func, func);
139
1.04k
}
140
141
142
static inline _signal_module_state*
143
get_signal_state(PyObject *module)
144
5.58k
{
145
5.58k
    void *state = _PyModule_GetState(module);
146
5.58k
    assert(state != NULL);
147
5.58k
    return (_signal_module_state *)state;
148
5.58k
}
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
signal.signal
464
465
    signalnum: int
466
    handler:   object
467
    /
468
469
Set the action for the given signal.
470
471
The action can be SIG_DFL, SIG_IGN, or a callable Python object.
472
The previous action is returned.  See getsignal() for possible return values.
473
474
*** IMPORTANT NOTICE ***
475
A signal handler function is called with two arguments:
476
the first is the signal number, the second is the interrupted stack frame.
477
[clinic start generated code]*/
478
479
static PyObject *
480
signal_signal_impl(PyObject *module, int signalnum, PyObject *handler)
481
/*[clinic end generated code: output=b44cfda43780f3a1 input=deee84af5fa0432c]*/
482
0
{
483
0
    _signal_module_state *modstate = get_signal_state(module);
484
0
    PyObject *old_handler;
485
0
    void (*func)(int);
486
#ifdef MS_WINDOWS
487
    /* Validate that signalnum is one of the allowable signals */
488
    switch (signalnum) {
489
        case SIGABRT: break;
490
#ifdef SIGBREAK
491
        /* Issue #10003: SIGBREAK is not documented as permitted, but works
492
           and corresponds to CTRL_BREAK_EVENT. */
493
        case SIGBREAK: break;
494
#endif
495
        case SIGFPE: break;
496
        case SIGILL: break;
497
        case SIGINT: break;
498
        case SIGSEGV: break;
499
        case SIGTERM: break;
500
        default:
501
            PyErr_SetString(PyExc_ValueError, "invalid signal value");
502
            return NULL;
503
    }
504
#endif
505
506
0
    PyThreadState *tstate = _PyThreadState_GET();
507
0
    if (!_Py_ThreadCanHandleSignals(tstate->interp)) {
508
0
        _PyErr_SetString(tstate, PyExc_ValueError,
509
0
                         "signal only works in main thread "
510
0
                         "of the main interpreter");
511
0
        return NULL;
512
0
    }
513
0
    if (signalnum < 1 || signalnum >= Py_NSIG) {
514
0
        _PyErr_SetString(tstate, PyExc_ValueError,
515
0
                         "signal number out of range");
516
0
        return NULL;
517
0
    }
518
0
    if (PyCallable_Check(handler)) {
519
0
        func = signal_handler;
520
0
    } else if (compare_handler(handler, modstate->ignore_handler)) {
521
0
        func = SIG_IGN;
522
0
    } else if (compare_handler(handler, modstate->default_handler)) {
523
0
        func = SIG_DFL;
524
0
    } else {
525
0
        _PyErr_SetString(tstate, PyExc_TypeError,
526
0
                         "signal handler must be signal.SIG_IGN, "
527
0
                         "signal.SIG_DFL, or a callable object");
528
0
        return NULL;
529
0
    }
530
531
    /* Check for pending signals before changing signal handler */
532
0
    if (_PyErr_CheckSignalsTstate(tstate)) {
533
0
        return NULL;
534
0
    }
535
0
    if (PyOS_setsig(signalnum, func) == SIG_ERR) {
536
0
        PyErr_SetFromErrno(PyExc_OSError);
537
0
        return NULL;
538
0
    }
539
540
0
    old_handler = get_handler(signalnum);
541
0
    set_handler(signalnum, Py_NewRef(handler));
542
543
0
    if (old_handler != NULL) {
544
0
        return old_handler;
545
0
    }
546
0
    else {
547
0
        Py_RETURN_NONE;
548
0
    }
549
0
}
550
551
552
/*[clinic input]
553
signal.getsignal
554
555
    signalnum: int
556
    /
557
558
Return the current action for the given signal.
559
560
The return value can be:
561
  SIG_IGN -- if the signal is being ignored
562
  SIG_DFL -- if the default action for the signal is in effect
563
  None    -- if an unknown handler is in effect
564
  anything else -- the callable Python object used as a handler
565
[clinic start generated code]*/
566
567
static PyObject *
568
signal_getsignal_impl(PyObject *module, int signalnum)
569
/*[clinic end generated code: output=35b3e0e796fd555e input=ac23a00f19dfa509]*/
570
0
{
571
0
    PyObject *old_handler;
572
0
    if (signalnum < 1 || signalnum >= Py_NSIG) {
573
0
        PyErr_SetString(PyExc_ValueError,
574
0
                        "signal number out of range");
575
0
        return NULL;
576
0
    }
577
0
    old_handler = get_handler(signalnum);
578
0
    if (old_handler != NULL) {
579
0
        return Py_NewRef(old_handler);
580
0
    }
581
0
    else {
582
0
        Py_RETURN_NONE;
583
0
    }
584
0
}
585
586
587
/*[clinic input]
588
signal.strsignal
589
590
    signalnum: int
591
    /
592
593
Return the system description of the given signal.
594
595
Returns the description of signal *signalnum*, such as "Interrupt"
596
for :const:`SIGINT`. Returns :const:`None` if *signalnum* has no
597
description. Raises :exc:`ValueError` if *signalnum* is invalid.
598
[clinic start generated code]*/
599
600
static PyObject *
601
signal_strsignal_impl(PyObject *module, int signalnum)
602
/*[clinic end generated code: output=44e12e1e3b666261 input=238b335847778bc0]*/
603
0
{
604
0
    const char *res;
605
606
0
    if (signalnum < 1 || signalnum >= Py_NSIG) {
607
0
        PyErr_SetString(PyExc_ValueError,
608
0
                "signal number out of range");
609
0
        return NULL;
610
0
    }
611
612
#ifndef HAVE_STRSIGNAL
613
    switch (signalnum) {
614
        /* Though being a UNIX, HP-UX does not provide strsignal(3). */
615
#ifndef MS_WINDOWS
616
        case SIGHUP:
617
            res = "Hangup";
618
            break;
619
        case SIGALRM:
620
            res = "Alarm clock";
621
            break;
622
        case SIGPIPE:
623
            res = "Broken pipe";
624
            break;
625
        case SIGQUIT:
626
            res = "Quit";
627
            break;
628
        case SIGCHLD:
629
            res = "Child exited";
630
            break;
631
#endif
632
        /* Custom redefinition of POSIX signals allowed on Windows. */
633
        case SIGINT:
634
            res = "Interrupt";
635
            break;
636
        case SIGILL:
637
            res = "Illegal instruction";
638
            break;
639
        case SIGABRT:
640
            res = "Aborted";
641
            break;
642
        case SIGFPE:
643
            res = "Floating-point exception";
644
            break;
645
        case SIGSEGV:
646
            res = "Segmentation fault";
647
            break;
648
        case SIGTERM:
649
            res = "Terminated";
650
            break;
651
        default:
652
            Py_RETURN_NONE;
653
    }
654
#else
655
0
    errno = 0;
656
0
    res = strsignal(signalnum);
657
658
0
    if (errno || res == NULL || strstr(res, "Unknown signal") != NULL)
659
0
        Py_RETURN_NONE;
660
0
#endif
661
662
0
    return PyUnicode_FromString(res);
663
0
}
664
665
#ifdef HAVE_SIGINTERRUPT
666
667
/*[clinic input]
668
signal.siginterrupt
669
670
    signalnum: int
671
    flag:      int
672
    /
673
674
Change system call restart behaviour.
675
676
If flag is False, system calls will be restarted when interrupted by
677
signal sig, else system calls will be interrupted.
678
[clinic start generated code]*/
679
680
static PyObject *
681
signal_siginterrupt_impl(PyObject *module, int signalnum, int flag)
682
/*[clinic end generated code: output=063816243d85dd19 input=4160acacca3e2099]*/
683
0
{
684
0
    if (signalnum < 1 || signalnum >= Py_NSIG) {
685
0
        PyErr_SetString(PyExc_ValueError,
686
0
                        "signal number out of range");
687
0
        return NULL;
688
0
    }
689
0
#ifdef HAVE_SIGACTION
690
0
    struct sigaction act;
691
0
    (void) sigaction(signalnum, NULL, &act);
692
0
    if (flag) {
693
0
        act.sa_flags &= ~SA_RESTART;
694
0
    }
695
0
    else {
696
0
        act.sa_flags |= SA_RESTART;
697
0
    }
698
0
    if (sigaction(signalnum, &act, NULL) < 0) {
699
#else
700
    if (siginterrupt(signalnum, flag) < 0) {
701
#endif
702
0
        PyErr_SetFromErrno(PyExc_OSError);
703
0
        return NULL;
704
0
    }
705
0
    Py_RETURN_NONE;
706
0
}
707
708
#endif
709
710
711
/*[clinic input]
712
signal.set_wakeup_fd
713
714
    fd as fdobj: object
715
    /
716
    *
717
    warn_on_full_buffer: bool = True
718
719
Sets the fd to be written to (with the signal number) when a signal comes in.
720
721
A library can use this to wakeup select or poll.
722
The previous fd or -1 is returned.
723
724
The fd must be non-blocking.
725
[clinic start generated code]*/
726
727
static PyObject *
728
signal_set_wakeup_fd_impl(PyObject *module, PyObject *fdobj,
729
                          int warn_on_full_buffer)
730
/*[clinic end generated code: output=2280d72dd2a54c4f input=5b545946a28b8339]*/
731
0
{
732
0
    struct _Py_stat_struct status;
733
#ifdef MS_WINDOWS
734
    SOCKET_T sockfd, old_sockfd;
735
    int res;
736
    int res_size = sizeof res;
737
    PyObject *mod;
738
    int is_socket;
739
740
    sockfd = PyLong_AsSocket_t(fdobj);
741
    if (sockfd == (SOCKET_T)(-1) && PyErr_Occurred())
742
        return NULL;
743
#else
744
0
    int fd = PyLong_AsInt(fdobj);
745
0
    if (fd == -1 && PyErr_Occurred()) {
746
0
        return NULL;
747
0
    }
748
0
#endif
749
750
0
    PyThreadState *tstate = _PyThreadState_GET();
751
0
    if (!_Py_ThreadCanHandleSignals(tstate->interp)) {
752
0
        _PyErr_SetString(tstate, PyExc_ValueError,
753
0
                         "set_wakeup_fd only works in main thread "
754
0
                         "of the main interpreter");
755
0
        return NULL;
756
0
    }
757
758
#ifdef MS_WINDOWS
759
    is_socket = 0;
760
    if (sockfd != INVALID_FD) {
761
        /* Import the _socket module to call WSAStartup() */
762
        mod = PyImport_ImportModule("_socket");
763
        if (mod == NULL)
764
            return NULL;
765
        Py_DECREF(mod);
766
767
        /* test the socket */
768
        if (getsockopt(sockfd, SOL_SOCKET, SO_ERROR,
769
                       (char *)&res, &res_size) != 0) {
770
            int fd, err;
771
772
            err = WSAGetLastError();
773
            if (err != WSAENOTSOCK) {
774
                PyErr_SetExcFromWindowsErr(PyExc_OSError, err);
775
                return NULL;
776
            }
777
778
            fd = (int)sockfd;
779
            if ((SOCKET_T)fd != sockfd) {
780
                _PyErr_SetString(tstate, PyExc_ValueError, "invalid fd");
781
                return NULL;
782
            }
783
784
            if (_Py_fstat(fd, &status) != 0) {
785
                return NULL;
786
            }
787
788
            /* on Windows, a file cannot be set to non-blocking mode */
789
        }
790
        else {
791
            is_socket = 1;
792
793
            /* Windows does not provide a function to test if a socket
794
               is in non-blocking mode */
795
        }
796
    }
797
798
    old_sockfd = wakeup.fd;
799
    wakeup.fd = Py_SAFE_DOWNCAST(sockfd, SOCKET_T, int);
800
    wakeup.warn_on_full_buffer = warn_on_full_buffer;
801
    wakeup.use_send = is_socket;
802
803
    if (old_sockfd != INVALID_FD)
804
        return PyLong_FromSocket_t(old_sockfd);
805
    else
806
        return PyLong_FromLong(-1);
807
#else
808
0
    if (fd != -1) {
809
0
        int blocking;
810
811
0
        if (_Py_fstat(fd, &status) != 0)
812
0
            return NULL;
813
814
0
        blocking = _Py_get_blocking(fd);
815
0
        if (blocking < 0)
816
0
            return NULL;
817
0
        if (blocking) {
818
0
            _PyErr_Format(tstate, PyExc_ValueError,
819
0
                          "the fd %i must be in non-blocking mode",
820
0
                          fd);
821
0
            return NULL;
822
0
        }
823
0
    }
824
825
0
    int old_fd = wakeup.fd;
826
0
    wakeup.fd = fd;
827
0
    wakeup.warn_on_full_buffer = warn_on_full_buffer;
828
829
0
    return PyLong_FromLong(old_fd);
830
0
#endif
831
0
}
832
833
/* C API for the same, without all the error checking */
834
int
835
PySignal_SetWakeupFd(int fd)
836
0
{
837
0
    if (fd < 0) {
838
0
        fd = -1;
839
0
    }
840
841
0
    int old_fd = wakeup.fd;
842
0
    wakeup.fd = fd;
843
0
    wakeup.warn_on_full_buffer = 1;
844
0
    return old_fd;
845
0
}
846
847
848
#ifdef HAVE_SETITIMER
849
/*[clinic input]
850
signal.setitimer
851
852
    which:    int
853
    seconds:  object
854
    interval: object(c_default="NULL") = 0.0
855
    /
856
857
Sets given itimer (one of ITIMER_REAL, ITIMER_VIRTUAL or ITIMER_PROF).
858
859
The timer will fire after value seconds and after that every interval seconds.
860
The itimer can be cleared by setting seconds to zero.
861
862
Returns old values as a tuple: (delay, interval).
863
[clinic start generated code]*/
864
865
static PyObject *
866
signal_setitimer_impl(PyObject *module, int which, PyObject *seconds,
867
                      PyObject *interval)
868
/*[clinic end generated code: output=65f9dcbddc35527b input=de43daf194e6f66f]*/
869
0
{
870
0
    _signal_module_state *modstate = get_signal_state(module);
871
872
0
    struct itimerval new;
873
0
    if (timeval_from_double(seconds, &new.it_value) < 0) {
874
0
        return NULL;
875
0
    }
876
0
    if (timeval_from_double(interval, &new.it_interval) < 0) {
877
0
        return NULL;
878
0
    }
879
880
    /* Let OS check "which" value */
881
0
    struct itimerval old;
882
0
    if (setitimer(which, &new, &old) != 0) {
883
0
        PyErr_SetFromErrno(modstate->itimer_error);
884
0
        return NULL;
885
0
    }
886
887
0
    return itimer_retval(&old);
888
0
}
889
#endif  // HAVE_SETITIMER
890
891
892
#ifdef HAVE_GETITIMER
893
/*[clinic input]
894
signal.getitimer
895
896
    which:    int
897
    /
898
899
Returns current value of given itimer.
900
[clinic start generated code]*/
901
902
static PyObject *
903
signal_getitimer_impl(PyObject *module, int which)
904
/*[clinic end generated code: output=9e053175d517db40 input=f7d21d38f3490627]*/
905
0
{
906
0
    _signal_module_state *modstate = get_signal_state(module);
907
908
0
    struct itimerval old;
909
0
    if (getitimer(which, &old) != 0) {
910
0
        PyErr_SetFromErrno(modstate->itimer_error);
911
0
        return NULL;
912
0
    }
913
914
0
    return itimer_retval(&old);
915
0
}
916
#endif // HAVE_GETITIMER
917
918
919
#ifdef HAVE_SIGSET_T
920
#if defined(PYPTHREAD_SIGMASK) || defined(HAVE_SIGPENDING)
921
static PyObject*
922
sigset_to_set(sigset_t mask)
923
0
{
924
0
    PyObject *signum, *result;
925
0
    int sig;
926
927
0
    result = PySet_New(0);
928
0
    if (result == NULL)
929
0
        return NULL;
930
931
0
    for (sig = 1; sig < Py_NSIG; sig++) {
932
0
        if (sigismember(&mask, sig) != 1)
933
0
            continue;
934
935
        /* Handle the case where it is a member by adding the signal to
936
           the result list.  Ignore the other cases because they mean the
937
           signal isn't a member of the mask or the signal was invalid,
938
           and an invalid signal must have been our fault in constructing
939
           the loop boundaries. */
940
0
        signum = PyLong_FromLong(sig);
941
0
        if (signum == NULL) {
942
0
            Py_DECREF(result);
943
0
            return NULL;
944
0
        }
945
0
        if (PySet_Add(result, signum) == -1) {
946
0
            Py_DECREF(signum);
947
0
            Py_DECREF(result);
948
0
            return NULL;
949
0
        }
950
0
        Py_DECREF(signum);
951
0
    }
952
0
    return result;
953
0
}
954
#endif
955
956
#ifdef PYPTHREAD_SIGMASK
957
958
/*[clinic input]
959
signal.pthread_sigmask
960
961
    how:  int
962
    mask: sigset_t
963
    /
964
965
Fetch and/or change the signal mask of the calling thread.
966
[clinic start generated code]*/
967
968
static PyObject *
969
signal_pthread_sigmask_impl(PyObject *module, int how, sigset_t mask)
970
/*[clinic end generated code: output=0562c0fb192981a8 input=85bcebda442fa77f]*/
971
0
{
972
0
    sigset_t previous;
973
0
    int err;
974
975
0
    err = pthread_sigmask(how, &mask, &previous);
976
0
    if (err != 0) {
977
0
        errno = err;
978
0
        PyErr_SetFromErrno(PyExc_OSError);
979
0
        return NULL;
980
0
    }
981
982
    /* if signals was unblocked, signal handlers have been called */
983
0
    if (PyErr_CheckSignals())
984
0
        return NULL;
985
986
0
    return sigset_to_set(previous);
987
0
}
988
989
#endif   /* #ifdef PYPTHREAD_SIGMASK */
990
991
992
#ifdef HAVE_SIGPENDING
993
994
/*[clinic input]
995
signal.sigpending
996
997
Examine pending signals.
998
999
Returns a set of signal numbers that are pending for delivery to
1000
the calling thread.
1001
[clinic start generated code]*/
1002
1003
static PyObject *
1004
signal_sigpending_impl(PyObject *module)
1005
/*[clinic end generated code: output=53375ffe89325022 input=e0036c016f874e29]*/
1006
0
{
1007
0
    int err;
1008
0
    sigset_t mask;
1009
0
    err = sigpending(&mask);
1010
0
    if (err)
1011
0
        return PyErr_SetFromErrno(PyExc_OSError);
1012
0
    return sigset_to_set(mask);
1013
0
}
1014
1015
#endif   /* #ifdef HAVE_SIGPENDING */
1016
1017
1018
#ifdef HAVE_SIGWAIT
1019
1020
/*[clinic input]
1021
signal.sigwait
1022
1023
    sigset: sigset_t
1024
    /
1025
1026
Wait for a signal.
1027
1028
Suspend execution of the calling thread until the delivery of one of the
1029
signals specified in the signal set sigset.  The function accepts the signal
1030
and returns the signal number.
1031
[clinic start generated code]*/
1032
1033
static PyObject *
1034
signal_sigwait_impl(PyObject *module, sigset_t sigset)
1035
/*[clinic end generated code: output=f43770699d682f96 input=a6fbd47b1086d119]*/
1036
0
{
1037
0
    int err, signum;
1038
1039
0
    Py_BEGIN_ALLOW_THREADS
1040
0
    err = sigwait(&sigset, &signum);
1041
0
    Py_END_ALLOW_THREADS
1042
0
    if (err) {
1043
0
        errno = err;
1044
0
        return PyErr_SetFromErrno(PyExc_OSError);
1045
0
    }
1046
1047
0
    return PyLong_FromLong(signum);
1048
0
}
1049
1050
#endif   /* #ifdef HAVE_SIGWAIT */
1051
#endif   /* #ifdef HAVE_SIGSET_T */
1052
1053
#if (defined(HAVE_SIGFILLSET) && defined(HAVE_SIGSET_T)) || defined(MS_WINDOWS)
1054
1055
/*[clinic input]
1056
signal.valid_signals
1057
1058
Return a set of valid signal numbers on this platform.
1059
1060
The signal numbers returned by this function can be safely passed to
1061
functions like `pthread_sigmask`.
1062
[clinic start generated code]*/
1063
1064
static PyObject *
1065
signal_valid_signals_impl(PyObject *module)
1066
/*[clinic end generated code: output=1609cffbcfcf1314 input=86a3717ff25288f2]*/
1067
0
{
1068
#ifdef MS_WINDOWS
1069
#ifdef SIGBREAK
1070
    PyObject *tup = Py_BuildValue("(iiiiiii)", SIGABRT, SIGBREAK, SIGFPE,
1071
                                  SIGILL, SIGINT, SIGSEGV, SIGTERM);
1072
#else
1073
    PyObject *tup = Py_BuildValue("(iiiiii)", SIGABRT, SIGFPE, SIGILL,
1074
                                  SIGINT, SIGSEGV, SIGTERM);
1075
#endif
1076
    if (tup == NULL) {
1077
        return NULL;
1078
    }
1079
    PyObject *set = PySet_New(tup);
1080
    Py_DECREF(tup);
1081
    return set;
1082
#else
1083
0
    sigset_t mask;
1084
0
    if (sigemptyset(&mask) || sigfillset(&mask)) {
1085
0
        return PyErr_SetFromErrno(PyExc_OSError);
1086
0
    }
1087
0
    return sigset_to_set(mask);
1088
0
#endif
1089
0
}
1090
1091
#endif   /* #if (defined(HAVE_SIGFILLSET) && defined(HAVE_SIGSET_T)) || defined(MS_WINDOWS) */
1092
1093
1094
1095
#if defined(HAVE_SIGWAITINFO) || defined(HAVE_SIGTIMEDWAIT)
1096
static PyStructSequence_Field struct_siginfo_fields[] = {
1097
    {"si_signo",        "signal number"},
1098
    {"si_code",         "signal code"},
1099
    {"si_errno",        "errno associated with this signal"},
1100
    {"si_pid",          "sending process ID"},
1101
    {"si_uid",          "real user ID of sending process"},
1102
    {"si_status",       "exit value or signal"},
1103
    {"si_band",         "band event for SIGPOLL"},
1104
    {0}
1105
};
1106
1107
PyDoc_STRVAR(struct_siginfo__doc__,
1108
"struct_siginfo: Result from sigwaitinfo or sigtimedwait.\n\n\
1109
This object may be accessed either as a tuple of\n\
1110
(si_signo, si_code, si_errno, si_pid, si_uid, si_status, si_band),\n\
1111
or via the attributes si_signo, si_code, and so on.");
1112
1113
static PyStructSequence_Desc struct_siginfo_desc = {
1114
    "signal.struct_siginfo",           /* name */
1115
    struct_siginfo__doc__,       /* doc */
1116
    struct_siginfo_fields,       /* fields */
1117
    7          /* n_in_sequence */
1118
};
1119
1120
1121
static PyObject *
1122
fill_siginfo(_signal_module_state *state, siginfo_t *si)
1123
0
{
1124
0
    PyObject *result = PyStructSequence_New(state->siginfo_type);
1125
0
    if (!result)
1126
0
        return NULL;
1127
1128
0
    PyStructSequence_SET_ITEM(result, 0, PyLong_FromLong((long)(si->si_signo)));
1129
0
    PyStructSequence_SET_ITEM(result, 1, PyLong_FromLong((long)(si->si_code)));
1130
#ifdef __VXWORKS__
1131
    PyStructSequence_SET_ITEM(result, 2, PyLong_FromLong(0L));
1132
    PyStructSequence_SET_ITEM(result, 3, PyLong_FromLong(0L));
1133
    PyStructSequence_SET_ITEM(result, 4, PyLong_FromLong(0L));
1134
    PyStructSequence_SET_ITEM(result, 5, PyLong_FromLong(0L));
1135
#else
1136
0
    PyStructSequence_SET_ITEM(result, 2, PyLong_FromLong((long)(si->si_errno)));
1137
0
    PyStructSequence_SET_ITEM(result, 3, PyLong_FromPid(si->si_pid));
1138
0
    PyStructSequence_SET_ITEM(result, 4, _PyLong_FromUid(si->si_uid));
1139
0
    PyStructSequence_SET_ITEM(result, 5,
1140
0
                                PyLong_FromLong((long)(si->si_status)));
1141
0
#endif
1142
0
#ifdef HAVE_SIGINFO_T_SI_BAND
1143
0
    PyStructSequence_SET_ITEM(result, 6, PyLong_FromLong(si->si_band));
1144
#else
1145
    PyStructSequence_SET_ITEM(result, 6, PyLong_FromLong(0L));
1146
#endif
1147
0
    if (PyErr_Occurred()) {
1148
0
        Py_DECREF(result);
1149
0
        return NULL;
1150
0
    }
1151
1152
0
    return result;
1153
0
}
1154
#endif
1155
1156
#ifdef HAVE_SIGSET_T
1157
#ifdef HAVE_SIGWAITINFO
1158
1159
/*[clinic input]
1160
signal.sigwaitinfo
1161
1162
    sigset: sigset_t
1163
    /
1164
1165
Wait synchronously until one of the signals in *sigset* is delivered.
1166
1167
Returns a struct_siginfo containing information about the signal.
1168
[clinic start generated code]*/
1169
1170
static PyObject *
1171
signal_sigwaitinfo_impl(PyObject *module, sigset_t sigset)
1172
/*[clinic end generated code: output=1eb2f1fa236fdbca input=3d1a7e1f27fc664c]*/
1173
0
{
1174
0
    siginfo_t si;
1175
0
    int err;
1176
0
    int async_err = 0;
1177
1178
0
    do {
1179
0
        Py_BEGIN_ALLOW_THREADS
1180
0
        err = sigwaitinfo(&sigset, &si);
1181
0
        Py_END_ALLOW_THREADS
1182
0
    } while (err == -1
1183
0
             && errno == EINTR && !(async_err = PyErr_CheckSignals()));
1184
0
    if (err == -1)
1185
0
        return (!async_err) ? PyErr_SetFromErrno(PyExc_OSError) : NULL;
1186
1187
0
    _signal_module_state *state = get_signal_state(module);
1188
0
    return fill_siginfo(state, &si);
1189
0
}
1190
1191
#endif   /* #ifdef HAVE_SIGWAITINFO */
1192
1193
#ifdef HAVE_SIGTIMEDWAIT
1194
1195
/*[clinic input]
1196
signal.sigtimedwait
1197
1198
    sigset: sigset_t
1199
    timeout as timeout_obj: object
1200
    /
1201
1202
Like sigwaitinfo(), but with a timeout.
1203
1204
The timeout is specified in seconds, with floating-point numbers allowed.
1205
[clinic start generated code]*/
1206
1207
static PyObject *
1208
signal_sigtimedwait_impl(PyObject *module, sigset_t sigset,
1209
                         PyObject *timeout_obj)
1210
/*[clinic end generated code: output=59c8971e8ae18a64 input=955773219c1596cd]*/
1211
0
{
1212
0
    PyTime_t timeout;
1213
0
    if (_PyTime_FromSecondsObject(&timeout,
1214
0
                                  timeout_obj, _PyTime_ROUND_CEILING) < 0)
1215
0
        return NULL;
1216
1217
0
    if (timeout < 0) {
1218
0
        PyErr_SetString(PyExc_ValueError, "timeout must be non-negative");
1219
0
        return NULL;
1220
0
    }
1221
1222
0
    PyTime_t deadline = _PyDeadline_Init(timeout);
1223
0
    siginfo_t si;
1224
1225
0
    do {
1226
0
        struct timespec ts;
1227
0
        if (_PyTime_AsTimespec(timeout, &ts) < 0) {
1228
0
            return NULL;
1229
0
        }
1230
1231
0
        int res;
1232
0
        Py_BEGIN_ALLOW_THREADS
1233
0
        res = sigtimedwait(&sigset, &si, &ts);
1234
0
        Py_END_ALLOW_THREADS
1235
1236
0
        if (res != -1)
1237
0
            break;
1238
1239
0
        if (errno != EINTR) {
1240
0
            if (errno == EAGAIN)
1241
0
                Py_RETURN_NONE;
1242
0
            else
1243
0
                return PyErr_SetFromErrno(PyExc_OSError);
1244
0
        }
1245
1246
        /* sigtimedwait() was interrupted by a signal (EINTR) */
1247
0
        if (PyErr_CheckSignals())
1248
0
            return NULL;
1249
1250
0
        timeout = _PyDeadline_Get(deadline);
1251
0
        if (timeout < 0) {
1252
0
            break;
1253
0
        }
1254
0
    } while (1);
1255
1256
0
    _signal_module_state *state = get_signal_state(module);
1257
0
    return fill_siginfo(state, &si);
1258
0
}
1259
1260
#endif   /* #ifdef HAVE_SIGTIMEDWAIT */
1261
#endif   /* #ifdef HAVE_SIGSET_T */
1262
1263
1264
#if defined(HAVE_PTHREAD_KILL)
1265
1266
/*[clinic input]
1267
signal.pthread_kill
1268
1269
    thread_id:  unsigned_long(bitwise=True)
1270
    signalnum:  int
1271
    /
1272
1273
Send a signal to a thread.
1274
[clinic start generated code]*/
1275
1276
static PyObject *
1277
signal_pthread_kill_impl(PyObject *module, unsigned long thread_id,
1278
                         int signalnum)
1279
/*[clinic end generated code: output=7629919b791bc27f input=1d901f2c7bb544ff]*/
1280
0
{
1281
0
    int err;
1282
1283
0
    if (PySys_Audit("signal.pthread_kill", "ki", thread_id, signalnum) < 0) {
1284
0
        return NULL;
1285
0
    }
1286
1287
0
    err = pthread_kill((pthread_t)thread_id, signalnum);
1288
0
    if (err != 0) {
1289
0
        errno = err;
1290
0
        PyErr_SetFromErrno(PyExc_OSError);
1291
0
        return NULL;
1292
0
    }
1293
1294
    /* the signal may have been send to the current thread */
1295
0
    if (PyErr_CheckSignals())
1296
0
        return NULL;
1297
1298
0
    Py_RETURN_NONE;
1299
0
}
1300
1301
#endif   /* #if defined(HAVE_PTHREAD_KILL) */
1302
1303
1304
// This system call always crashes on older Android versions.
1305
#if defined(__linux__) && defined(__NR_pidfd_send_signal) && \
1306
    !(defined(__ANDROID__) && __ANDROID_API__ < 31)
1307
/*[clinic input]
1308
signal.pidfd_send_signal
1309
1310
    pidfd: int
1311
    signalnum: int
1312
    siginfo: object = None
1313
    flags: int = 0
1314
    /
1315
1316
Send a signal to a process referred to by a pid file descriptor.
1317
[clinic start generated code]*/
1318
1319
static PyObject *
1320
signal_pidfd_send_signal_impl(PyObject *module, int pidfd, int signalnum,
1321
                              PyObject *siginfo, int flags)
1322
/*[clinic end generated code: output=2d59f04a75d9cbdf input=2a6543a1f4ac2000]*/
1323
1324
0
{
1325
0
    if (siginfo != Py_None) {
1326
0
        PyErr_SetString(PyExc_TypeError, "siginfo must be None");
1327
0
        return NULL;
1328
0
    }
1329
0
    if (syscall(__NR_pidfd_send_signal, pidfd, signalnum, NULL, flags) < 0) {
1330
0
        PyErr_SetFromErrno(PyExc_OSError);
1331
0
        return NULL;
1332
0
    }
1333
0
    Py_RETURN_NONE;
1334
0
}
1335
#endif
1336
1337
1338
1339
/* List of functions defined in the module -- some of the methoddefs are
1340
   defined to nothing if the corresponding C function is not available. */
1341
static PyMethodDef signal_methods[] = {
1342
    SIGNAL_DEFAULT_INT_HANDLER_METHODDEF
1343
    SIGNAL_ALARM_METHODDEF
1344
    SIGNAL_SETITIMER_METHODDEF
1345
    SIGNAL_GETITIMER_METHODDEF
1346
    SIGNAL_SIGNAL_METHODDEF
1347
    SIGNAL_RAISE_SIGNAL_METHODDEF
1348
    SIGNAL_STRSIGNAL_METHODDEF
1349
    SIGNAL_GETSIGNAL_METHODDEF
1350
    SIGNAL_SET_WAKEUP_FD_METHODDEF
1351
    SIGNAL_SIGINTERRUPT_METHODDEF
1352
    SIGNAL_PAUSE_METHODDEF
1353
    SIGNAL_PIDFD_SEND_SIGNAL_METHODDEF
1354
    SIGNAL_PTHREAD_KILL_METHODDEF
1355
    SIGNAL_PTHREAD_SIGMASK_METHODDEF
1356
    SIGNAL_SIGPENDING_METHODDEF
1357
    SIGNAL_SIGWAIT_METHODDEF
1358
    SIGNAL_SIGWAITINFO_METHODDEF
1359
    SIGNAL_SIGTIMEDWAIT_METHODDEF
1360
#if defined(HAVE_SIGFILLSET) || defined(MS_WINDOWS)
1361
    SIGNAL_VALID_SIGNALS_METHODDEF
1362
#endif
1363
    {NULL, NULL}           /* sentinel */
1364
};
1365
1366
1367
PyDoc_STRVAR(module_doc,
1368
"This module provides mechanisms to use signal handlers in Python.\n\
1369
\n\
1370
Functions:\n\
1371
\n\
1372
alarm() -- cause SIGALRM after a specified time [Unix only]\n\
1373
setitimer() -- cause a signal (described below) after a specified\n\
1374
               float time and the timer may restart then [Unix only]\n\
1375
getitimer() -- get current value of timer [Unix only]\n\
1376
signal() -- set the action for a given signal\n\
1377
getsignal() -- get the signal action for a given signal\n\
1378
pause() -- wait until a signal arrives [Unix only]\n\
1379
default_int_handler() -- default SIGINT handler\n\
1380
\n\
1381
signal constants:\n\
1382
SIG_DFL -- used to refer to the system default handler\n\
1383
SIG_IGN -- used to ignore the signal\n\
1384
NSIG -- number of defined signals\n\
1385
SIGINT, SIGTERM, etc. -- signal numbers\n\
1386
\n\
1387
itimer constants:\n\
1388
ITIMER_REAL -- decrements in real time, and delivers SIGALRM upon\n\
1389
               expiration\n\
1390
ITIMER_VIRTUAL -- decrements only when the process is executing,\n\
1391
               and delivers SIGVTALRM upon expiration\n\
1392
ITIMER_PROF -- decrements both when the process is executing and\n\
1393
               when the system is executing on behalf of the process.\n\
1394
               Coupled with ITIMER_VIRTUAL, this timer is usually\n\
1395
               used to profile the time spent by the application\n\
1396
               in user and kernel space. SIGPROF is delivered upon\n\
1397
               expiration.\n\
1398
\n\n\
1399
*** IMPORTANT NOTICE ***\n\
1400
A signal handler function is called with two arguments:\n\
1401
the first is the signal number, the second is the interrupted stack frame.");
1402
1403
1404
1405
static int
1406
signal_add_constants(PyObject *module)
1407
16
{
1408
16
    if (PyModule_AddIntConstant(module, "NSIG", Py_NSIG) < 0) {
1409
0
        return -1;
1410
0
    }
1411
1412
16
#define ADD_INT_MACRO(macro) \
1413
672
    if (PyModule_AddIntConstant(module, #macro, macro) < 0) { \
1414
0
        return -1; \
1415
0
    }
1416
1417
    // SIG_xxx pthread_sigmask() constants
1418
16
#ifdef SIG_BLOCK
1419
16
    ADD_INT_MACRO(SIG_BLOCK);
1420
16
#endif
1421
16
#ifdef SIG_UNBLOCK
1422
16
    ADD_INT_MACRO(SIG_UNBLOCK);
1423
16
#endif
1424
16
#ifdef SIG_SETMASK
1425
16
    ADD_INT_MACRO(SIG_SETMASK);
1426
16
#endif
1427
1428
    // SIGxxx signal number constants
1429
16
#ifdef SIGHUP
1430
16
    ADD_INT_MACRO(SIGHUP);
1431
16
#endif
1432
16
#ifdef SIGINT
1433
16
    ADD_INT_MACRO(SIGINT);
1434
16
#endif
1435
#ifdef SIGBREAK
1436
    ADD_INT_MACRO(SIGBREAK);
1437
#endif
1438
16
#ifdef SIGQUIT
1439
16
    ADD_INT_MACRO(SIGQUIT);
1440
16
#endif
1441
16
#ifdef SIGILL
1442
16
    ADD_INT_MACRO(SIGILL);
1443
16
#endif
1444
16
#ifdef SIGTRAP
1445
16
    ADD_INT_MACRO(SIGTRAP);
1446
16
#endif
1447
16
#ifdef SIGIOT
1448
16
    ADD_INT_MACRO(SIGIOT);
1449
16
#endif
1450
16
#ifdef SIGABRT
1451
16
    ADD_INT_MACRO(SIGABRT);
1452
16
#endif
1453
#ifdef SIGEMT
1454
    ADD_INT_MACRO(SIGEMT);
1455
#endif
1456
16
#ifdef SIGFPE
1457
16
    ADD_INT_MACRO(SIGFPE);
1458
16
#endif
1459
16
#ifdef SIGKILL
1460
16
    ADD_INT_MACRO(SIGKILL);
1461
16
#endif
1462
16
#ifdef SIGBUS
1463
16
    ADD_INT_MACRO(SIGBUS);
1464
16
#endif
1465
16
#ifdef SIGSEGV
1466
16
    ADD_INT_MACRO(SIGSEGV);
1467
16
#endif
1468
16
#ifdef SIGSYS
1469
16
    ADD_INT_MACRO(SIGSYS);
1470
16
#endif
1471
16
#ifdef SIGPIPE
1472
16
    ADD_INT_MACRO(SIGPIPE);
1473
16
#endif
1474
16
#ifdef SIGALRM
1475
16
    ADD_INT_MACRO(SIGALRM);
1476
16
#endif
1477
16
#ifdef SIGTERM
1478
16
    ADD_INT_MACRO(SIGTERM);
1479
16
#endif
1480
16
#ifdef SIGUSR1
1481
16
    ADD_INT_MACRO(SIGUSR1);
1482
16
#endif
1483
16
#ifdef SIGUSR2
1484
16
    ADD_INT_MACRO(SIGUSR2);
1485
16
#endif
1486
16
#ifdef SIGCLD
1487
16
    ADD_INT_MACRO(SIGCLD);
1488
16
#endif
1489
16
#ifdef SIGCHLD
1490
16
    ADD_INT_MACRO(SIGCHLD);
1491
16
#endif
1492
16
#ifdef SIGPWR
1493
16
    ADD_INT_MACRO(SIGPWR);
1494
16
#endif
1495
16
#ifdef SIGIO
1496
16
    ADD_INT_MACRO(SIGIO);
1497
16
#endif
1498
16
#ifdef SIGURG
1499
16
    ADD_INT_MACRO(SIGURG);
1500
16
#endif
1501
16
#ifdef SIGWINCH
1502
16
    ADD_INT_MACRO(SIGWINCH);
1503
16
#endif
1504
16
#ifdef SIGPOLL
1505
16
    ADD_INT_MACRO(SIGPOLL);
1506
16
#endif
1507
16
#ifdef SIGSTOP
1508
16
    ADD_INT_MACRO(SIGSTOP);
1509
16
#endif
1510
16
#ifdef SIGTSTP
1511
16
    ADD_INT_MACRO(SIGTSTP);
1512
16
#endif
1513
16
#ifdef SIGCONT
1514
16
    ADD_INT_MACRO(SIGCONT);
1515
16
#endif
1516
16
#ifdef SIGTTIN
1517
16
    ADD_INT_MACRO(SIGTTIN);
1518
16
#endif
1519
16
#ifdef SIGTTOU
1520
16
    ADD_INT_MACRO(SIGTTOU);
1521
16
#endif
1522
16
#ifdef SIGVTALRM
1523
16
    ADD_INT_MACRO(SIGVTALRM);
1524
16
#endif
1525
16
#ifdef SIGPROF
1526
16
    ADD_INT_MACRO(SIGPROF);
1527
16
#endif
1528
16
#ifdef SIGXCPU
1529
16
    ADD_INT_MACRO(SIGXCPU);
1530
16
#endif
1531
16
#ifdef SIGXFSZ
1532
16
    ADD_INT_MACRO(SIGXFSZ);
1533
16
#endif
1534
16
#ifdef SIGRTMIN
1535
16
    ADD_INT_MACRO(SIGRTMIN);
1536
16
#endif
1537
16
#ifdef SIGRTMAX
1538
16
    ADD_INT_MACRO(SIGRTMAX);
1539
16
#endif
1540
#ifdef SIGINFO
1541
    ADD_INT_MACRO(SIGINFO);
1542
#endif
1543
16
#ifdef SIGSTKFLT
1544
16
    ADD_INT_MACRO(SIGSTKFLT);
1545
16
#endif
1546
1547
    // ITIMER_xxx constants
1548
16
#ifdef ITIMER_REAL
1549
16
    ADD_INT_MACRO(ITIMER_REAL);
1550
16
#endif
1551
16
#ifdef ITIMER_VIRTUAL
1552
16
    ADD_INT_MACRO(ITIMER_VIRTUAL);
1553
16
#endif
1554
16
#ifdef ITIMER_PROF
1555
16
    ADD_INT_MACRO(ITIMER_PROF);
1556
16
#endif
1557
1558
    // CTRL_xxx Windows signals
1559
#ifdef CTRL_C_EVENT
1560
    ADD_INT_MACRO(CTRL_C_EVENT);
1561
#endif
1562
#ifdef CTRL_BREAK_EVENT
1563
    ADD_INT_MACRO(CTRL_BREAK_EVENT);
1564
#endif
1565
1566
16
    return 0;
1567
1568
16
#undef ADD_INT_MACRO
1569
16
}
1570
1571
1572
static int
1573
signal_get_set_handlers(signal_state_t *state, PyObject *mod_dict)
1574
16
{
1575
    // Get signal handlers
1576
1.04k
    for (int signum = 1; signum < Py_NSIG; signum++) {
1577
1.02k
        void (*c_handler)(int) = PyOS_getsig(signum);
1578
1.02k
        PyObject *func;
1579
1.02k
        if (c_handler == SIG_DFL) {
1580
912
            func = state->default_handler;
1581
912
        }
1582
112
        else if (c_handler == SIG_IGN) {
1583
32
            func = state->ignore_handler;
1584
32
        }
1585
80
        else {
1586
80
            func = Py_None; // None of our business
1587
80
        }
1588
        // If signal_module_exec() is called more than one, we must
1589
        // clear the strong reference to the previous function.
1590
1.02k
        PyObject* old_func = get_handler(signum);
1591
1.02k
        set_handler(signum, Py_NewRef(func));
1592
1.02k
        Py_XDECREF(old_func);
1593
1.02k
    }
1594
1595
    // Install Python SIGINT handler which raises KeyboardInterrupt
1596
16
    PyObject* sigint_func = get_handler(SIGINT);
1597
16
    if (sigint_func == state->default_handler) {
1598
16
        PyObject *int_handler = PyMapping_GetItemString(mod_dict,
1599
16
                                                        "default_int_handler");
1600
16
        if (!int_handler) {
1601
0
            return -1;
1602
0
        }
1603
1604
16
        set_handler(SIGINT, int_handler);
1605
16
        Py_DECREF(sigint_func);
1606
16
        PyOS_setsig(SIGINT, signal_handler);
1607
16
    }
1608
16
    return 0;
1609
16
}
1610
1611
1612
static int
1613
signal_module_exec(PyObject *m)
1614
16
{
1615
16
    assert(!PyErr_Occurred());
1616
1617
16
    signal_state_t *state = &signal_global_state;
1618
16
    _signal_module_state *modstate = get_signal_state(m);
1619
1620
    // XXX For proper isolation, these values must be guaranteed
1621
    // to be effectively const (e.g. immortal).
1622
16
    modstate->default_handler = state->default_handler;  // borrowed ref
1623
16
    modstate->ignore_handler = state->ignore_handler;  // borrowed ref
1624
1625
16
#ifdef PYHAVE_ITIMER_ERROR
1626
16
    modstate->itimer_error = PyErr_NewException("signal.itimer_error",
1627
16
                                                PyExc_OSError, NULL);
1628
16
    if (modstate->itimer_error == NULL) {
1629
0
        return -1;
1630
0
    }
1631
16
#endif
1632
1633
16
    if (signal_add_constants(m) < 0) {
1634
0
        return -1;
1635
0
    }
1636
1637
    /* Add some symbolic constants to the module */
1638
16
    PyObject *d = PyModule_GetDict(m);
1639
16
    if (PyDict_SetItemString(d, "SIG_DFL", state->default_handler) < 0) {
1640
0
        return -1;
1641
0
    }
1642
16
    if (PyDict_SetItemString(d, "SIG_IGN", state->ignore_handler) < 0) {
1643
0
        return -1;
1644
0
    }
1645
16
#ifdef PYHAVE_ITIMER_ERROR
1646
16
    if (PyDict_SetItemString(d, "ItimerError", modstate->itimer_error) < 0) {
1647
0
        return -1;
1648
0
    }
1649
16
#endif
1650
1651
16
#if defined(HAVE_SIGWAITINFO) || defined(HAVE_SIGTIMEDWAIT)
1652
16
    modstate->siginfo_type = PyStructSequence_NewType(&struct_siginfo_desc);
1653
16
    if (modstate->siginfo_type == NULL) {
1654
0
        return -1;
1655
0
    }
1656
16
#endif
1657
16
#if defined(HAVE_SIGWAITINFO) || defined(HAVE_SIGTIMEDWAIT)
1658
16
    if (PyModule_AddType(m, modstate->siginfo_type) < 0) {
1659
0
        return -1;
1660
0
    }
1661
16
#endif
1662
1663
16
    PyThreadState *tstate = _PyThreadState_GET();
1664
16
    if (_Py_IsMainInterpreter(tstate->interp)) {
1665
16
        if (signal_get_set_handlers(state, d) < 0) {
1666
0
            return -1;
1667
0
        }
1668
16
    }
1669
1670
16
    assert(!PyErr_Occurred());
1671
16
    return 0;
1672
16
}
1673
1674
1675
#ifdef PYHAVE_ITIMER_ERROR
1676
static int
1677
_signal_module_traverse(PyObject *module, visitproc visit, void *arg)
1678
5.56k
{
1679
5.56k
    _signal_module_state *state = get_signal_state(module);
1680
5.56k
    Py_VISIT(state->itimer_error);
1681
5.56k
    Py_VISIT(state->siginfo_type);
1682
5.56k
    return 0;
1683
5.56k
}
1684
1685
static int
1686
_signal_module_clear(PyObject *module)
1687
0
{
1688
0
    _signal_module_state *state = get_signal_state(module);
1689
0
    Py_CLEAR(state->itimer_error);
1690
0
    Py_CLEAR(state->siginfo_type);
1691
0
    return 0;
1692
0
}
1693
1694
static void
1695
_signal_module_free(void *module)
1696
0
{
1697
0
    _signal_module_clear((PyObject *)module);
1698
0
}
1699
#endif  // PYHAVE_ITIMER_ERROR
1700
1701
1702
static PyModuleDef_Slot signal_slots[] = {
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
16
{
1727
16
    return PyModuleDef_Init(&signal_module);
1728
16
}
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
114M
{
1767
114M
    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
114M
    if (_Py_eval_breaker_bit_is_set(tstate, _PY_GC_SCHEDULED_BIT)) {
1776
10
        _Py_unset_eval_breaker_bit(tstate, _PY_GC_SCHEDULED_BIT);
1777
10
        _Py_RunGC(tstate);
1778
10
    }
1779
1780
114M
#if defined(Py_REMOTE_DEBUG) && defined(Py_SUPPORTS_REMOTE_DEBUG)
1781
114M
    _PyRunRemoteDebugger(tstate);
1782
114M
#endif
1783
1784
114M
    if (!_Py_ThreadCanHandleSignals(tstate->interp)) {
1785
0
        return 0;
1786
0
    }
1787
1788
114M
    return _PyErr_CheckSignalsTstate(tstate);
1789
114M
}
1790
1791
1792
/* Declared in cpython/pyerrors.h */
1793
int
1794
_PyErr_CheckSignalsTstate(PyThreadState *tstate)
1795
114M
{
1796
114M
    _Py_CHECK_EMSCRIPTEN_SIGNALS();
1797
114M
    if (!_Py_atomic_load_int(&is_tripped)) {
1798
114M
        return 0;
1799
114M
    }
1800
1801
    /*
1802
     * The is_tripped variable is meant to speed up the calls to
1803
     * PyErr_CheckSignals (both directly or via pending calls) when no
1804
     * signal has arrived. This variable is set to 1 when a signal arrives
1805
     * and it is set to 0 here, when we know some signals arrived. This way
1806
     * we can run the registered handlers with no signals blocked.
1807
     *
1808
     * NOTE: with this approach we can have a situation where is_tripped is
1809
     *       1 but we have no more signals to handle (Handlers[i].tripped
1810
     *       is 0 for every signal i). This won't do us any harm (except
1811
     *       we're gonna spent some cycles for nothing). This happens when
1812
     *       we receive a signal i after we zero is_tripped and before we
1813
     *       check Handlers[i].tripped.
1814
     */
1815
0
    _Py_atomic_store_int(&is_tripped, 0);
1816
1817
0
    _PyInterpreterFrame *frame = _PyThreadState_GetFrame(tstate);
1818
0
    signal_state_t *state = &signal_global_state;
1819
0
    for (int i = 1; i < Py_NSIG; i++) {
1820
0
        if (!_Py_atomic_load_int_relaxed(&Handlers[i].tripped)) {
1821
0
            continue;
1822
0
        }
1823
0
        _Py_atomic_store_int_relaxed(&Handlers[i].tripped, 0);
1824
1825
        /* Signal handlers can be modified while a signal is received,
1826
         * and therefore the fact that trip_signal() or PyErr_SetInterrupt()
1827
         * was called doesn't guarantee that there is still a Python
1828
         * signal handler for it by the time PyErr_CheckSignals() is called
1829
         * (see bpo-43406).
1830
         */
1831
0
        PyObject *func = get_handler(i);
1832
0
        if (func == NULL || func == Py_None ||
1833
0
            compare_handler(func, state->ignore_handler) ||
1834
0
            compare_handler(func, state->default_handler)) {
1835
            /* No Python signal handler due to aforementioned race condition.
1836
             * We can't call raise() as it would break the assumption
1837
             * that PyErr_SetInterrupt() only *simulates* an incoming
1838
             * signal (i.e. it will never kill the process).
1839
             * We also don't want to interrupt user code with a cryptic
1840
             * asynchronous exception, so instead just write out an
1841
             * unraisable error.
1842
             */
1843
0
            PyErr_Format(PyExc_OSError,
1844
0
                         "Signal %i ignored due to race condition",
1845
0
                         i);
1846
0
            PyErr_FormatUnraisable("Exception ignored while "
1847
0
                                   "calling signal handler");
1848
0
            continue;
1849
0
        }
1850
0
        PyObject *arglist = NULL;
1851
0
        if (frame == NULL) {
1852
0
            arglist = Py_BuildValue("(iO)", i, Py_None);
1853
0
        }
1854
0
        else {
1855
0
            PyFrameObject *f = _PyFrame_GetFrameObject(frame);
1856
0
            if (f != NULL) {
1857
0
                arglist = Py_BuildValue("(iO)", i, f);
1858
0
            }
1859
0
        }
1860
0
        PyObject *result;
1861
0
        if (arglist) {
1862
0
            result = _PyObject_Call(tstate, func, arglist, NULL);
1863
0
            Py_DECREF(arglist);
1864
0
        }
1865
0
        else {
1866
0
            result = NULL;
1867
0
        }
1868
0
        if (!result) {
1869
            /* On error, re-schedule a call to _PyErr_CheckSignalsTstate() */
1870
0
            _Py_atomic_store_int(&is_tripped, 1);
1871
0
            return -1;
1872
0
        }
1873
1874
0
        Py_DECREF(result);
1875
0
    }
1876
1877
0
    return 0;
1878
0
}
1879
1880
1881
1882
int
1883
_PyErr_CheckSignals(void)
1884
0
{
1885
0
    PyThreadState *tstate = _PyThreadState_GET();
1886
0
    return _PyErr_CheckSignalsTstate(tstate);
1887
0
}
1888
1889
1890
/* Simulate the effect of a signal arriving. The next time PyErr_CheckSignals
1891
   is called,  the corresponding Python signal handler will be raised.
1892
1893
   Missing signal handler for the given signal number is silently ignored. */
1894
int
1895
PyErr_SetInterruptEx(int signum)
1896
0
{
1897
0
    if (signum < 1 || signum >= Py_NSIG) {
1898
0
        return -1;
1899
0
    }
1900
1901
0
    signal_state_t *state = &signal_global_state;
1902
0
    PyObject *func = get_handler(signum);
1903
0
    if (!compare_handler(func, state->ignore_handler)
1904
0
            && !compare_handler(func, state->default_handler)) {
1905
0
        trip_signal(signum);
1906
0
    }
1907
0
    return 0;
1908
0
}
1909
1910
void
1911
PyErr_SetInterrupt(void)
1912
0
{
1913
0
    (void) PyErr_SetInterruptEx(SIGINT);
1914
0
}
1915
1916
static int
1917
signal_install_handlers(void)
1918
16
{
1919
16
#ifdef SIGPIPE
1920
16
    PyOS_setsig(SIGPIPE, SIG_IGN);
1921
16
#endif
1922
#ifdef SIGXFZ
1923
    PyOS_setsig(SIGXFZ, SIG_IGN);
1924
#endif
1925
16
#ifdef SIGXFSZ
1926
16
    PyOS_setsig(SIGXFSZ, SIG_IGN);
1927
16
#endif
1928
1929
    // Import _signal to install the Python SIGINT handler
1930
16
    PyObject *module = PyImport_ImportModule("_signal");
1931
16
    if (!module) {
1932
0
        return -1;
1933
0
    }
1934
16
    Py_DECREF(module);
1935
1936
16
    return 0;
1937
16
}
1938
1939
1940
/* Restore signals that the interpreter has called SIG_IGN on to SIG_DFL.
1941
 *
1942
 * All of the code in this function must only use async-signal-safe functions,
1943
 * listed at `man 7 signal` or
1944
 * http://www.opengroup.org/onlinepubs/009695399/functions/xsh_chap02_04.html.
1945
 *
1946
 * If this function is updated, update also _posix_spawn() of subprocess.py.
1947
 */
1948
void
1949
_Py_RestoreSignals(void)
1950
0
{
1951
0
#ifdef SIGPIPE
1952
0
    PyOS_setsig(SIGPIPE, SIG_DFL);
1953
0
#endif
1954
#ifdef SIGXFZ
1955
    PyOS_setsig(SIGXFZ, SIG_DFL);
1956
#endif
1957
0
#ifdef SIGXFSZ
1958
0
    PyOS_setsig(SIGXFSZ, SIG_DFL);
1959
0
#endif
1960
0
}
1961
1962
1963
int
1964
_PySignal_Init(int install_signal_handlers)
1965
16
{
1966
16
    signal_state_t *state = &signal_global_state;
1967
1968
16
    state->default_handler = PyLong_FromVoidPtr((void *)SIG_DFL);
1969
16
    if (state->default_handler == NULL) {
1970
0
        return -1;
1971
0
    }
1972
1973
16
    state->ignore_handler = PyLong_FromVoidPtr((void *)SIG_IGN);
1974
16
    if (state->ignore_handler == NULL) {
1975
0
        return -1;
1976
0
    }
1977
1978
#ifdef MS_WINDOWS
1979
    /* Create manual-reset event, initially unset */
1980
    state->sigint_event = (void *)CreateEvent(NULL, TRUE, FALSE, FALSE);
1981
    if (state->sigint_event == NULL) {
1982
        PyErr_SetFromWindowsErr(0);
1983
        return -1;
1984
    }
1985
#endif
1986
1987
1.04k
    for (int signum = 1; signum < Py_NSIG; signum++) {
1988
1.02k
        _Py_atomic_store_int_relaxed(&Handlers[signum].tripped, 0);
1989
1.02k
    }
1990
1991
16
    if (install_signal_handlers) {
1992
16
        if (signal_install_handlers() < 0) {
1993
0
            return -1;
1994
0
        }
1995
16
    }
1996
1997
16
    return 0;
1998
16
}
1999
2000
2001
// The caller doesn't have to hold the GIL
2002
int
2003
_PyOS_InterruptOccurred(PyThreadState *tstate)
2004
0
{
2005
0
    _Py_EnsureTstateNotNULL(tstate);
2006
0
    if (!_Py_ThreadCanHandleSignals(tstate->interp)) {
2007
0
        return 0;
2008
0
    }
2009
2010
0
    if (!_Py_atomic_load_int_relaxed(&Handlers[SIGINT].tripped)) {
2011
0
        return 0;
2012
0
    }
2013
2014
0
    _Py_atomic_store_int_relaxed(&Handlers[SIGINT].tripped, 0);
2015
0
    return 1;
2016
0
}
2017
2018
2019
// The caller must to hold the GIL
2020
int
2021
PyOS_InterruptOccurred(void)
2022
0
{
2023
0
    PyThreadState *tstate = _PyThreadState_GET();
2024
0
    return _PyOS_InterruptOccurred(tstate);
2025
0
}
2026
2027
2028
#ifdef HAVE_FORK
2029
static void
2030
_clear_pending_signals(void)
2031
0
{
2032
0
    if (!_Py_atomic_load_int(&is_tripped)) {
2033
0
        return;
2034
0
    }
2035
2036
0
    _Py_atomic_store_int(&is_tripped, 0);
2037
0
    for (int i = 1; i < Py_NSIG; ++i) {
2038
0
        _Py_atomic_store_int_relaxed(&Handlers[i].tripped, 0);
2039
0
    }
2040
0
}
2041
2042
void
2043
_PySignal_AfterFork(void)
2044
0
{
2045
    /* Clear the signal flags after forking so that they aren't handled
2046
     * in both processes if they came in just before the fork() but before
2047
     * the interpreter had an opportunity to call the handlers.  issue9535. */
2048
0
    _clear_pending_signals();
2049
0
}
2050
#endif   /* HAVE_FORK */
2051
2052
2053
int
2054
_PyOS_IsMainThread(void)
2055
0
{
2056
0
    PyInterpreterState *interp = _PyInterpreterState_GET();
2057
0
    return _Py_ThreadCanHandleSignals(interp);
2058
0
}
2059
2060
#ifdef MS_WINDOWS
2061
/* Returns a manual-reset event which gets tripped whenever
2062
   SIGINT is received.
2063
2064
   Python.h does not include windows.h so we do cannot use HANDLE
2065
   as the return type of this function.  We use void* instead. */
2066
void *_PyOS_SigintEvent(void)
2067
{
2068
    signal_state_t *state = &signal_global_state;
2069
    return state->sigint_event;
2070
}
2071
#endif