Coverage Report

Created: 2025-07-11 06:59

/src/Python-3.8.3/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_atomic.h"
8
#include "pycore_ceval.h"
9
#include "pycore_pystate.h"
10
11
#ifndef MS_WINDOWS
12
#include "posixmodule.h"
13
#endif
14
#ifdef MS_WINDOWS
15
#include "socketmodule.h"   /* needed for SOCKET_T */
16
#endif
17
18
#ifdef MS_WINDOWS
19
#include <windows.h>
20
#ifdef HAVE_PROCESS_H
21
#include <process.h>
22
#endif
23
#endif
24
25
#ifdef HAVE_SIGNAL_H
26
#include <signal.h>
27
#endif
28
#ifdef HAVE_SYS_STAT_H
29
#include <sys/stat.h>
30
#endif
31
#ifdef HAVE_SYS_TIME_H
32
#include <sys/time.h>
33
#endif
34
35
#if defined(HAVE_PTHREAD_SIGMASK) && !defined(HAVE_BROKEN_PTHREAD_SIGMASK)
36
#  define PYPTHREAD_SIGMASK
37
#endif
38
39
#if defined(PYPTHREAD_SIGMASK) && defined(HAVE_PTHREAD_H)
40
#  include <pthread.h>
41
#endif
42
43
#ifndef SIG_ERR
44
#define SIG_ERR ((PyOS_sighandler_t)(-1))
45
#endif
46
47
#ifndef NSIG
48
# if defined(_NSIG)
49
#  define NSIG _NSIG            /* For BSD/SysV */
50
# elif defined(_SIGMAX)
51
#  define NSIG (_SIGMAX + 1)    /* For QNX */
52
# elif defined(SIGMAX)
53
#  define NSIG (SIGMAX + 1)     /* For djgpp */
54
# else
55
#  define NSIG 64               /* Use a reasonable default value */
56
# endif
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
/*[python input]
67
68
class sigset_t_converter(CConverter):
69
    type = 'sigset_t'
70
    converter = '_Py_Sigset_Converter'
71
72
[python start generated code]*/
73
/*[python end generated code: output=da39a3ee5e6b4b0d input=b5689d14466b6823]*/
74
75
/*
76
   NOTES ON THE INTERACTION BETWEEN SIGNALS AND THREADS
77
78
   We want the following semantics:
79
80
   - only the main thread can set a signal handler
81
   - only the main thread runs the signal handler
82
   - signals can be delivered to any thread
83
   - any thread can get a signal handler
84
85
   I.e. we don't support "synchronous signals" like SIGFPE (catching
86
   this doesn't make much sense in Python anyway) nor do we support
87
   signals as a means of inter-thread communication, since not all
88
   thread implementations support that (at least our thread library
89
   doesn't).
90
91
   We still have the problem that in some implementations signals
92
   generated by the keyboard (e.g. SIGINT) are delivered to all
93
   threads (e.g. SGI), while in others (e.g. Solaris) such signals are
94
   delivered to one random thread. On Linux, signals are delivered to
95
   the main thread (unless the main thread is blocking the signal, for
96
   example because it's already handling the same signal).  Since we
97
   allow signals to be delivered to any thread, this works fine. The
98
   only oddity is that the thread executing the Python signal handler
99
   may not be the thread that received the signal.
100
*/
101
102
#include "pythread.h"
103
104
static volatile struct {
105
    _Py_atomic_int tripped;
106
    PyObject *func;
107
} Handlers[NSIG];
108
109
#ifdef MS_WINDOWS
110
#define INVALID_FD ((SOCKET_T)-1)
111
112
static volatile struct {
113
    SOCKET_T fd;
114
    int warn_on_full_buffer;
115
    int use_send;
116
} wakeup = {.fd = INVALID_FD, .warn_on_full_buffer = 1, .use_send = 0};
117
#else
118
0
#define INVALID_FD (-1)
119
static volatile struct {
120
    sig_atomic_t fd;
121
    int warn_on_full_buffer;
122
} wakeup = {.fd = INVALID_FD, .warn_on_full_buffer = 1};
123
#endif
124
125
/* Speed up sigcheck() when none tripped */
126
static _Py_atomic_int is_tripped;
127
128
static PyObject *DefaultHandler;
129
static PyObject *IgnoreHandler;
130
static PyObject *IntHandler;
131
132
#ifdef MS_WINDOWS
133
static HANDLE sigint_event = NULL;
134
#endif
135
136
#ifdef HAVE_GETITIMER
137
static PyObject *ItimerError;
138
139
/* auxiliary functions for setitimer */
140
static int
141
timeval_from_double(PyObject *obj, struct timeval *tv)
142
0
{
143
0
    if (obj == NULL) {
144
0
        tv->tv_sec = 0;
145
0
        tv->tv_usec = 0;
146
0
        return 0;
147
0
    }
148
149
0
    _PyTime_t t;
150
0
    if (_PyTime_FromSecondsObject(&t, obj, _PyTime_ROUND_CEILING) < 0) {
151
0
        return -1;
152
0
    }
153
0
    return _PyTime_AsTimeval(t, tv, _PyTime_ROUND_CEILING);
154
0
}
155
156
Py_LOCAL_INLINE(double)
157
double_from_timeval(struct timeval *tv)
158
0
{
159
0
    return tv->tv_sec + (double)(tv->tv_usec / 1000000.0);
160
0
}
161
162
static PyObject *
163
itimer_retval(struct itimerval *iv)
164
0
{
165
0
    PyObject *r, *v;
166
167
0
    r = PyTuple_New(2);
168
0
    if (r == NULL)
169
0
        return NULL;
170
171
0
    if(!(v = PyFloat_FromDouble(double_from_timeval(&iv->it_value)))) {
172
0
        Py_DECREF(r);
173
0
        return NULL;
174
0
    }
175
176
0
    PyTuple_SET_ITEM(r, 0, v);
177
178
0
    if(!(v = PyFloat_FromDouble(double_from_timeval(&iv->it_interval)))) {
179
0
        Py_DECREF(r);
180
0
        return NULL;
181
0
    }
182
183
0
    PyTuple_SET_ITEM(r, 1, v);
184
185
0
    return r;
186
0
}
187
#endif
188
189
static int
190
is_main(_PyRuntimeState *runtime)
191
3.68k
{
192
3.68k
    unsigned long thread = PyThread_get_thread_ident();
193
3.68k
    PyInterpreterState *interp = _PyRuntimeState_GetThreadState(runtime)->interp;
194
3.68k
    return (thread == runtime->main_thread
195
3.68k
            && interp == runtime->interpreters.main);
196
3.68k
}
197
198
static PyObject *
199
signal_default_int_handler(PyObject *self, PyObject *args)
200
0
{
201
0
    PyErr_SetNone(PyExc_KeyboardInterrupt);
202
0
    return NULL;
203
0
}
204
205
PyDoc_STRVAR(default_int_handler_doc,
206
"default_int_handler(...)\n\
207
\n\
208
The default handler for SIGINT installed by Python.\n\
209
It raises KeyboardInterrupt.");
210
211
212
static int
213
report_wakeup_write_error(void *data)
214
0
{
215
0
    PyObject *exc, *val, *tb;
216
0
    int save_errno = errno;
217
0
    errno = (int) (intptr_t) data;
218
0
    PyErr_Fetch(&exc, &val, &tb);
219
0
    PyErr_SetFromErrno(PyExc_OSError);
220
0
    PySys_WriteStderr("Exception ignored when trying to write to the "
221
0
                      "signal wakeup fd:\n");
222
0
    PyErr_WriteUnraisable(NULL);
223
0
    PyErr_Restore(exc, val, tb);
224
0
    errno = save_errno;
225
0
    return 0;
226
0
}
227
228
#ifdef MS_WINDOWS
229
static int
230
report_wakeup_send_error(void* data)
231
{
232
    PyObject *exc, *val, *tb;
233
    PyErr_Fetch(&exc, &val, &tb);
234
    /* PyErr_SetExcFromWindowsErr() invokes FormatMessage() which
235
       recognizes the error codes used by both GetLastError() and
236
       WSAGetLastError */
237
    PyErr_SetExcFromWindowsErr(PyExc_OSError, (int) (intptr_t) data);
238
    PySys_WriteStderr("Exception ignored when trying to send to the "
239
                      "signal wakeup fd:\n");
240
    PyErr_WriteUnraisable(NULL);
241
    PyErr_Restore(exc, val, tb);
242
    return 0;
243
}
244
#endif   /* MS_WINDOWS */
245
246
static void
247
trip_signal(int sig_num)
248
0
{
249
0
    unsigned char byte;
250
0
    int fd;
251
0
    Py_ssize_t rc;
252
253
0
    _Py_atomic_store_relaxed(&Handlers[sig_num].tripped, 1);
254
255
    /* Set is_tripped after setting .tripped, as it gets
256
       cleared in PyErr_CheckSignals() before .tripped. */
257
0
    _Py_atomic_store(&is_tripped, 1);
258
259
    /* Notify ceval.c */
260
0
    _PyRuntimeState *runtime = &_PyRuntime;
261
0
    PyThreadState *tstate = _PyRuntimeState_GetThreadState(runtime);
262
0
    _PyEval_SignalReceived(&runtime->ceval);
263
264
    /* And then write to the wakeup fd *after* setting all the globals and
265
       doing the _PyEval_SignalReceived. We used to write to the wakeup fd
266
       and then set the flag, but this allowed the following sequence of events
267
       (especially on windows, where trip_signal may run in a new thread):
268
269
       - main thread blocks on select([wakeup.fd], ...)
270
       - signal arrives
271
       - trip_signal writes to the wakeup fd
272
       - the main thread wakes up
273
       - the main thread checks the signal flags, sees that they're unset
274
       - the main thread empties the wakeup fd
275
       - the main thread goes back to sleep
276
       - trip_signal sets the flags to request the Python-level signal handler
277
         be run
278
       - the main thread doesn't notice, because it's asleep
279
280
       See bpo-30038 for more details.
281
    */
282
283
#ifdef MS_WINDOWS
284
    fd = Py_SAFE_DOWNCAST(wakeup.fd, SOCKET_T, int);
285
#else
286
0
    fd = wakeup.fd;
287
0
#endif
288
289
0
    if (fd != INVALID_FD) {
290
0
        byte = (unsigned char)sig_num;
291
#ifdef MS_WINDOWS
292
        if (wakeup.use_send) {
293
            rc = send(fd, &byte, 1, 0);
294
295
            if (rc < 0) {
296
                int last_error = GetLastError();
297
                if (wakeup.warn_on_full_buffer ||
298
                    last_error != WSAEWOULDBLOCK)
299
                {
300
                    /* Py_AddPendingCall() isn't signal-safe, but we
301
                       still use it for this exceptional case. */
302
                    _PyEval_AddPendingCall(tstate, &runtime->ceval,
303
                                           report_wakeup_send_error,
304
                                           (void *)(intptr_t) last_error);
305
                }
306
            }
307
        }
308
        else
309
#endif
310
0
        {
311
            /* _Py_write_noraise() retries write() if write() is interrupted by
312
               a signal (fails with EINTR). */
313
0
            rc = _Py_write_noraise(fd, &byte, 1);
314
315
0
            if (rc < 0) {
316
0
                if (wakeup.warn_on_full_buffer ||
317
0
                    (errno != EWOULDBLOCK && errno != EAGAIN))
318
0
                {
319
                    /* Py_AddPendingCall() isn't signal-safe, but we
320
                       still use it for this exceptional case. */
321
0
                    _PyEval_AddPendingCall(tstate, &runtime->ceval,
322
0
                                           report_wakeup_write_error,
323
0
                                           (void *)(intptr_t)errno);
324
0
                }
325
0
            }
326
0
        }
327
0
    }
328
0
}
329
330
static void
331
signal_handler(int sig_num)
332
0
{
333
0
    int save_errno = errno;
334
335
0
    trip_signal(sig_num);
336
337
#ifndef HAVE_SIGACTION
338
#ifdef SIGCHLD
339
    /* To avoid infinite recursion, this signal remains
340
       reset until explicit re-instated.
341
       Don't clear the 'func' field as it is our pointer
342
       to the Python handler... */
343
    if (sig_num != SIGCHLD)
344
#endif
345
    /* If the handler was not set up with sigaction, reinstall it.  See
346
     * Python/pylifecycle.c for the implementation of PyOS_setsig which
347
     * makes this true.  See also issue8354. */
348
    PyOS_setsig(sig_num, signal_handler);
349
#endif
350
351
    /* Issue #10311: asynchronously executing signal handlers should not
352
       mutate errno under the feet of unsuspecting C code. */
353
0
    errno = save_errno;
354
355
#ifdef MS_WINDOWS
356
    if (sig_num == SIGINT)
357
        SetEvent(sigint_event);
358
#endif
359
0
}
360
361
362
#ifdef HAVE_ALARM
363
364
/*[clinic input]
365
signal.alarm -> long
366
367
    seconds: int
368
    /
369
370
Arrange for SIGALRM to arrive after the given number of seconds.
371
[clinic start generated code]*/
372
373
static long
374
signal_alarm_impl(PyObject *module, int seconds)
375
/*[clinic end generated code: output=144232290814c298 input=0d5e97e0e6f39e86]*/
376
0
{
377
    /* alarm() returns the number of seconds remaining */
378
0
    return (long)alarm(seconds);
379
0
}
380
381
#endif
382
383
#ifdef HAVE_PAUSE
384
385
/*[clinic input]
386
signal.pause
387
388
Wait until a signal arrives.
389
[clinic start generated code]*/
390
391
static PyObject *
392
signal_pause_impl(PyObject *module)
393
/*[clinic end generated code: output=391656788b3c3929 input=f03de0f875752062]*/
394
0
{
395
0
    Py_BEGIN_ALLOW_THREADS
396
0
    (void)pause();
397
0
    Py_END_ALLOW_THREADS
398
    /* make sure that any exceptions that got raised are propagated
399
     * back into Python
400
     */
401
0
    if (PyErr_CheckSignals())
402
0
        return NULL;
403
404
0
    Py_RETURN_NONE;
405
0
}
406
407
#endif
408
409
/*[clinic input]
410
signal.raise_signal
411
412
    signalnum: int
413
    /
414
415
Send a signal to the executing process.
416
[clinic start generated code]*/
417
418
static PyObject *
419
signal_raise_signal_impl(PyObject *module, int signalnum)
420
/*[clinic end generated code: output=e2b014220aa6111d input=e90c0f9a42358de6]*/
421
0
{
422
0
    int err;
423
0
    Py_BEGIN_ALLOW_THREADS
424
0
    _Py_BEGIN_SUPPRESS_IPH
425
0
    err = raise(signalnum);
426
0
    _Py_END_SUPPRESS_IPH
427
0
    Py_END_ALLOW_THREADS
428
429
0
    if (err) {
430
0
        return PyErr_SetFromErrno(PyExc_OSError);
431
0
    }
432
0
    Py_RETURN_NONE;
433
0
}
434
435
/*[clinic input]
436
signal.signal
437
438
    signalnum: int
439
    handler:   object
440
    /
441
442
Set the action for the given signal.
443
444
The action can be SIG_DFL, SIG_IGN, or a callable Python object.
445
The previous action is returned.  See getsignal() for possible return values.
446
447
*** IMPORTANT NOTICE ***
448
A signal handler function is called with two arguments:
449
the first is the signal number, the second is the interrupted stack frame.
450
[clinic start generated code]*/
451
452
static PyObject *
453
signal_signal_impl(PyObject *module, int signalnum, PyObject *handler)
454
/*[clinic end generated code: output=b44cfda43780f3a1 input=deee84af5fa0432c]*/
455
0
{
456
0
    PyObject *old_handler;
457
0
    void (*func)(int);
458
#ifdef MS_WINDOWS
459
    /* Validate that signalnum is one of the allowable signals */
460
    switch (signalnum) {
461
        case SIGABRT: break;
462
#ifdef SIGBREAK
463
        /* Issue #10003: SIGBREAK is not documented as permitted, but works
464
           and corresponds to CTRL_BREAK_EVENT. */
465
        case SIGBREAK: break;
466
#endif
467
        case SIGFPE: break;
468
        case SIGILL: break;
469
        case SIGINT: break;
470
        case SIGSEGV: break;
471
        case SIGTERM: break;
472
        default:
473
            PyErr_SetString(PyExc_ValueError, "invalid signal value");
474
            return NULL;
475
    }
476
#endif
477
478
0
    _PyRuntimeState *runtime = &_PyRuntime;
479
0
    if (!is_main(runtime)) {
480
0
        PyErr_SetString(PyExc_ValueError,
481
0
                        "signal only works in main thread");
482
0
        return NULL;
483
0
    }
484
0
    if (signalnum < 1 || signalnum >= NSIG) {
485
0
        PyErr_SetString(PyExc_ValueError,
486
0
                        "signal number out of range");
487
0
        return NULL;
488
0
    }
489
0
    if (handler == IgnoreHandler)
490
0
        func = SIG_IGN;
491
0
    else if (handler == DefaultHandler)
492
0
        func = SIG_DFL;
493
0
    else if (!PyCallable_Check(handler)) {
494
0
        PyErr_SetString(PyExc_TypeError,
495
0
"signal handler must be signal.SIG_IGN, signal.SIG_DFL, or a callable object");
496
0
                return NULL;
497
0
    }
498
0
    else
499
0
        func = signal_handler;
500
    /* Check for pending signals before changing signal handler */
501
0
    if (_PyErr_CheckSignals()) {
502
0
        return NULL;
503
0
    }
504
0
    if (PyOS_setsig(signalnum, func) == SIG_ERR) {
505
0
        PyErr_SetFromErrno(PyExc_OSError);
506
0
        return NULL;
507
0
    }
508
0
    old_handler = Handlers[signalnum].func;
509
0
    Py_INCREF(handler);
510
0
    Handlers[signalnum].func = handler;
511
0
    if (old_handler != NULL)
512
0
        return old_handler;
513
0
    else
514
0
        Py_RETURN_NONE;
515
0
}
516
517
518
/*[clinic input]
519
signal.getsignal
520
521
    signalnum: int
522
    /
523
524
Return the current action for the given signal.
525
526
The return value can be:
527
  SIG_IGN -- if the signal is being ignored
528
  SIG_DFL -- if the default action for the signal is in effect
529
  None    -- if an unknown handler is in effect
530
  anything else -- the callable Python object used as a handler
531
[clinic start generated code]*/
532
533
static PyObject *
534
signal_getsignal_impl(PyObject *module, int signalnum)
535
/*[clinic end generated code: output=35b3e0e796fd555e input=ac23a00f19dfa509]*/
536
0
{
537
0
    PyObject *old_handler;
538
0
    if (signalnum < 1 || signalnum >= NSIG) {
539
0
        PyErr_SetString(PyExc_ValueError,
540
0
                        "signal number out of range");
541
0
        return NULL;
542
0
    }
543
0
    old_handler = Handlers[signalnum].func;
544
0
    if (old_handler != NULL) {
545
0
        Py_INCREF(old_handler);
546
0
        return old_handler;
547
0
    }
548
0
    else {
549
0
        Py_RETURN_NONE;
550
0
    }
551
0
}
552
553
554
/*[clinic input]
555
signal.strsignal
556
557
    signalnum: int
558
    /
559
560
Return the system description of the given signal.
561
562
The return values can be such as "Interrupt", "Segmentation fault", etc.
563
Returns None if the signal is not recognized.
564
[clinic start generated code]*/
565
566
static PyObject *
567
signal_strsignal_impl(PyObject *module, int signalnum)
568
/*[clinic end generated code: output=44e12e1e3b666261 input=b77914b03f856c74]*/
569
0
{
570
0
    char *res;
571
572
0
    if (signalnum < 1 || signalnum >= NSIG) {
573
0
        PyErr_SetString(PyExc_ValueError,
574
0
                "signal number out of range");
575
0
        return NULL;
576
0
    }
577
578
#ifndef HAVE_STRSIGNAL
579
    switch (signalnum) {
580
        /* Though being a UNIX, HP-UX does not provide strsignal(3). */
581
#ifndef MS_WINDOWS
582
        case SIGHUP:
583
            res = "Hangup";
584
            break;
585
        case SIGALRM:
586
            res = "Alarm clock";
587
            break;
588
        case SIGPIPE:
589
            res = "Broken pipe";
590
            break;
591
        case SIGQUIT:
592
            res = "Quit";
593
            break;
594
        case SIGCHLD:
595
            res = "Child exited";
596
            break;
597
#endif
598
        /* Custom redefinition of POSIX signals allowed on Windows. */
599
        case SIGINT:
600
            res = "Interrupt";
601
            break;
602
        case SIGILL:
603
            res = "Illegal instruction";
604
            break;
605
        case SIGABRT:
606
            res = "Aborted";
607
            break;
608
        case SIGFPE:
609
            res = "Floating point exception";
610
            break;
611
        case SIGSEGV:
612
            res = "Segmentation fault";
613
            break;
614
        case SIGTERM:
615
            res = "Terminated";
616
            break;
617
        default:
618
            Py_RETURN_NONE;
619
    }
620
#else
621
0
    errno = 0;
622
0
    res = strsignal(signalnum);
623
624
0
    if (errno || res == NULL || strstr(res, "Unknown signal") != NULL)
625
0
        Py_RETURN_NONE;
626
0
#endif
627
628
0
    return Py_BuildValue("s", res);
629
0
}
630
631
#ifdef HAVE_SIGINTERRUPT
632
633
/*[clinic input]
634
signal.siginterrupt
635
636
    signalnum: int
637
    flag:      int
638
    /
639
640
Change system call restart behaviour.
641
642
If flag is False, system calls will be restarted when interrupted by
643
signal sig, else system calls will be interrupted.
644
[clinic start generated code]*/
645
646
static PyObject *
647
signal_siginterrupt_impl(PyObject *module, int signalnum, int flag)
648
/*[clinic end generated code: output=063816243d85dd19 input=4160acacca3e2099]*/
649
0
{
650
0
    if (signalnum < 1 || signalnum >= NSIG) {
651
0
        PyErr_SetString(PyExc_ValueError,
652
0
                        "signal number out of range");
653
0
        return NULL;
654
0
    }
655
0
    if (siginterrupt(signalnum, flag)<0) {
656
0
        PyErr_SetFromErrno(PyExc_OSError);
657
0
        return NULL;
658
0
    }
659
0
    Py_RETURN_NONE;
660
0
}
661
662
#endif
663
664
665
static PyObject*
666
signal_set_wakeup_fd(PyObject *self, PyObject *args, PyObject *kwds)
667
0
{
668
0
    struct _Py_stat_struct status;
669
0
    static char *kwlist[] = {
670
0
        "", "warn_on_full_buffer", NULL,
671
0
    };
672
0
    int warn_on_full_buffer = 1;
673
#ifdef MS_WINDOWS
674
    PyObject *fdobj;
675
    SOCKET_T sockfd, old_sockfd;
676
    int res;
677
    int res_size = sizeof res;
678
    PyObject *mod;
679
    int is_socket;
680
681
    if (!PyArg_ParseTupleAndKeywords(args, kwds, "O|$p:set_wakeup_fd", kwlist,
682
                                     &fdobj, &warn_on_full_buffer))
683
        return NULL;
684
685
    sockfd = PyLong_AsSocket_t(fdobj);
686
    if (sockfd == (SOCKET_T)(-1) && PyErr_Occurred())
687
        return NULL;
688
#else
689
0
    int fd, old_fd;
690
691
0
    if (!PyArg_ParseTupleAndKeywords(args, kwds, "i|$p:set_wakeup_fd", kwlist,
692
0
                                     &fd, &warn_on_full_buffer))
693
0
        return NULL;
694
0
#endif
695
696
0
    _PyRuntimeState *runtime = &_PyRuntime;
697
0
    if (!is_main(runtime)) {
698
0
        PyErr_SetString(PyExc_ValueError,
699
0
                        "set_wakeup_fd only works in main thread");
700
0
        return NULL;
701
0
    }
702
703
#ifdef MS_WINDOWS
704
    is_socket = 0;
705
    if (sockfd != INVALID_FD) {
706
        /* Import the _socket module to call WSAStartup() */
707
        mod = PyImport_ImportModuleNoBlock("_socket");
708
        if (mod == NULL)
709
            return NULL;
710
        Py_DECREF(mod);
711
712
        /* test the socket */
713
        if (getsockopt(sockfd, SOL_SOCKET, SO_ERROR,
714
                       (char *)&res, &res_size) != 0) {
715
            int fd, err;
716
717
            err = WSAGetLastError();
718
            if (err != WSAENOTSOCK) {
719
                PyErr_SetExcFromWindowsErr(PyExc_OSError, err);
720
                return NULL;
721
            }
722
723
            fd = (int)sockfd;
724
            if ((SOCKET_T)fd != sockfd) {
725
                PyErr_SetString(PyExc_ValueError, "invalid fd");
726
                return NULL;
727
            }
728
729
            if (_Py_fstat(fd, &status) != 0)
730
                return NULL;
731
732
            /* on Windows, a file cannot be set to non-blocking mode */
733
        }
734
        else {
735
            is_socket = 1;
736
737
            /* Windows does not provide a function to test if a socket
738
               is in non-blocking mode */
739
        }
740
    }
741
742
    old_sockfd = wakeup.fd;
743
    wakeup.fd = sockfd;
744
    wakeup.warn_on_full_buffer = warn_on_full_buffer;
745
    wakeup.use_send = is_socket;
746
747
    if (old_sockfd != INVALID_FD)
748
        return PyLong_FromSocket_t(old_sockfd);
749
    else
750
        return PyLong_FromLong(-1);
751
#else
752
0
    if (fd != -1) {
753
0
        int blocking;
754
755
0
        if (_Py_fstat(fd, &status) != 0)
756
0
            return NULL;
757
758
0
        blocking = _Py_get_blocking(fd);
759
0
        if (blocking < 0)
760
0
            return NULL;
761
0
        if (blocking) {
762
0
            PyErr_Format(PyExc_ValueError,
763
0
                         "the fd %i must be in non-blocking mode",
764
0
                         fd);
765
0
            return NULL;
766
0
        }
767
0
    }
768
769
0
    old_fd = wakeup.fd;
770
0
    wakeup.fd = fd;
771
0
    wakeup.warn_on_full_buffer = warn_on_full_buffer;
772
773
0
    return PyLong_FromLong(old_fd);
774
0
#endif
775
0
}
776
777
PyDoc_STRVAR(set_wakeup_fd_doc,
778
"set_wakeup_fd(fd, *, warn_on_full_buffer=True) -> fd\n\
779
\n\
780
Sets the fd to be written to (with the signal number) when a signal\n\
781
comes in.  A library can use this to wakeup select or poll.\n\
782
The previous fd or -1 is returned.\n\
783
\n\
784
The fd must be non-blocking.");
785
786
/* C API for the same, without all the error checking */
787
int
788
PySignal_SetWakeupFd(int fd)
789
0
{
790
0
    int old_fd;
791
0
    if (fd < 0)
792
0
        fd = -1;
793
794
#ifdef MS_WINDOWS
795
    old_fd = Py_SAFE_DOWNCAST(wakeup.fd, SOCKET_T, int);
796
#else
797
0
    old_fd = wakeup.fd;
798
0
#endif
799
0
    wakeup.fd = fd;
800
0
    wakeup.warn_on_full_buffer = 1;
801
0
    return old_fd;
802
0
}
803
804
805
#ifdef HAVE_SETITIMER
806
807
/*[clinic input]
808
signal.setitimer
809
810
    which:    int
811
    seconds:  object
812
    interval: object(c_default="NULL") = 0.0
813
    /
814
815
Sets given itimer (one of ITIMER_REAL, ITIMER_VIRTUAL or ITIMER_PROF).
816
817
The timer will fire after value seconds and after that every interval seconds.
818
The itimer can be cleared by setting seconds to zero.
819
820
Returns old values as a tuple: (delay, interval).
821
[clinic start generated code]*/
822
823
static PyObject *
824
signal_setitimer_impl(PyObject *module, int which, PyObject *seconds,
825
                      PyObject *interval)
826
/*[clinic end generated code: output=65f9dcbddc35527b input=de43daf194e6f66f]*/
827
0
{
828
0
    struct itimerval new, old;
829
830
0
    if (timeval_from_double(seconds, &new.it_value) < 0) {
831
0
        return NULL;
832
0
    }
833
0
    if (timeval_from_double(interval, &new.it_interval) < 0) {
834
0
        return NULL;
835
0
    }
836
837
    /* Let OS check "which" value */
838
0
    if (setitimer(which, &new, &old) != 0) {
839
0
        PyErr_SetFromErrno(ItimerError);
840
0
        return NULL;
841
0
    }
842
843
0
    return itimer_retval(&old);
844
0
}
845
846
#endif
847
848
849
#ifdef HAVE_GETITIMER
850
851
/*[clinic input]
852
signal.getitimer
853
854
    which:    int
855
    /
856
857
Returns current value of given itimer.
858
[clinic start generated code]*/
859
860
static PyObject *
861
signal_getitimer_impl(PyObject *module, int which)
862
/*[clinic end generated code: output=9e053175d517db40 input=f7d21d38f3490627]*/
863
0
{
864
0
    struct itimerval old;
865
866
0
    if (getitimer(which, &old) != 0) {
867
0
        PyErr_SetFromErrno(ItimerError);
868
0
        return NULL;
869
0
    }
870
871
0
    return itimer_retval(&old);
872
0
}
873
874
#endif
875
876
#if defined(PYPTHREAD_SIGMASK) || defined(HAVE_SIGPENDING)
877
static PyObject*
878
sigset_to_set(sigset_t mask)
879
0
{
880
0
    PyObject *signum, *result;
881
0
    int sig;
882
883
0
    result = PySet_New(0);
884
0
    if (result == NULL)
885
0
        return NULL;
886
887
0
    for (sig = 1; sig < NSIG; sig++) {
888
0
        if (sigismember(&mask, sig) != 1)
889
0
            continue;
890
891
        /* Handle the case where it is a member by adding the signal to
892
           the result list.  Ignore the other cases because they mean the
893
           signal isn't a member of the mask or the signal was invalid,
894
           and an invalid signal must have been our fault in constructing
895
           the loop boundaries. */
896
0
        signum = PyLong_FromLong(sig);
897
0
        if (signum == NULL) {
898
0
            Py_DECREF(result);
899
0
            return NULL;
900
0
        }
901
0
        if (PySet_Add(result, signum) == -1) {
902
0
            Py_DECREF(signum);
903
0
            Py_DECREF(result);
904
0
            return NULL;
905
0
        }
906
0
        Py_DECREF(signum);
907
0
    }
908
0
    return result;
909
0
}
910
#endif
911
912
#ifdef PYPTHREAD_SIGMASK
913
914
/*[clinic input]
915
signal.pthread_sigmask
916
917
    how:  int
918
    mask: sigset_t
919
    /
920
921
Fetch and/or change the signal mask of the calling thread.
922
[clinic start generated code]*/
923
924
static PyObject *
925
signal_pthread_sigmask_impl(PyObject *module, int how, sigset_t mask)
926
/*[clinic end generated code: output=0562c0fb192981a8 input=85bcebda442fa77f]*/
927
0
{
928
0
    sigset_t previous;
929
0
    int err;
930
931
0
    err = pthread_sigmask(how, &mask, &previous);
932
0
    if (err != 0) {
933
0
        errno = err;
934
0
        PyErr_SetFromErrno(PyExc_OSError);
935
0
        return NULL;
936
0
    }
937
938
    /* if signals was unblocked, signal handlers have been called */
939
0
    if (PyErr_CheckSignals())
940
0
        return NULL;
941
942
0
    return sigset_to_set(previous);
943
0
}
944
945
#endif   /* #ifdef PYPTHREAD_SIGMASK */
946
947
948
#ifdef HAVE_SIGPENDING
949
950
/*[clinic input]
951
signal.sigpending
952
953
Examine pending signals.
954
955
Returns a set of signal numbers that are pending for delivery to
956
the calling thread.
957
[clinic start generated code]*/
958
959
static PyObject *
960
signal_sigpending_impl(PyObject *module)
961
/*[clinic end generated code: output=53375ffe89325022 input=e0036c016f874e29]*/
962
0
{
963
0
    int err;
964
0
    sigset_t mask;
965
0
    err = sigpending(&mask);
966
0
    if (err)
967
0
        return PyErr_SetFromErrno(PyExc_OSError);
968
0
    return sigset_to_set(mask);
969
0
}
970
971
#endif   /* #ifdef HAVE_SIGPENDING */
972
973
974
#ifdef HAVE_SIGWAIT
975
976
/*[clinic input]
977
signal.sigwait
978
979
    sigset: sigset_t
980
    /
981
982
Wait for a signal.
983
984
Suspend execution of the calling thread until the delivery of one of the
985
signals specified in the signal set sigset.  The function accepts the signal
986
and returns the signal number.
987
[clinic start generated code]*/
988
989
static PyObject *
990
signal_sigwait_impl(PyObject *module, sigset_t sigset)
991
/*[clinic end generated code: output=f43770699d682f96 input=a6fbd47b1086d119]*/
992
0
{
993
0
    int err, signum;
994
995
0
    Py_BEGIN_ALLOW_THREADS
996
0
    err = sigwait(&sigset, &signum);
997
0
    Py_END_ALLOW_THREADS
998
0
    if (err) {
999
0
        errno = err;
1000
0
        return PyErr_SetFromErrno(PyExc_OSError);
1001
0
    }
1002
1003
0
    return PyLong_FromLong(signum);
1004
0
}
1005
1006
#endif   /* #ifdef HAVE_SIGWAIT */
1007
1008
1009
#if defined(HAVE_SIGFILLSET) || defined(MS_WINDOWS)
1010
1011
/*[clinic input]
1012
signal.valid_signals
1013
1014
Return a set of valid signal numbers on this platform.
1015
1016
The signal numbers returned by this function can be safely passed to
1017
functions like `pthread_sigmask`.
1018
[clinic start generated code]*/
1019
1020
static PyObject *
1021
signal_valid_signals_impl(PyObject *module)
1022
/*[clinic end generated code: output=1609cffbcfcf1314 input=86a3717ff25288f2]*/
1023
0
{
1024
#ifdef MS_WINDOWS
1025
#ifdef SIGBREAK
1026
    PyObject *tup = Py_BuildValue("(iiiiiii)", SIGABRT, SIGBREAK, SIGFPE,
1027
                                  SIGILL, SIGINT, SIGSEGV, SIGTERM);
1028
#else
1029
    PyObject *tup = Py_BuildValue("(iiiiii)", SIGABRT, SIGFPE, SIGILL,
1030
                                  SIGINT, SIGSEGV, SIGTERM);
1031
#endif
1032
    if (tup == NULL) {
1033
        return NULL;
1034
    }
1035
    PyObject *set = PySet_New(tup);
1036
    Py_DECREF(tup);
1037
    return set;
1038
#else
1039
0
    sigset_t mask;
1040
0
    if (sigemptyset(&mask) || sigfillset(&mask)) {
1041
0
        return PyErr_SetFromErrno(PyExc_OSError);
1042
0
    }
1043
0
    return sigset_to_set(mask);
1044
0
#endif
1045
0
}
1046
1047
#endif   /* #if defined(HAVE_SIGFILLSET) || defined(MS_WINDOWS) */
1048
1049
1050
#if defined(HAVE_SIGWAITINFO) || defined(HAVE_SIGTIMEDWAIT)
1051
static int initialized;
1052
static PyStructSequence_Field struct_siginfo_fields[] = {
1053
    {"si_signo",        "signal number"},
1054
    {"si_code",         "signal code"},
1055
    {"si_errno",        "errno associated with this signal"},
1056
    {"si_pid",          "sending process ID"},
1057
    {"si_uid",          "real user ID of sending process"},
1058
    {"si_status",       "exit value or signal"},
1059
    {"si_band",         "band event for SIGPOLL"},
1060
    {0}
1061
};
1062
1063
PyDoc_STRVAR(struct_siginfo__doc__,
1064
"struct_siginfo: Result from sigwaitinfo or sigtimedwait.\n\n\
1065
This object may be accessed either as a tuple of\n\
1066
(si_signo, si_code, si_errno, si_pid, si_uid, si_status, si_band),\n\
1067
or via the attributes si_signo, si_code, and so on.");
1068
1069
static PyStructSequence_Desc struct_siginfo_desc = {
1070
    "signal.struct_siginfo",           /* name */
1071
    struct_siginfo__doc__,       /* doc */
1072
    struct_siginfo_fields,       /* fields */
1073
    7          /* n_in_sequence */
1074
};
1075
1076
static PyTypeObject SiginfoType;
1077
1078
static PyObject *
1079
fill_siginfo(siginfo_t *si)
1080
0
{
1081
0
    PyObject *result = PyStructSequence_New(&SiginfoType);
1082
0
    if (!result)
1083
0
        return NULL;
1084
1085
0
    PyStructSequence_SET_ITEM(result, 0, PyLong_FromLong((long)(si->si_signo)));
1086
0
    PyStructSequence_SET_ITEM(result, 1, PyLong_FromLong((long)(si->si_code)));
1087
#ifdef __VXWORKS__
1088
    PyStructSequence_SET_ITEM(result, 2, PyLong_FromLong(0L));
1089
    PyStructSequence_SET_ITEM(result, 3, PyLong_FromLong(0L));
1090
    PyStructSequence_SET_ITEM(result, 4, PyLong_FromLong(0L));
1091
    PyStructSequence_SET_ITEM(result, 5, PyLong_FromLong(0L));
1092
#else
1093
0
    PyStructSequence_SET_ITEM(result, 2, PyLong_FromLong((long)(si->si_errno)));
1094
0
    PyStructSequence_SET_ITEM(result, 3, PyLong_FromPid(si->si_pid));
1095
0
    PyStructSequence_SET_ITEM(result, 4, _PyLong_FromUid(si->si_uid));
1096
0
    PyStructSequence_SET_ITEM(result, 5,
1097
0
                                PyLong_FromLong((long)(si->si_status)));
1098
0
#endif
1099
0
#ifdef HAVE_SIGINFO_T_SI_BAND
1100
0
    PyStructSequence_SET_ITEM(result, 6, PyLong_FromLong(si->si_band));
1101
#else
1102
    PyStructSequence_SET_ITEM(result, 6, PyLong_FromLong(0L));
1103
#endif
1104
0
    if (PyErr_Occurred()) {
1105
0
        Py_DECREF(result);
1106
0
        return NULL;
1107
0
    }
1108
1109
0
    return result;
1110
0
}
1111
#endif
1112
1113
#ifdef HAVE_SIGWAITINFO
1114
1115
/*[clinic input]
1116
signal.sigwaitinfo
1117
1118
    sigset: sigset_t
1119
    /
1120
1121
Wait synchronously until one of the signals in *sigset* is delivered.
1122
1123
Returns a struct_siginfo containing information about the signal.
1124
[clinic start generated code]*/
1125
1126
static PyObject *
1127
signal_sigwaitinfo_impl(PyObject *module, sigset_t sigset)
1128
/*[clinic end generated code: output=1eb2f1fa236fdbca input=3d1a7e1f27fc664c]*/
1129
0
{
1130
0
    siginfo_t si;
1131
0
    int err;
1132
0
    int async_err = 0;
1133
1134
0
    do {
1135
0
        Py_BEGIN_ALLOW_THREADS
1136
0
        err = sigwaitinfo(&sigset, &si);
1137
0
        Py_END_ALLOW_THREADS
1138
0
    } while (err == -1
1139
0
             && errno == EINTR && !(async_err = PyErr_CheckSignals()));
1140
0
    if (err == -1)
1141
0
        return (!async_err) ? PyErr_SetFromErrno(PyExc_OSError) : NULL;
1142
1143
0
    return fill_siginfo(&si);
1144
0
}
1145
1146
#endif   /* #ifdef HAVE_SIGWAITINFO */
1147
1148
#ifdef HAVE_SIGTIMEDWAIT
1149
1150
/*[clinic input]
1151
signal.sigtimedwait
1152
1153
    sigset: sigset_t
1154
    timeout as timeout_obj: object
1155
    /
1156
1157
Like sigwaitinfo(), but with a timeout.
1158
1159
The timeout is specified in seconds, with floating point numbers allowed.
1160
[clinic start generated code]*/
1161
1162
static PyObject *
1163
signal_sigtimedwait_impl(PyObject *module, sigset_t sigset,
1164
                         PyObject *timeout_obj)
1165
/*[clinic end generated code: output=59c8971e8ae18a64 input=87fd39237cf0b7ba]*/
1166
0
{
1167
0
    struct timespec ts;
1168
0
    siginfo_t si;
1169
0
    int res;
1170
0
    _PyTime_t timeout, deadline, monotonic;
1171
1172
0
    if (_PyTime_FromSecondsObject(&timeout,
1173
0
                                  timeout_obj, _PyTime_ROUND_CEILING) < 0)
1174
0
        return NULL;
1175
1176
0
    if (timeout < 0) {
1177
0
        PyErr_SetString(PyExc_ValueError, "timeout must be non-negative");
1178
0
        return NULL;
1179
0
    }
1180
1181
0
    deadline = _PyTime_GetMonotonicClock() + timeout;
1182
1183
0
    do {
1184
0
        if (_PyTime_AsTimespec(timeout, &ts) < 0)
1185
0
            return NULL;
1186
1187
0
        Py_BEGIN_ALLOW_THREADS
1188
0
        res = sigtimedwait(&sigset, &si, &ts);
1189
0
        Py_END_ALLOW_THREADS
1190
1191
0
        if (res != -1)
1192
0
            break;
1193
1194
0
        if (errno != EINTR) {
1195
0
            if (errno == EAGAIN)
1196
0
                Py_RETURN_NONE;
1197
0
            else
1198
0
                return PyErr_SetFromErrno(PyExc_OSError);
1199
0
        }
1200
1201
        /* sigtimedwait() was interrupted by a signal (EINTR) */
1202
0
        if (PyErr_CheckSignals())
1203
0
            return NULL;
1204
1205
0
        monotonic = _PyTime_GetMonotonicClock();
1206
0
        timeout = deadline - monotonic;
1207
0
        if (timeout < 0)
1208
0
            break;
1209
0
    } while (1);
1210
1211
0
    return fill_siginfo(&si);
1212
0
}
1213
1214
#endif   /* #ifdef HAVE_SIGTIMEDWAIT */
1215
1216
1217
#if defined(HAVE_PTHREAD_KILL)
1218
1219
/*[clinic input]
1220
signal.pthread_kill
1221
1222
    thread_id:  unsigned_long(bitwise=True)
1223
    signalnum:  int
1224
    /
1225
1226
Send a signal to a thread.
1227
[clinic start generated code]*/
1228
1229
static PyObject *
1230
signal_pthread_kill_impl(PyObject *module, unsigned long thread_id,
1231
                         int signalnum)
1232
/*[clinic end generated code: output=7629919b791bc27f input=1d901f2c7bb544ff]*/
1233
0
{
1234
0
    int err;
1235
1236
0
    if (PySys_Audit("signal.pthread_kill", "ki", thread_id, signalnum) < 0) {
1237
0
        return NULL;
1238
0
    }
1239
1240
0
    err = pthread_kill((pthread_t)thread_id, signalnum);
1241
0
    if (err != 0) {
1242
0
        errno = err;
1243
0
        PyErr_SetFromErrno(PyExc_OSError);
1244
0
        return NULL;
1245
0
    }
1246
1247
    /* the signal may have been send to the current thread */
1248
0
    if (PyErr_CheckSignals())
1249
0
        return NULL;
1250
1251
0
    Py_RETURN_NONE;
1252
0
}
1253
1254
#endif   /* #if defined(HAVE_PTHREAD_KILL) */
1255
1256
1257
1258
/* List of functions defined in the module -- some of the methoddefs are
1259
   defined to nothing if the corresponding C function is not available. */
1260
static PyMethodDef signal_methods[] = {
1261
    {"default_int_handler", signal_default_int_handler, METH_VARARGS, default_int_handler_doc},
1262
    SIGNAL_ALARM_METHODDEF
1263
    SIGNAL_SETITIMER_METHODDEF
1264
    SIGNAL_GETITIMER_METHODDEF
1265
    SIGNAL_SIGNAL_METHODDEF
1266
    SIGNAL_RAISE_SIGNAL_METHODDEF
1267
    SIGNAL_STRSIGNAL_METHODDEF
1268
    SIGNAL_GETSIGNAL_METHODDEF
1269
    {"set_wakeup_fd", (PyCFunction)(void(*)(void))signal_set_wakeup_fd, METH_VARARGS | METH_KEYWORDS, set_wakeup_fd_doc},
1270
    SIGNAL_SIGINTERRUPT_METHODDEF
1271
    SIGNAL_PAUSE_METHODDEF
1272
    SIGNAL_PTHREAD_KILL_METHODDEF
1273
    SIGNAL_PTHREAD_SIGMASK_METHODDEF
1274
    SIGNAL_SIGPENDING_METHODDEF
1275
    SIGNAL_SIGWAIT_METHODDEF
1276
    SIGNAL_SIGWAITINFO_METHODDEF
1277
    SIGNAL_SIGTIMEDWAIT_METHODDEF
1278
#if defined(HAVE_SIGFILLSET) || defined(MS_WINDOWS)
1279
    SIGNAL_VALID_SIGNALS_METHODDEF
1280
#endif
1281
    {NULL, NULL}           /* sentinel */
1282
};
1283
1284
1285
PyDoc_STRVAR(module_doc,
1286
"This module provides mechanisms to use signal handlers in Python.\n\
1287
\n\
1288
Functions:\n\
1289
\n\
1290
alarm() -- cause SIGALRM after a specified time [Unix only]\n\
1291
setitimer() -- cause a signal (described below) after a specified\n\
1292
               float time and the timer may restart then [Unix only]\n\
1293
getitimer() -- get current value of timer [Unix only]\n\
1294
signal() -- set the action for a given signal\n\
1295
getsignal() -- get the signal action for a given signal\n\
1296
pause() -- wait until a signal arrives [Unix only]\n\
1297
default_int_handler() -- default SIGINT handler\n\
1298
\n\
1299
signal constants:\n\
1300
SIG_DFL -- used to refer to the system default handler\n\
1301
SIG_IGN -- used to ignore the signal\n\
1302
NSIG -- number of defined signals\n\
1303
SIGINT, SIGTERM, etc. -- signal numbers\n\
1304
\n\
1305
itimer constants:\n\
1306
ITIMER_REAL -- decrements in real time, and delivers SIGALRM upon\n\
1307
               expiration\n\
1308
ITIMER_VIRTUAL -- decrements only when the process is executing,\n\
1309
               and delivers SIGVTALRM upon expiration\n\
1310
ITIMER_PROF -- decrements both when the process is executing and\n\
1311
               when the system is executing on behalf of the process.\n\
1312
               Coupled with ITIMER_VIRTUAL, this timer is usually\n\
1313
               used to profile the time spent by the application\n\
1314
               in user and kernel space. SIGPROF is delivered upon\n\
1315
               expiration.\n\
1316
\n\n\
1317
*** IMPORTANT NOTICE ***\n\
1318
A signal handler function is called with two arguments:\n\
1319
the first is the signal number, the second is the interrupted stack frame.");
1320
1321
static struct PyModuleDef signalmodule = {
1322
    PyModuleDef_HEAD_INIT,
1323
    "_signal",
1324
    module_doc,
1325
    -1,
1326
    signal_methods,
1327
    NULL,
1328
    NULL,
1329
    NULL,
1330
    NULL
1331
};
1332
1333
PyMODINIT_FUNC
1334
PyInit__signal(void)
1335
0
{
1336
0
    PyObject *m, *d;
1337
0
    int i;
1338
1339
    /* Create the module and add the functions */
1340
0
    m = PyModule_Create(&signalmodule);
1341
0
    if (m == NULL)
1342
0
        return NULL;
1343
1344
0
#if defined(HAVE_SIGWAITINFO) || defined(HAVE_SIGTIMEDWAIT)
1345
0
    if (!initialized) {
1346
0
        if (PyStructSequence_InitType2(&SiginfoType, &struct_siginfo_desc) < 0)
1347
0
            return NULL;
1348
0
    }
1349
0
    Py_INCREF((PyObject*) &SiginfoType);
1350
0
    PyModule_AddObject(m, "struct_siginfo", (PyObject*) &SiginfoType);
1351
0
    initialized = 1;
1352
0
#endif
1353
1354
    /* Add some symbolic constants to the module */
1355
0
    d = PyModule_GetDict(m);
1356
1357
0
    DefaultHandler = PyLong_FromVoidPtr((void *)SIG_DFL);
1358
0
    if (!DefaultHandler ||
1359
0
        PyDict_SetItemString(d, "SIG_DFL", DefaultHandler) < 0) {
1360
0
        goto finally;
1361
0
    }
1362
1363
0
    IgnoreHandler = PyLong_FromVoidPtr((void *)SIG_IGN);
1364
0
    if (!IgnoreHandler ||
1365
0
        PyDict_SetItemString(d, "SIG_IGN", IgnoreHandler) < 0) {
1366
0
        goto finally;
1367
0
    }
1368
1369
0
    if (PyModule_AddIntMacro(m, NSIG))
1370
0
        goto finally;
1371
1372
0
#ifdef SIG_BLOCK
1373
0
    if (PyModule_AddIntMacro(m, SIG_BLOCK))
1374
0
         goto finally;
1375
0
#endif
1376
0
#ifdef SIG_UNBLOCK
1377
0
    if (PyModule_AddIntMacro(m, SIG_UNBLOCK))
1378
0
         goto finally;
1379
0
#endif
1380
0
#ifdef SIG_SETMASK
1381
0
    if (PyModule_AddIntMacro(m, SIG_SETMASK))
1382
0
         goto finally;
1383
0
#endif
1384
1385
0
    IntHandler = PyDict_GetItemString(d, "default_int_handler");
1386
0
    if (!IntHandler)
1387
0
        goto finally;
1388
0
    Py_INCREF(IntHandler);
1389
1390
0
    _Py_atomic_store_relaxed(&Handlers[0].tripped, 0);
1391
0
    for (i = 1; i < NSIG; i++) {
1392
0
        void (*t)(int);
1393
0
        t = PyOS_getsig(i);
1394
0
        _Py_atomic_store_relaxed(&Handlers[i].tripped, 0);
1395
0
        if (t == SIG_DFL)
1396
0
            Handlers[i].func = DefaultHandler;
1397
0
        else if (t == SIG_IGN)
1398
0
            Handlers[i].func = IgnoreHandler;
1399
0
        else
1400
0
            Handlers[i].func = Py_None; /* None of our business */
1401
0
        Py_INCREF(Handlers[i].func);
1402
0
    }
1403
0
    if (Handlers[SIGINT].func == DefaultHandler) {
1404
        /* Install default int handler */
1405
0
        Py_INCREF(IntHandler);
1406
0
        Py_SETREF(Handlers[SIGINT].func, IntHandler);
1407
0
        PyOS_setsig(SIGINT, signal_handler);
1408
0
    }
1409
1410
0
#ifdef SIGHUP
1411
0
    if (PyModule_AddIntMacro(m, SIGHUP))
1412
0
         goto finally;
1413
0
#endif
1414
0
#ifdef SIGINT
1415
0
    if (PyModule_AddIntMacro(m, SIGINT))
1416
0
         goto finally;
1417
0
#endif
1418
#ifdef SIGBREAK
1419
    if (PyModule_AddIntMacro(m, SIGBREAK))
1420
         goto finally;
1421
#endif
1422
0
#ifdef SIGQUIT
1423
0
    if (PyModule_AddIntMacro(m, SIGQUIT))
1424
0
         goto finally;
1425
0
#endif
1426
0
#ifdef SIGILL
1427
0
    if (PyModule_AddIntMacro(m, SIGILL))
1428
0
         goto finally;
1429
0
#endif
1430
0
#ifdef SIGTRAP
1431
0
    if (PyModule_AddIntMacro(m, SIGTRAP))
1432
0
         goto finally;
1433
0
#endif
1434
0
#ifdef SIGIOT
1435
0
    if (PyModule_AddIntMacro(m, SIGIOT))
1436
0
         goto finally;
1437
0
#endif
1438
0
#ifdef SIGABRT
1439
0
    if (PyModule_AddIntMacro(m, SIGABRT))
1440
0
         goto finally;
1441
0
#endif
1442
#ifdef SIGEMT
1443
    if (PyModule_AddIntMacro(m, SIGEMT))
1444
         goto finally;
1445
#endif
1446
0
#ifdef SIGFPE
1447
0
    if (PyModule_AddIntMacro(m, SIGFPE))
1448
0
         goto finally;
1449
0
#endif
1450
0
#ifdef SIGKILL
1451
0
    if (PyModule_AddIntMacro(m, SIGKILL))
1452
0
         goto finally;
1453
0
#endif
1454
0
#ifdef SIGBUS
1455
0
    if (PyModule_AddIntMacro(m, SIGBUS))
1456
0
         goto finally;
1457
0
#endif
1458
0
#ifdef SIGSEGV
1459
0
    if (PyModule_AddIntMacro(m, SIGSEGV))
1460
0
         goto finally;
1461
0
#endif
1462
0
#ifdef SIGSYS
1463
0
    if (PyModule_AddIntMacro(m, SIGSYS))
1464
0
         goto finally;
1465
0
#endif
1466
0
#ifdef SIGPIPE
1467
0
    if (PyModule_AddIntMacro(m, SIGPIPE))
1468
0
         goto finally;
1469
0
#endif
1470
0
#ifdef SIGALRM
1471
0
    if (PyModule_AddIntMacro(m, SIGALRM))
1472
0
         goto finally;
1473
0
#endif
1474
0
#ifdef SIGTERM
1475
0
    if (PyModule_AddIntMacro(m, SIGTERM))
1476
0
         goto finally;
1477
0
#endif
1478
0
#ifdef SIGUSR1
1479
0
    if (PyModule_AddIntMacro(m, SIGUSR1))
1480
0
         goto finally;
1481
0
#endif
1482
0
#ifdef SIGUSR2
1483
0
    if (PyModule_AddIntMacro(m, SIGUSR2))
1484
0
         goto finally;
1485
0
#endif
1486
0
#ifdef SIGCLD
1487
0
    if (PyModule_AddIntMacro(m, SIGCLD))
1488
0
         goto finally;
1489
0
#endif
1490
0
#ifdef SIGCHLD
1491
0
    if (PyModule_AddIntMacro(m, SIGCHLD))
1492
0
         goto finally;
1493
0
#endif
1494
0
#ifdef SIGPWR
1495
0
    if (PyModule_AddIntMacro(m, SIGPWR))
1496
0
         goto finally;
1497
0
#endif
1498
0
#ifdef SIGIO
1499
0
    if (PyModule_AddIntMacro(m, SIGIO))
1500
0
         goto finally;
1501
0
#endif
1502
0
#ifdef SIGURG
1503
0
    if (PyModule_AddIntMacro(m, SIGURG))
1504
0
         goto finally;
1505
0
#endif
1506
0
#ifdef SIGWINCH
1507
0
    if (PyModule_AddIntMacro(m, SIGWINCH))
1508
0
         goto finally;
1509
0
#endif
1510
0
#ifdef SIGPOLL
1511
0
    if (PyModule_AddIntMacro(m, SIGPOLL))
1512
0
         goto finally;
1513
0
#endif
1514
0
#ifdef SIGSTOP
1515
0
    if (PyModule_AddIntMacro(m, SIGSTOP))
1516
0
         goto finally;
1517
0
#endif
1518
0
#ifdef SIGTSTP
1519
0
    if (PyModule_AddIntMacro(m, SIGTSTP))
1520
0
         goto finally;
1521
0
#endif
1522
0
#ifdef SIGCONT
1523
0
    if (PyModule_AddIntMacro(m, SIGCONT))
1524
0
         goto finally;
1525
0
#endif
1526
0
#ifdef SIGTTIN
1527
0
    if (PyModule_AddIntMacro(m, SIGTTIN))
1528
0
         goto finally;
1529
0
#endif
1530
0
#ifdef SIGTTOU
1531
0
    if (PyModule_AddIntMacro(m, SIGTTOU))
1532
0
         goto finally;
1533
0
#endif
1534
0
#ifdef SIGVTALRM
1535
0
    if (PyModule_AddIntMacro(m, SIGVTALRM))
1536
0
         goto finally;
1537
0
#endif
1538
0
#ifdef SIGPROF
1539
0
    if (PyModule_AddIntMacro(m, SIGPROF))
1540
0
         goto finally;
1541
0
#endif
1542
0
#ifdef SIGXCPU
1543
0
    if (PyModule_AddIntMacro(m, SIGXCPU))
1544
0
         goto finally;
1545
0
#endif
1546
0
#ifdef SIGXFSZ
1547
0
    if (PyModule_AddIntMacro(m, SIGXFSZ))
1548
0
         goto finally;
1549
0
#endif
1550
0
#ifdef SIGRTMIN
1551
0
    if (PyModule_AddIntMacro(m, SIGRTMIN))
1552
0
         goto finally;
1553
0
#endif
1554
0
#ifdef SIGRTMAX
1555
0
    if (PyModule_AddIntMacro(m, SIGRTMAX))
1556
0
         goto finally;
1557
0
#endif
1558
#ifdef SIGINFO
1559
    if (PyModule_AddIntMacro(m, SIGINFO))
1560
         goto finally;
1561
#endif
1562
1563
0
#ifdef ITIMER_REAL
1564
0
    if (PyModule_AddIntMacro(m, ITIMER_REAL))
1565
0
         goto finally;
1566
0
#endif
1567
0
#ifdef ITIMER_VIRTUAL
1568
0
    if (PyModule_AddIntMacro(m, ITIMER_VIRTUAL))
1569
0
         goto finally;
1570
0
#endif
1571
0
#ifdef ITIMER_PROF
1572
0
    if (PyModule_AddIntMacro(m, ITIMER_PROF))
1573
0
         goto finally;
1574
0
#endif
1575
1576
0
#if defined (HAVE_SETITIMER) || defined (HAVE_GETITIMER)
1577
0
    ItimerError = PyErr_NewException("signal.ItimerError",
1578
0
            PyExc_OSError, NULL);
1579
0
    if (!ItimerError ||
1580
0
        PyDict_SetItemString(d, "ItimerError", ItimerError) < 0) {
1581
0
        goto finally;
1582
0
    }
1583
0
#endif
1584
1585
#ifdef CTRL_C_EVENT
1586
    if (PyModule_AddIntMacro(m, CTRL_C_EVENT))
1587
         goto finally;
1588
#endif
1589
1590
#ifdef CTRL_BREAK_EVENT
1591
    if (PyModule_AddIntMacro(m, CTRL_BREAK_EVENT))
1592
         goto finally;
1593
#endif
1594
1595
#ifdef MS_WINDOWS
1596
    /* Create manual-reset event, initially unset */
1597
    sigint_event = CreateEvent(NULL, TRUE, FALSE, FALSE);
1598
#endif
1599
1600
0
    if (PyErr_Occurred()) {
1601
0
        Py_DECREF(m);
1602
0
        m = NULL;
1603
0
    }
1604
1605
0
  finally:
1606
0
    return m;
1607
0
}
1608
1609
static void
1610
finisignal(void)
1611
0
{
1612
0
    int i;
1613
0
    PyObject *func;
1614
1615
0
    for (i = 1; i < NSIG; i++) {
1616
0
        func = Handlers[i].func;
1617
0
        _Py_atomic_store_relaxed(&Handlers[i].tripped, 0);
1618
0
        Handlers[i].func = NULL;
1619
0
        if (func != NULL && func != Py_None &&
1620
0
            func != DefaultHandler && func != IgnoreHandler)
1621
0
            PyOS_setsig(i, SIG_DFL);
1622
0
        Py_XDECREF(func);
1623
0
    }
1624
1625
0
    Py_CLEAR(IntHandler);
1626
0
    Py_CLEAR(DefaultHandler);
1627
0
    Py_CLEAR(IgnoreHandler);
1628
0
#ifdef HAVE_GETITIMER
1629
0
    Py_CLEAR(ItimerError);
1630
0
#endif
1631
0
}
1632
1633
1634
/* Declared in pyerrors.h */
1635
int
1636
PyErr_CheckSignals(void)
1637
3.68k
{
1638
3.68k
    _PyRuntimeState *runtime = &_PyRuntime;
1639
3.68k
    if (!is_main(runtime)) {
1640
0
        return 0;
1641
0
    }
1642
1643
3.68k
    return _PyErr_CheckSignals();
1644
3.68k
}
1645
1646
1647
/* Declared in cpython/pyerrors.h */
1648
int
1649
_PyErr_CheckSignals(void)
1650
3.68k
{
1651
3.68k
    int i;
1652
3.68k
    PyObject *f;
1653
1654
3.68k
    if (!_Py_atomic_load(&is_tripped))
1655
3.68k
        return 0;
1656
1657
    /*
1658
     * The is_tripped variable is meant to speed up the calls to
1659
     * PyErr_CheckSignals (both directly or via pending calls) when no
1660
     * signal has arrived. This variable is set to 1 when a signal arrives
1661
     * and it is set to 0 here, when we know some signals arrived. This way
1662
     * we can run the registered handlers with no signals blocked.
1663
     *
1664
     * NOTE: with this approach we can have a situation where is_tripped is
1665
     *       1 but we have no more signals to handle (Handlers[i].tripped
1666
     *       is 0 for every signal i). This won't do us any harm (except
1667
     *       we're gonna spent some cycles for nothing). This happens when
1668
     *       we receive a signal i after we zero is_tripped and before we
1669
     *       check Handlers[i].tripped.
1670
     */
1671
0
    _Py_atomic_store(&is_tripped, 0);
1672
1673
0
    if (!(f = (PyObject *)PyEval_GetFrame()))
1674
0
        f = Py_None;
1675
1676
0
    for (i = 1; i < NSIG; i++) {
1677
0
        if (_Py_atomic_load_relaxed(&Handlers[i].tripped)) {
1678
0
            PyObject *result = NULL;
1679
0
            PyObject *arglist = Py_BuildValue("(iO)", i, f);
1680
0
            _Py_atomic_store_relaxed(&Handlers[i].tripped, 0);
1681
1682
0
            if (arglist) {
1683
0
                result = PyEval_CallObject(Handlers[i].func,
1684
0
                                           arglist);
1685
0
                Py_DECREF(arglist);
1686
0
            }
1687
0
            if (!result) {
1688
0
                _Py_atomic_store(&is_tripped, 1);
1689
0
                return -1;
1690
0
            }
1691
1692
0
            Py_DECREF(result);
1693
0
        }
1694
0
    }
1695
1696
0
    return 0;
1697
0
}
1698
1699
1700
/* Simulate the effect of a signal.SIGINT signal arriving. The next time
1701
   PyErr_CheckSignals is called,  the Python SIGINT signal handler will be
1702
   raised.
1703
1704
   Missing signal handler for the SIGINT signal is silently ignored. */
1705
void
1706
PyErr_SetInterrupt(void)
1707
0
{
1708
0
    if ((Handlers[SIGINT].func != IgnoreHandler) &&
1709
0
        (Handlers[SIGINT].func != DefaultHandler)) {
1710
0
        trip_signal(SIGINT);
1711
0
    }
1712
0
}
1713
1714
void
1715
PyOS_InitInterrupts(void)
1716
0
{
1717
0
    PyObject *m = PyImport_ImportModule("_signal");
1718
0
    if (m) {
1719
0
        Py_DECREF(m);
1720
0
    }
1721
0
}
1722
1723
void
1724
PyOS_FiniInterrupts(void)
1725
0
{
1726
0
    finisignal();
1727
0
}
1728
1729
int
1730
PyOS_InterruptOccurred(void)
1731
0
{
1732
0
    if (_Py_atomic_load_relaxed(&Handlers[SIGINT].tripped)) {
1733
0
        _PyRuntimeState *runtime = &_PyRuntime;
1734
0
        if (!is_main(runtime)) {
1735
0
            return 0;
1736
0
        }
1737
0
        _Py_atomic_store_relaxed(&Handlers[SIGINT].tripped, 0);
1738
0
        return 1;
1739
0
    }
1740
0
    return 0;
1741
0
}
1742
1743
static void
1744
_clear_pending_signals(void)
1745
0
{
1746
0
    int i;
1747
0
    if (!_Py_atomic_load(&is_tripped))
1748
0
        return;
1749
0
    _Py_atomic_store(&is_tripped, 0);
1750
0
    for (i = 1; i < NSIG; ++i) {
1751
0
        _Py_atomic_store_relaxed(&Handlers[i].tripped, 0);
1752
0
    }
1753
0
}
1754
1755
void
1756
_PySignal_AfterFork(void)
1757
0
{
1758
    /* Clear the signal flags after forking so that they aren't handled
1759
     * in both processes if they came in just before the fork() but before
1760
     * the interpreter had an opportunity to call the handlers.  issue9535. */
1761
0
    _clear_pending_signals();
1762
0
}
1763
1764
int
1765
_PyOS_IsMainThread(void)
1766
0
{
1767
0
    _PyRuntimeState *runtime = &_PyRuntime;
1768
0
    return is_main(runtime);
1769
0
}
1770
1771
#ifdef MS_WINDOWS
1772
void *_PyOS_SigintEvent(void)
1773
{
1774
    /* Returns a manual-reset event which gets tripped whenever
1775
       SIGINT is received.
1776
1777
       Python.h does not include windows.h so we do cannot use HANDLE
1778
       as the return type of this function.  We use void* instead. */
1779
    return sigint_event;
1780
}
1781
#endif