Take out my (long since disabled) POSIX signal mask handling code.

I'm not going to have the time or energy to get this working x-platform
-- anyone who does is welcome to the code!
This commit is contained in:
Michael W. Hudson 2003-03-13 13:56:53 +00:00
parent 94afd3095e
commit 43ed43bfc1
5 changed files with 6 additions and 289 deletions

View file

@ -17,6 +17,10 @@ regardless of the underlying implementation), with the exception of
the handler for \constant{SIGCHLD}, which follows the underlying
implementation.
\item
There is no way to ``block'' signals temporarily from critical
sections (since this is not supported by all \UNIX{} flavors).
\item
Although Python signal handlers are called asynchronously as far as
the Python user is concerned, they can only occur between the
@ -88,16 +92,6 @@ The variables defined in the \module{signal} module are:
One more than the number of the highest signal number.
\end{datadesc}
\begin{datadesc}{SIG_BLOCK}
\end{datadesc}
\begin{datadesc}{SIG_UNBLOCK}
\end{datadesc}
\begin{datadesc}{SIG_SETMASK}
These constants are for use as the first parameter of the
\function{sigprocmask} function described below.
\end{datadesc}
The \module{signal} module defines the following functions:
\begin{funcdesc}{alarm}{time}
@ -150,46 +144,6 @@ The \module{signal} module defines the following functions:
\obindex{frame}
\end{funcdesc}
The following functions are supported if your platform does. Most
modern \UNIX-alikes now do.
\begin{funcdesc}{sigpending}{}
Return the set of pending signals, i.e. a list containing the
numbers of those signals that have been raised while blocked.
\versionadded{2.3}
\end{funcdesc}
\begin{funcdesc}{sigprocmask}{how, sigset}
Change the list of currently blocked signals. The parameter
\var{how} should be one of \constant{SIG_BLOCK},
\constant{SIG_UNBLOCK} or \constant{SIG_SETMASK} and \var{sigset}
should be a sequence of signal numbers. The behaviour of the call
depends on the value of \var{how}:
\begin{tableii}{l|l}{textrm}{Value of \var{how}}{Behaviour of call}
\lineii{\constant{SIG_BLOCK}}
{The set of blocked signals is the union of the current set
and \var{sigset}.}
\lineii{\constant{SIG_UNBLOCK}}
{The signals in \var{sigset} are removed from the current
set of blocked signals. It is legal to attempt to unblock
a signal which is not blocked.}
\lineii{\constant{SIG_SETMASK}}
{The set of blocked signals is set to the \var{sigset}.}
\end{tableii}
A list contating the numbers of the previously blocked signals is
returned.
\versionadded{2.3}
\end{funcdesc}
\begin{funcdesc}{sigsuspend}{sigset}
Temporarily replace the signal mask with \var{sigset} (which should
be a sequnce of signal numbers) and suspend the process until a
signal is received.
\versionadded{2.3}
\end{funcdesc}
\subsection{Example}
\nodename{Signal Example}

View file

@ -1485,10 +1485,8 @@ it immediately.)
location.
\item Support for more advanced POSIX signal handling was added
to the \module{signal} module by adding the \function{sigpending},
\function{sigprocmask} and \function{sigsuspend} functions where supported
by the platform. These functions make it possible to avoid some previously
unavoidable race conditions with signal handling.
to the \module{signal} but then removed again as it proved impossible
to make it work reliably across platforms.
\item The \module{socket} module now supports timeouts. You
can call the \method{settimeout(\var{t})} method on a socket object to

View file

