Skip to content
Projects
Groups
Snippets
Help
Loading...
Help
Support
Keyboard shortcuts
?
Submit feedback
Contribute to GitLab
Sign in / Register
Toggle navigation
C
cpython
Project overview
Project overview
Details
Activity
Releases
Repository
Repository
Files
Commits
Branches
Tags
Contributors
Graph
Compare
Issues
0
Issues
0
List
Boards
Labels
Milestones
Merge Requests
0
Merge Requests
0
Analytics
Analytics
Repository
Value Stream
Wiki
Wiki
Members
Members
Collapse sidebar
Close sidebar
Activity
Graph
Create a new issue
Commits
Issue Boards
Open sidebar
Kirill Smelkov
cpython
Commits
6ed7ac48
Commit
6ed7ac48
authored
Jun 19, 2010
by
Jean-Paul Calderone
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
Revert r82089. Commit was intended for a branch.
parent
867c4354
Changes
7
Show whitespace changes
Inline
Side-by-side
Showing
7 changed files
with
7 additions
and
474 deletions
+7
-474
Doc/library/signal.rst
Doc/library/signal.rst
+3
-78
Lib/test/test_signal.py
Lib/test/test_signal.py
+2
-203
Misc/NEWS
Misc/NEWS
+0
-5
Modules/signalmodule.c
Modules/signalmodule.c
+0
-180
configure
configure
+1
-1
configure.in
configure.in
+1
-1
pyconfig.h.in
pyconfig.h.in
+0
-6
No files found.
Doc/library/signal.rst
View file @
6ed7ac48
...
...
@@ -13,6 +13,9 @@ rules for working with signals and their handlers:
underlying implementation), with the exception of the handler for
:const:`SIGCHLD`, which follows the underlying implementation.
* There is no way to "block" signals temporarily from critical sections (since
this is not supported by all Unix flavors).
* Although Python signal handlers are called asynchronously as far as the Python
user is concerned, they can only occur between the "atomic" instructions of the
Python interpreter. This means that signals arriving during long calculations
...
...
@@ -112,46 +115,6 @@ The variables defined in the :mod:`signal` module are:
in user and kernel space. SIGPROF is delivered upon expiration.
.. data:: SIG_BLOCK
A possible value for the *how* parameter to :func:`sigprocmask`
indicating that signals are to be blocked.
.. versionadded:: 2.7
.. data:: SIG_UNBLOCK
A possible value for the *how* parameter to :func:`sigprocmask`
indicating that signals are to be unblocked.
.. versionadded:: 2.7
.. data:: SIG_SETMASK
A possible value for the *how* parameter to :func:`sigprocmask`
indicating that the signal mask is to be replaced.
.. versionadded:: 2.7
.. data:: SFD_CLOEXEC
A possible flag in the *flags* parameter to :func:`signalfd` which causes
the new file descriptor to be marked as close-on-exec.
.. versionadded:: 2.7
.. data:: SFD_NONBLOCK
A possible flag in the *flags* parameter to :func:`signalfd` which causes
the new file description to be set non-blocking.
.. versionadded:: 2.7
The :mod:`signal` module defines one exception:
.. exception:: ItimerError
...
...
@@ -264,44 +227,6 @@ The :mod:`signal` module defines the following functions:
attribute descriptions in the :mod:`inspect` module).
.. function:: signalfd(fd, mask[, flags])
Create a new file descriptor on which to receive signals or modify the
mask of such a file descriptor previously created by this function.
Availability: Linux (See the manpage :manpage:`signalfd(2)` for further
information).
If *fd* is ``-1``, a new file descriptor will be created. Otherwise,
*fd* must be a file descriptor previously returned by this function.
*mask* is a list of signal numbers which will trigger data on this file
descriptor.
*flags* is a bit mask which may include any :const:`signal.SFD_*` flag.
.. versionadded:: 2.7
.. function:: sigprocmask(how, mask)
Set the signal mask for the process. The old signal mask is returned.
Availability: Unix (See the Unix man page :manpage:`sigprocmask(2)` and
:manpage:`pthread_sigmask(2)`.)
If *how* is :const:`signal.SIG_BLOCK`, the signals in the mask are added
to the set of blocked signals.
If *how* is :const:`signal.SIG_UNBLOCK`, the signals in the mask are
removed from the set of blocked signals.
If *how* is :const:`signal.SIG_SETMASK`, the signals in the mask are set
as blocked and the signals not in the mask are set as unblocked.
*mask* is a list of signal numbers (eg :const:`signal.SIGUSR1`).
.. versionadded:: 2.7
.. _signal-example:
Example
...
...
Lib/test/test_signal.py
View file @
6ed7ac48
...
...
@@ -462,210 +462,9 @@ class ItimerTest(unittest.TestCase):
# and the handler should have been called
self
.
assertEqual
(
self
.
hndl_called
,
True
)
class
SomeException
(
Exception
):
"""
A unique exception class to be raised by a signal handler to verify that the
signal handler was invoked.
"""
def
raiser
(
*
args
):
"""A signal handler which raises SomeException."""
raise
SomeException
()
class
SigprocmaskTests
(
unittest
.
TestCase
):
"""Tests for sigprocmask."""
def
_handle_sigusr1
(
self
):
old_handler
=
signal
.
signal
(
signal
.
SIGUSR1
,
raiser
)
self
.
addCleanup
(
signal
.
signal
,
signal
.
SIGUSR1
,
old_handler
)
def
test_signature
(
self
):
"""When invoked with other than two arguments, sigprocmask raises
TypeError.
"""
self
.
assertRaises
(
TypeError
,
signal
.
sigprocmask
)
self
.
assertRaises
(
TypeError
,
signal
.
sigprocmask
,
1
)
self
.
assertRaises
(
TypeError
,
signal
.
sigprocmask
,
1
,
2
,
3
)
def
test_invalid_how
(
self
):
"""If a value other than SIG_BLOCK, SIG_UNBLOCK, or SIG_SETMASK is
passed for the how argument to sigprocmask, ValueError is raised.
"""
message
=
"value specified for how
\
(
170
0
\
) i
n
valid"
with
self
.
assertRaisesRegexp
(
ValueError
,
message
):
signal
.
sigprocmask
(
1700
,
[])
def
test_invalid_signal_iterable
(
self
):
"""If iterating over the value passed for the signals parameter to
sigprocmask raises an exception, sigprocmask raises that exception.
"""
class
BrokenIter
(
object
):
def
__iter__
(
self
):
raise
RuntimeError
(
"my __iter__ is broken"
)
with
self
.
assertRaisesRegexp
(
RuntimeError
,
"my __iter__ is broken"
):
signal
.
sigprocmask
(
signal
.
SIG_BLOCK
,
BrokenIter
())
def
test_invalid_signal
(
self
):
"""If an object in the iterable passed for the signals parameter to
sigprocmask isn't an integer, TypeError is raised."""
with
self
.
assertRaisesRegexp
(
TypeError
,
"an integer is required"
):
signal
.
sigprocmask
(
signal
.
SIG_BLOCK
,
[
object
()])
def
test_return_previous_mask
(
self
):
"""sigprocmask returns a list of the signals previously masked.
"""
previous
=
signal
.
sigprocmask
(
signal
.
SIG_BLOCK
,
[
1
,
3
,
5
])
result
=
signal
.
sigprocmask
(
signal
.
SIG_BLOCK
,
previous
)
self
.
assertEquals
(
result
,
[
1
,
3
,
5
])
def
test_block
(
self
):
"""When invoked with SIG_BLOCK, sigprocmask blocks the signals in the
sigmask list.
"""
self
.
_handle_sigusr1
()
previous
=
signal
.
sigprocmask
(
signal
.
SIG_BLOCK
,
[
signal
.
SIGUSR1
])
os
.
kill
(
os
.
getpid
(),
signal
.
SIGUSR1
)
with
self
.
assertRaises
(
SomeException
):
# Expect to receive SIGUSR1 after unblocking it.
signal
.
sigprocmask
(
signal
.
SIG_SETMASK
,
previous
)
def
test_unblock
(
self
):
"""When invoked with SIG_UNBLOCK, sigprocmask unblocks the signals in
the sigmask list.
"""
self
.
_handle_sigusr1
()
previous
=
signal
.
sigprocmask
(
signal
.
SIG_BLOCK
,
[
signal
.
SIGUSR1
])
self
.
addCleanup
(
signal
.
sigprocmask
,
signal
.
SIG_SETMASK
,
previous
)
signal
.
sigprocmask
(
signal
.
SIG_UNBLOCK
,
[
signal
.
SIGUSR1
])
with
self
.
assertRaises
(
SomeException
):
os
.
kill
(
os
.
getpid
(),
signal
.
SIGUSR1
)
def
test_long_signals
(
self
):
"""sigprocmask accepts signal numbers as instances of long."""
previous
=
signal
.
sigprocmask
(
signal
.
SIG_SETMASK
,
[
long
(
signal
.
SIGUSR1
),
long
(
signal
.
SIGUSR2
)])
masked
=
signal
.
sigprocmask
(
signal
.
SIG_SETMASK
,
previous
)
self
.
assertEquals
(
masked
,
[
signal
.
SIGUSR1
,
signal
.
SIGUSR2
])
class
SignalfdTests
(
unittest
.
TestCase
):
"""
Tests for signal.signalfd.
"""
def
test_signature
(
self
):
"""When invoked with fewer than two arguments or more than three,
signalfd raises TypeError.
"""
self
.
assertRaises
(
TypeError
,
signal
.
signalfd
)
self
.
assertRaises
(
TypeError
,
signal
.
signalfd
,
1
)
self
.
assertRaises
(
TypeError
,
signal
.
signalfd
,
1
,
2
,
3
,
4
)
def
test_create_signalfd
(
self
):
"""When invoked with a file descriptor of -1, signalfd allocates a new
file descriptor for signal information delivery and returns it.
"""
fd
=
signal
.
signalfd
(
-
1
,
[])
self
.
assertTrue
(
isinstance
(
fd
,
int
))
os
.
close
(
fd
)
def
test_non_iterable_signals
(
self
):
"""If an object which is not iterable is passed for the sigmask list
argument to signalfd, the exception raised by trying to iterate over
that object is raised.
"""
self
.
assertRaises
(
TypeError
,
signal
.
signalfd
,
-
1
,
object
())
def
test_non_integer_signals
(
self
):
"""If any non-integer values are included in the sigmask list argument
to signalfd, the exception raised by the attempt to convert them to an
integer is raised.
"""
self
.
assertRaises
(
TypeError
,
signal
.
signalfd
,
-
1
,
[
object
()])
def
test_out_of_range_signal
(
self
):
"""If a signal number that is out of the valid range is included in the
sigmask list argument to signalfd, ValueError is raised.
"""
message
=
"signal number -2 out of range"
with
self
.
assertRaisesRegexp
(
ValueError
,
message
):
signal
.
signalfd
(
-
1
,
[
-
2
])
def
test_handle_signals
(
self
):
"""After signalfd is called, if a signal is received which was in the
sigmask list passed to that call, information about the signal can be
read from the fd returned by that call.
"""
fd
=
signal
.
signalfd
(
-
1
,
[
signal
.
SIGUSR2
])
self
.
addCleanup
(
os
.
close
,
fd
)
previous
=
signal
.
sigprocmask
(
signal
.
SIG_BLOCK
,
[
signal
.
SIGUSR2
])
self
.
addCleanup
(
signal
.
sigprocmask
,
signal
.
SIG_SETMASK
,
previous
)
os
.
kill
(
os
.
getpid
(),
signal
.
SIGUSR2
)
bytes
=
os
.
read
(
fd
,
128
)
self
.
assertTrue
(
bytes
)
def
test_close_on_exec
(
self
):
"""If the bit mask passed as the 3rd argument to signalfd includes
SFD_CLOEXEC, the returned file descriptor has FD_CLOEXEC set on it.
"""
import
fcntl
fd
=
signal
.
signalfd
(
-
1
,
[],
signal
.
SFD_CLOEXEC
)
self
.
addCleanup
(
os
.
close
,
fd
)
flags
=
fcntl
.
fcntl
(
fd
,
fcntl
.
F_GETFD
)
self
.
assertTrue
(
flags
&
fcntl
.
FD_CLOEXEC
)
def
test_nonblocking
(
self
):
"""If the bit mask passed as the 3rd argument to signalfd includes
SFD_NOBLOCK, the file description referenced by the returned file
descriptor has O_NONBLOCK set on it.
"""
import
fcntl
fd
=
signal
.
signalfd
(
-
1
,
[],
signal
.
SFD_NONBLOCK
)
self
.
addCleanup
(
os
.
close
,
fd
)
flags
=
fcntl
.
fcntl
(
fd
,
fcntl
.
F_GETFL
)
self
.
assertTrue
(
flags
&
os
.
O_NONBLOCK
)
def
test_default_flags
(
self
):
"""If an empty bit mask is passed as the 3rd argument to signalfd,
neither FD_CLOEXEC nor O_NONBLOCK is set on the resulting file
descriptor/description.
"""
import
fcntl
fd
=
signal
.
signalfd
(
-
1
,
[])
self
.
addCleanup
(
os
.
close
,
fd
)
flags
=
fcntl
.
fcntl
(
fd
,
fcntl
.
F_GETFD
)
self
.
assertFalse
(
flags
&
fcntl
.
FD_CLOEXEC
)
flags
=
fcntl
.
fcntl
(
fd
,
fcntl
.
F_GETFL
)
self
.
assertFalse
(
flags
&
os
.
O_NONBLOCK
)
def
test_main
():
support
.
run_unittest
(
BasicSignalTests
,
InterProcessSignalTests
,
WakeupSignalTests
,
SiginterruptTest
,
ItimerTest
,
SignalfdTests
,
SigprocmaskTests
)
support
.
run_unittest
(
BasicSignalTests
,
InterProcessSignalTests
,
WakeupSignalTests
,
SiginterruptTest
,
ItimerTest
)
if
__name__
==
"__main__"
:
...
...
Misc/NEWS
View file @
6ed7ac48
...
...
@@ -1025,11 +1025,6 @@ Library
- Issue #5949: added check for correct lineends in input from IMAP server
in imaplib.
- Issue #8407: The signal module gains the ``signalfd()`` and
``sigprocmask(2)`` functions providing access to the signalfd(2) and
sigprocmask(2) system calls respectively on Linux systems which implement
them.
- Add count() and reverse() methods to collections.deque().
- Fix variations of extending deques: d.extend(d) d.extendleft(d) d+=d
...
...
Modules/signalmodule.c
View file @
6ed7ac48
...
...
@@ -22,10 +22,6 @@
#ifdef HAVE_SYS_TIME_H
#include <sys/time.h>
#endif
#ifdef HAVE_SIGNALFD
#include <sys/signalfd.h>
#endif
#ifndef SIG_ERR
#define SIG_ERR ((PyOS_sighandler_t)(-1))
...
...
@@ -468,144 +464,6 @@ Returns current value of given itimer.");
#endif
static
int
_iterable_to_mask
(
PyObject
*
iterable
,
sigset_t
*
mask
)
{
static
const
char
*
range_format
=
"signal number %d out of range"
;
char
range_buffer
[
1024
];
int
result
=
0
;
PyObject
*
item
,
*
iterator
=
NULL
;
sigemptyset
(
mask
);
iterator
=
PyObject_GetIter
(
iterable
);
if
(
iterator
==
NULL
)
{
result
=
-
1
;
goto
error
;
}
while
((
item
=
PyIter_Next
(
iterator
)))
{
int
signum
=
PyInt_AsLong
(
item
);
Py_DECREF
(
item
);
if
(
signum
==
-
1
&&
PyErr_Occurred
())
{
result
=
-
1
;
goto
error
;
}
if
(
sigaddset
(
mask
,
signum
)
==
-
1
)
{
PyOS_snprintf
(
range_buffer
,
sizeof
(
range_buffer
),
range_format
,
signum
);
PyErr_SetString
(
PyExc_ValueError
,
range_buffer
);
result
=
-
1
;
goto
error
;
}
}
error:
Py_XDECREF
(
iterator
);
return
result
;
}
#if defined(HAVE_PTHREAD_SIGMASK) && !defined(HAVE_BROKEN_PTHREAD_SIGMASK)
# define PY_SIGMASK pthread_sigmask
#elif defined(HAVE_SIGPROCMASK)
# define PY_SIGMASK sigprocmask
#endif
#ifdef PY_SIGMASK
static
PyObject
*
signal_sigprocmask
(
PyObject
*
self
,
PyObject
*
args
)
{
static
const
char
*
how_format
=
"value specified for how (%d) invalid"
;
char
how_buffer
[
1024
];
int
how
,
sig
;
PyObject
*
signals
,
*
result
,
*
signum
;
sigset_t
mask
,
previous
;
if
(
!
PyArg_ParseTuple
(
args
,
"iO:sigprocmask"
,
&
how
,
&
signals
))
{
return
NULL
;
}
if
(
_iterable_to_mask
(
signals
,
&
mask
)
==
-
1
)
{
return
NULL
;
}
if
(
PY_SIGMASK
(
how
,
&
mask
,
&
previous
)
!=
0
)
{
PyOS_snprintf
(
how_buffer
,
sizeof
(
how_buffer
),
how_format
,
how
);
PyErr_SetString
(
PyExc_ValueError
,
how_buffer
);
return
NULL
;
}
result
=
PyList_New
(
0
);
if
(
result
==
NULL
)
{
return
NULL
;
}
for
(
sig
=
1
;
sig
<
NSIG
;
++
sig
)
{
if
(
sigismember
(
&
previous
,
sig
)
==
1
)
{
/* Handle the case where it is a member by adding the signal to
the result list. Ignore the other cases because they mean the
signal isn't a member of the mask or the signal was invalid,
and an invalid signal must have been our fault in constructing
the loop boundaries. */
signum
=
PyInt_FromLong
(
sig
);
if
(
signum
==
NULL
)
{
Py_DECREF
(
result
);
return
NULL
;
}
if
(
PyList_Append
(
result
,
signum
)
==
-
1
)
{
Py_DECREF
(
signum
);
Py_DECREF
(
result
);
return
NULL
;
}
Py_DECREF
(
signum
);
}
}
return
result
;
}
PyDoc_STRVAR
(
sigprocmask_doc
,
"sigprocmask(how, mask) -> old mask
\n
\
\n
\
Examine and change blocked signals."
);
#endif
#ifdef HAVE_SIGNALFD
static
PyObject
*
signal_signalfd
(
PyObject
*
self
,
PyObject
*
args
)
{
int
result
,
flags
=
0
;
sigset_t
mask
;
int
fd
;
PyObject
*
signals
;
if
(
!
PyArg_ParseTuple
(
args
,
"iO|i:signalfd"
,
&
fd
,
&
signals
,
&
flags
))
{
return
NULL
;
}
if
(
_iterable_to_mask
(
signals
,
&
mask
)
==
-
1
)
{
return
NULL
;
}
result
=
signalfd
(
-
1
,
&
mask
,
flags
);
if
(
result
==
-
1
)
{
PyErr_SetFromErrno
(
PyExc_OSError
);
return
NULL
;
}
return
PyInt_FromLong
(
result
);
}
PyDoc_STRVAR
(
signalfd_doc
,
"signalfd(fd, mask, flags)
\n
\
\n
\
Create a file descriptor for accepting signals."
);
#endif
/* List of functions defined in the module */
static
PyMethodDef
signal_methods
[]
=
{
#ifdef HAVE_ALARM
...
...
@@ -620,14 +478,6 @@ static PyMethodDef signal_methods[] = {
{
"signal"
,
signal_signal
,
METH_VARARGS
,
signal_doc
},
{
"getsignal"
,
signal_getsignal
,
METH_VARARGS
,
getsignal_doc
},
{
"set_wakeup_fd"
,
signal_set_wakeup_fd
,
METH_VARARGS
,
set_wakeup_fd_doc
},
#ifdef PY_SIGMASK
{
"sigprocmask"
,
signal_sigprocmask
,
METH_VARARGS
,
sigprocmask_doc
},
/* It's no longer needed, so clean up the namespace. */
#undef PY_SIGMASK
#endif
#ifdef HAVE_SIGNALFD
{
"signalfd"
,
signal_signalfd
,
METH_VARARGS
,
signalfd_doc
},
#endif
#ifdef HAVE_SIGINTERRUPT
{
"siginterrupt"
,
signal_siginterrupt
,
METH_VARARGS
,
siginterrupt_doc
},
#endif
...
...
@@ -961,36 +811,6 @@ PyInit_signal(void)
PyDict_SetItemString
(
d
,
"ItimerError"
,
ItimerError
);
#endif
#ifdef SIG_BLOCK
x
=
PyLong_FromLong
(
SIG_BLOCK
);
PyDict_SetItemString
(
d
,
"SIG_BLOCK"
,
x
);
Py_DECREF
(
x
);
#endif
#ifdef SIG_UNBLOCK
x
=
PyLong_FromLong
(
SIG_UNBLOCK
);
PyDict_SetItemString
(
d
,
"SIG_UNBLOCK"
,
x
);
Py_DECREF
(
x
);
#endif
#ifdef SIG_SETMASK
x
=
PyLong_FromLong
(
SIG_SETMASK
);
PyDict_SetItemString
(
d
,
"SIG_SETMASK"
,
x
);
Py_DECREF
(
x
);
#endif
#ifdef SFD_CLOEXEC
x
=
PyLong_FromLong
(
SFD_CLOEXEC
);
PyDict_SetItemString
(
d
,
"SFD_CLOEXEC"
,
x
);
Py_DECREF
(
x
);
#endif
#ifdef SFD_NONBLOCK
x
=
PyLong_FromLong
(
SFD_NONBLOCK
);
PyDict_SetItemString
(
d
,
"SFD_NONBLOCK"
,
x
);
Py_DECREF
(
x
);
#endif
#ifdef CTRL_C_EVENT
x
=
PyLong_FromLong
(
CTRL_C_EVENT
);
PyDict_SetItemString
(
d
,
"CTRL_C_EVENT"
,
x
);
...
...
configure
View file @
6ed7ac48
...
...
@@ -9297,7 +9297,7 @@ for ac_func in alarm setitimer getitimer bind_textdomain_codeset chown \
select
sem_open sem_timedwait sem_getvalue sem_unlink setegid seteuid
\
setgid
\
setlocale setregid setreuid setresuid setresgid setsid setpgid setpgrp setuid setvbuf
\
sigaction siginterrupt sig
nalfd sigprocmask sig
relse snprintf strftime strlcpy
\
sigaction siginterrupt sigrelse snprintf strftime strlcpy
\
sysconf tcgetpgrp tcsetpgrp tempnam timegm
times
tmpfile tmpnam tmpnam_r
\
truncate uname
unsetenv utimes waitpid wait3 wait4
\
wcscoll wcsftime wcsxfrm _getpty
...
...
configure.in
View file @
6ed7ac48
...
...
@@ -2580,7 +2580,7 @@ AC_CHECK_FUNCS(alarm setitimer getitimer bind_textdomain_codeset chown \
select sem_open sem_timedwait sem_getvalue sem_unlink setegid seteuid \
setgid \
setlocale setregid setreuid setresuid setresgid setsid setpgid setpgrp setuid setvbuf \
sigaction siginterrupt sig
nalfd sigprocmask sig
relse snprintf strftime strlcpy \
sigaction siginterrupt sigrelse snprintf strftime strlcpy \
sysconf tcgetpgrp tcsetpgrp tempnam timegm times tmpfile tmpnam tmpnam_r \
truncate uname unsetenv utimes waitpid wait3 wait4 \
wcscoll wcsftime wcsxfrm _getpty)
...
...
pyconfig.h.in
View file @
6ed7ac48
...
...
@@ -620,12 +620,6 @@
/* Define to 1 if you have the <signal.h> header file. */
#undef HAVE_SIGNAL_H
/* Define to 1 if you have the `signalfd' function. */
#undef HAVE_SIGNALFD
/* Define to 1 if you have the `sigprocmask' function. */
#undef HAVE_SIGPROCMASK
/* Define to 1 if you have the `sigrelse' function. */
#undef HAVE_SIGRELSE
...
...
Write
Preview
Markdown
is supported
0%
Try again
or
attach a new file
Attach a file
Cancel
You are about to add
0
people
to the discussion. Proceed with caution.
Finish editing this message first!
Cancel
Please
register
or
sign in
to comment