diff -r a22ef88143b9 Doc/library/signal.rst --- a/Doc/library/signal.rst Sat Oct 25 23:05:21 2014 -0500 +++ b/Doc/library/signal.rst Sun Oct 26 19:19:10 2014 +0700 @@ -72,7 +72,8 @@ :class:`enums `. :func:`getsignal`, :func:`pthread_sigmask`, :func:`sigpending` and :func:`sigwait` functions return human-readable - :class:`enums `. + :class:`enums `. :func:`strsignal` was added and it returns + the description of signal. The variables defined in the :mod:`signal` module are: @@ -209,6 +210,13 @@ installed from Python. +.. function:: strsignal(signalnum) + + Return the description for the signal *signalnum*. The returned value + may be :const:`None` if the signal is not recognized, or the description itself, + such as 'Interrupt', 'Killed', etc. + + .. function:: pause() Cause the process to sleep until a signal is received; the appropriate handler diff -r a22ef88143b9 Lib/test/test_signal.py --- a/Lib/test/test_signal.py Sat Oct 25 23:05:21 2014 -0500 +++ b/Lib/test/test_signal.py Sun Oct 26 19:19:10 2014 +0700 @@ -212,6 +212,8 @@ 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) @@ -224,6 +226,10 @@ 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.SIGKILL), "Killed") + @unittest.skipUnless(sys.platform == "win32", "Windows specific") class WindowsSignalTests(unittest.TestCase): diff -r a22ef88143b9 Modules/signalmodule.c --- a/Modules/signalmodule.c Sat Oct 25 23:05:21 2014 -0500 +++ b/Modules/signalmodule.c Sun Oct 26 19:19:10 2014 +0700 @@ -469,6 +469,43 @@ None -- if an unknown handler is in effect\n\ anything else -- the callable Python object used as a handler"); +static PyObject * +signal_strsignal(PyObject *self, PyObject *args) +{ + int sig_num, position; + char *strsignal_result, *pch; + char signal_description[40]; + + if (!PyArg_ParseTuple(args, "i:strsignal", &sig_num)) + return NULL; + if (sig_num < 1 || sig_num >= NSIG) { + PyErr_SetString(PyExc_ValueError, + "signal number out of range"); + return NULL; + } + strsignal_result = strsignal(sig_num); + if (strsignal_result == NULL || + strstr(strsignal_result, "Unknown signal") != NULL) + Py_RETURN_NONE; + /* On Mac, it returns 'Quit: 3', while on Linux it returns 'Quit'. */ + pch = strchr(strsignal_result, ':'); + if (pch) { + position = pch - strsignal_result; + strncpy(signal_description, strsignal_result, position); + signal_description[position] = '\0'; + return Py_BuildValue("s", signal_description); + } + return Py_BuildValue("s", strsignal_result); +} + +PyDoc_STRVAR(strsignal_doc, +"strsignal(sig) -> description\n\ +\n\ +Return the description for the given signal. The return value can be:\n\ +None -- if the signal is not recognized\n\ +'Interrupt' -- if the signal is SIGINT\n\ +and so on."); + #ifdef HAVE_SIGINTERRUPT PyDoc_STRVAR(siginterrupt_doc, "siginterrupt(sig, flag) -> None\n\ @@ -1052,6 +1089,7 @@ {"getitimer", signal_getitimer, METH_VARARGS, getitimer_doc}, #endif {"signal", signal_signal, METH_VARARGS, signal_doc}, + {"strsignal", signal_strsignal, METH_VARARGS, strsignal_doc}, {"getsignal", signal_getsignal, METH_VARARGS, getsignal_doc}, {"set_wakeup_fd", signal_set_wakeup_fd, METH_VARARGS, set_wakeup_fd_doc}, #ifdef HAVE_SIGINTERRUPT