@ -64,64 +64,3 @@ except KeyboardInterrupt:
if verbose:
print "KeyboardInterrupt (assume the alarm() went off)"
if hasattr(signal, "sigprocmask"):
class HupDelivered(Exception):
pass
def hup(signum, frame):
raise HupDelivered
def hup2(signum, frame):
signal.signal(signal.SIGHUP, hup)
return
signal.signal(signal.SIGHUP, hup)
if verbose:
print "blocking SIGHUP"
defaultmask = signal.sigprocmask(signal.SIG_BLOCK, [signal.SIGHUP])
if verbose:
print "sending SIGHUP"
try:
os.kill(pid, signal.SIGHUP)
except HupDelivered:
raise TestFailed, "HUP not blocked"
if signal.SIGHUP not in signal.sigpending():
raise TestFailed, "HUP not pending"
if verbose:
print "unblocking SIGHUP"
try:
signal.sigprocmask(signal.SIG_UNBLOCK, [signal.SIGHUP])
except HupDelivered:
pass
else:
raise TestFailed, "HUP not delivered"
if verbose:
print "testing sigsuspend"
signal.sigprocmask(signal.SIG_BLOCK, [signal.SIGHUP])
signal.signal(signal.SIGHUP, hup2)
if not os.fork():
time.sleep(2)
os.kill(pid, signal.SIGHUP)
time.sleep(2)
os.kill(pid, signal.SIGHUP)
os._exit(0)
else:
try:
signal.sigsuspend(defaultmask)
except:
raise TestFailed, "sigsuspend erroneously raised"
try:
signal.sigsuspend(defaultmask)
except HupDelivered:
pass
else:
raise TestFailed, "sigsupsend didn't raise"

View file

@ -982,9 +982,6 @@ Extension modules
of sizeof(int)!=sizeof(long)!=sizeof(void*) is delayed until dl.open
is called.
- signal.sigpending, signal.sigprocmask and signal.sigsuspend have
been added where available.
- The sys module acquired a new attribute, api_version, which evaluates
to the value of the PYTHON_API_VERSION macro with which the
interpreter was compiled.

View file

