signal: add strsignal() (#6017)

Co-authored-by: Vajrasky Kok <sky.kok@speaklikeaking.com>
This commit is contained in:
Antoine Pietri 2018-03-12 14:42:34 +01:00 committed by Antoine Pitrou
parent 4484f9dca9
commit 5d2a27de62
5 changed files with 109 additions and 1 deletions

View File

@ -207,6 +207,15 @@ The :mod:`signal` module defines the following functions:
installed from Python.
.. function:: strsignal(signalnum)
Return the system description of the signal *signalnum*, such as
"Interrupt", "Segmentation fault", etc. Returns :const:`None` if the signal
is not recognized.
.. versionadded:: 3.8
.. function:: pause()
Cause the process to sleep until a signal is received; the appropriate handler

View File

@ -43,6 +43,8 @@ class PosixTests(unittest.TestCase):
self.assertRaises(ValueError, signal.signal, 4242,
self.trivial_signal_handler)
self.assertRaises(ValueError, signal.strsignal, 4242)
def test_setting_signal_handler_to_none_raises_error(self):
self.assertRaises(TypeError, signal.signal,
signal.SIGUSR1, None)
@ -55,6 +57,10 @@ class PosixTests(unittest.TestCase):
signal.signal(signal.SIGHUP, hup)
self.assertEqual(signal.getsignal(signal.SIGHUP), hup)
def test_strsignal(self):
self.assertEqual(signal.strsignal(signal.SIGINT), "Interrupt")
self.assertEqual(signal.strsignal(signal.SIGTERM), "Terminated")
# Issue 3864, unknown if this affects earlier versions of freebsd also
def test_interprocess_signal(self):
dirname = os.path.dirname(__file__)

View File

@ -0,0 +1,2 @@
Add the strsignal() function in the signal module that returns the system
description of the given signal, as returned by strsignal(3).

View File

@ -129,6 +129,36 @@ exit:
return return_value;
}
PyDoc_STRVAR(signal_strsignal__doc__,
"strsignal($module, signalnum, /)\n"
"--\n"
"\n"
"Return the system description of the given signal.\n"
"\n"
"The return values can be such as \"Interrupt\", \"Segmentation fault\", etc.\n"
"Returns None if the signal is not recognized.");
#define SIGNAL_STRSIGNAL_METHODDEF \
{"strsignal", (PyCFunction)signal_strsignal, METH_O, signal_strsignal__doc__},
static PyObject *
signal_strsignal_impl(PyObject *module, int signalnum);
static PyObject *
signal_strsignal(PyObject *module, PyObject *arg)
{
PyObject *return_value = NULL;
int signalnum;
if (!PyArg_Parse(arg, "i:strsignal", &signalnum)) {
goto exit;
}
return_value = signal_strsignal_impl(module, signalnum);
exit:
return return_value;
}
#if defined(HAVE_SIGINTERRUPT)
PyDoc_STRVAR(signal_siginterrupt__doc__,
@ -440,4 +470,4 @@ exit:
#ifndef SIGNAL_PTHREAD_KILL_METHODDEF
#define SIGNAL_PTHREAD_KILL_METHODDEF
#endif /* !defined(SIGNAL_PTHREAD_KILL_METHODDEF) */
/*[clinic end generated code: output=36132f4189381fe0 input=a9049054013a1b77]*/
/*[clinic end generated code: output=7b41486acf93aa8e input=a9049054013a1b77]*/

View File

@ -504,6 +504,66 @@ signal_getsignal_impl(PyObject *module, int signalnum)
}
}
/*[clinic input]
signal.strsignal
signalnum: int
/
Return the system description of the given signal.
The return values can be such as "Interrupt", "Segmentation fault", etc.
Returns None if the signal is not recognized.
[clinic start generated code]*/
static PyObject *
signal_strsignal_impl(PyObject *module, int signalnum)
/*[clinic end generated code: output=44e12e1e3b666261 input=b77914b03f856c74]*/
{
char *res;
if (signalnum < 1 || signalnum >= NSIG) {
PyErr_SetString(PyExc_ValueError,
"signal number out of range");
return NULL;
}
#ifdef MS_WINDOWS
/* Custom redefinition of POSIX signals allowed on Windows */
switch (signalnum) {
case SIGINT:
res = "Interrupt";
break;
case SIGILL:
res = "Illegal instruction";
break;
case SIGABRT:
res = "Aborted";
break;
case SIGFPE:
res = "Floating point exception";
break;
case SIGSEGV:
res = "Segmentation fault";
break;
case SIGTERM:
res = "Terminated";
break;
default:
Py_RETURN_NONE;
}
#else
errno = 0;
res = strsignal(signalnum);
if (errno || res == NULL || strstr(res, "Unknown signal") != NULL)
Py_RETURN_NONE;
#endif
return Py_BuildValue("s", res);
}
#ifdef HAVE_SIGINTERRUPT
/*[clinic input]
@ -1152,6 +1212,7 @@ static PyMethodDef signal_methods[] = {
SIGNAL_SETITIMER_METHODDEF
SIGNAL_GETITIMER_METHODDEF
SIGNAL_SIGNAL_METHODDEF
SIGNAL_STRSIGNAL_METHODDEF
SIGNAL_GETSIGNAL_METHODDEF
{"set_wakeup_fd", (PyCFunction)signal_set_wakeup_fd, METH_VARARGS | METH_KEYWORDS, set_wakeup_fd_doc},
SIGNAL_SIGINTERRUPT_METHODDEF