@ -269,153 +269,6 @@ SIG_DFL -- if the default action for the signal is in effect\n\
None -- if an unknown handler is in effect\n\
anything else -- the callable Python object used as a handler");
#ifdef HAVE_SIGPROCMASK /* we assume that having SIGPROCMASK is enough
to guarantee full POSIX signal handling */
/* returns 0 for success, <0 for failure (with exception set) */
static int
_signal_list_to_sigset(PyObject* seq, sigset_t* set, char* mesg)
{
int i, len, val;
seq = PySequence_Fast(seq, mesg);
if (!seq)
return -1;
len = PySequence_Fast_GET_SIZE(seq);
sigemptyset(set);
for (i = 0; i < len; i++) {
val = PyInt_AsLong(PySequence_Fast_GET_ITEM(seq, i));
if (val == -1 && PyErr_Occurred()) {
Py_DECREF(seq);
return -1;
}
if (sigaddset(set, val) < 0) {
Py_DECREF(seq);
PyErr_SetFromErrno(PyExc_ValueError);
return -1;
}
}
Py_DECREF(seq);
return 0;
}
static PyObject*
_signal_sigset_to_list(sigset_t* set)
{
PyObject* ret;
PyObject* ob;
int i;
ret = PyList_New(0);
if (!ret)
return NULL;
for (i = 1; i < NSIG; i++) {
if (sigismember(set, i)) {
ob = PyInt_FromLong(i);
if (!ob) {
Py_DECREF(ret);
return NULL;
}
PyList_Append(ret, ob);
Py_DECREF(ob);
}
}
return ret;
}
static PyObject*
signal_sigprocmask(PyObject* self, PyObject* args)
{
int how;
sigset_t newset, oldset;
PyObject* seq;
if (!PyArg_ParseTuple(args, "iO", &how, &seq))
return NULL;
if (_signal_list_to_sigset(seq, &newset,
"sigprocmask requires a sequence") < 0)
return NULL;
if (sigprocmask(how, &newset, &oldset) < 0) {
return PyErr_SetFromErrno(PyExc_ValueError);
}
if (PyErr_CheckSignals())
return NULL;
return _signal_sigset_to_list(&oldset);
}
PyDoc_STRVAR(sigprocmask_doc,
"sigprocmask(how, sigset) -> sigset\n\
\n\
Change the list of currently blocked signals. The parameter how should be\n\
one of SIG_BLOCK, SIG_UNBLOCK or SIG_SETMASK and sigset should be a\n\
sequence of signal numbers. The behaviour of the call depends on the value\n\
of how:\n\
\n\
SIG_BLOCK\n\
The set of blocked signals is the union of the current set and the\n\
sigset argument.\n\
SIG_UNBLOCK\n\
The signals in sigset are removed from the current set of blocked\n\
signals. It is legal to attempt to unblock a signal which is not\n\
blocked.\n\
SIG_SETMASK\n\
The set of blocked signals is set to the argument set.\n\
\n\
A list contating the numbers of the previously blocked signals is returned.");
static PyObject*
signal_sigpending(PyObject* self)
{
sigset_t set;
if (sigpending(&set) < 0) {
return PyErr_SetFromErrno(PyExc_ValueError);
}
return _signal_sigset_to_list(&set);
}
PyDoc_STRVAR(sigpending_doc,
"sigpending() -> sigset\n\
\n\
Return the set of pending signals, i.e. a list containing the numbers of\n\
those signals that have been raised while blocked.");
static PyObject*
signal_sigsuspend(PyObject* self, PyObject* arg)
{
sigset_t set;
if (_signal_list_to_sigset(arg, &set,
"sigsuspend requires a sequence") < 0)
return NULL;
Py_BEGIN_ALLOW_THREADS
sigsuspend(&set);
Py_END_ALLOW_THREADS
if (PyErr_CheckSignals())
return NULL;
Py_INCREF(Py_None);
return Py_None;
}
PyDoc_STRVAR(sigsuspend_doc,
"sigsuspend(sigset) -> None\n\
\n\
Temporarily replace the signal mask with sigset (which should be a sequence\n\
of signal numbers) and suspend the process until a signal is received.");
#endif
/* List of functions defined in the module */
static PyMethodDef signal_methods[] = {
@ -430,14 +283,6 @@ static PyMethodDef signal_methods[] = {
#endif
{"default_int_handler", signal_default_int_handler,
METH_VARARGS, default_int_handler_doc},
#ifdef HAVE_SIGPROCMASK
{"sigprocmask", (PyCFunction)signal_sigprocmask,
METH_VARARGS, sigprocmask_doc},
{"sigpending", (PyCFunction)signal_sigpending,
METH_NOARGS, sigpending_doc},
{"sigsuspend", (PyCFunction)signal_sigsuspend,
METH_O, sigsuspend_doc},
#endif
{NULL, NULL} /* sentinel */
};
@ -453,10 +298,6 @@ getsignal() -- get the signal action for a given signal\n\
pause() -- wait until a signal arrives [Unix only]\n\
default_int_handler() -- default SIGINT handler\n\
\n\
sigpending() |\n\
sigprocmask() |-- posix signal mask handling [Unix only]\n\
sigsuspend() |\n\
\n\
Constants:\n\
\n\
SIG_DFL -- used to refer to the system default handler\n\
@ -705,18 +546,6 @@ initsignal(void)
PyDict_SetItemString(d, "SIGINFO", x);
Py_XDECREF(x);
#endif
#ifdef HAVE_SIGPROCMASK
x = PyInt_FromLong(SIG_BLOCK);
PyDict_SetItemString(d, "SIG_BLOCK", x);
Py_XDECREF(x);
x = PyInt_FromLong(SIG_UNBLOCK);
PyDict_SetItemString(d, "SIG_UNBLOCK", x);
Py_XDECREF(x);
x = PyInt_FromLong(SIG_SETMASK);
PyDict_SetItemString(d, "SIG_SETMASK", x);
Py_XDECREF(x);
#endif
if (!PyErr_Occurred())
return;