This commit is contained in:
parent
bc99b94232
commit
eed0cf819e
196
python-2.5-subprocess-eintr-safety.patch
Normal file
196
python-2.5-subprocess-eintr-safety.patch
Normal file
@ -0,0 +1,196 @@
|
||||
--- Lib/subprocess.py 2007-03-14 19:16:36.000000000 +0100
|
||||
+++ Lib/subprocess.py 2007-03-14 19:18:50.000000000 +0100
|
||||
@@ -655,12 +655,12 @@ class Popen(object):
|
||||
stderr = None
|
||||
if self.stdin:
|
||||
if input:
|
||||
- self.stdin.write(input)
|
||||
+ self._fo_write_no_intr(self.stdin, input)
|
||||
self.stdin.close()
|
||||
elif self.stdout:
|
||||
- stdout = self.stdout.read()
|
||||
+ stdout = self._fo_read_no_intr(self.stdout)
|
||||
elif self.stderr:
|
||||
- stderr = self.stderr.read()
|
||||
+ stderr = self._fo_read_no_intr(self.stderr)
|
||||
self.wait()
|
||||
return (stdout, stderr)
|
||||
|
||||
@@ -977,6 +977,62 @@ class Popen(object):
|
||||
pass
|
||||
|
||||
|
||||
+ def _read_no_intr(self, fd, buffersize):
|
||||
+ """Like os.read, but retries on EINTR"""
|
||||
+ while True:
|
||||
+ try:
|
||||
+ return os.read(fd, buffersize)
|
||||
+ except OSError, e:
|
||||
+ if e.errno == errno.EINTR:
|
||||
+ continue
|
||||
+ else:
|
||||
+ raise
|
||||
+
|
||||
+
|
||||
+ def _write_no_intr(self, fd, s):
|
||||
+ """Like os.write, but retries on EINTR"""
|
||||
+ while True:
|
||||
+ try:
|
||||
+ return os.write(fd, s)
|
||||
+ except OSError, e:
|
||||
+ if e.errno == errno.EINTR:
|
||||
+ continue
|
||||
+ else:
|
||||
+ raise
|
||||
+
|
||||
+ def _waitpid_no_intr(self, pid, options):
|
||||
+ """Like os.waitpid, but retries on EINTR"""
|
||||
+ while True:
|
||||
+ try:
|
||||
+ return os.waitpid(pid, options)
|
||||
+ except OSError, e:
|
||||
+ if e.errno == errno.EINTR:
|
||||
+ continue
|
||||
+ else:
|
||||
+ raise
|
||||
+
|
||||
+ def _fo_read_no_intr(self, obj):
|
||||
+ """Like obj.read(), but retries on EINTR"""
|
||||
+ while True:
|
||||
+ try:
|
||||
+ return obj.read()
|
||||
+ except IOError, e:
|
||||
+ if e.errno == errno.EINTR:
|
||||
+ continue
|
||||
+ else:
|
||||
+ raise
|
||||
+
|
||||
+ def _fo_write_no_intr(self, obj, data):
|
||||
+ """Like obj.write(), but retries on EINTR"""
|
||||
+ while True:
|
||||
+ try:
|
||||
+ return obj.write(data)
|
||||
+ except IOError, e:
|
||||
+ if e.errno == errno.EINTR:
|
||||
+ continue
|
||||
+ else:
|
||||
+ raise
|
||||
+
|
||||
def _execute_child(self, args, executable, preexec_fn, close_fds,
|
||||
cwd, env, universal_newlines,
|
||||
startupinfo, creationflags, shell,
|
||||
@@ -1055,7 +1121,7 @@ class Popen(object):
|
||||
exc_value,
|
||||
tb)
|
||||
exc_value.child_traceback = ''.join(exc_lines)
|
||||
- os.write(errpipe_write, pickle.dumps(exc_value))
|
||||
+ self._write_no_intr(errpipe_write, pickle.dumps(exc_value))
|
||||
|
||||
# This exitcode won't be reported to applications, so it
|
||||
# really doesn't matter what we return.
|
||||
@@ -1071,10 +1137,10 @@ class Popen(object):
|
||||
os.close(errwrite)
|
||||
|
||||
# Wait for exec to fail or succeed; possibly raising exception
|
||||
- data = os.read(errpipe_read, 1048576) # Exceptions limited to 1 MB
|
||||
+ data = self._read_no_intr(errpipe_read, 1048576) # Exceptions limited to 1 MB
|
||||
os.close(errpipe_read)
|
||||
if data != "":
|
||||
- os.waitpid(self.pid, 0)
|
||||
+ self._waitpid_no_intr(self.pid, 0)
|
||||
child_exception = pickle.loads(data)
|
||||
raise child_exception
|
||||
|
||||
@@ -1094,7 +1160,7 @@ class Popen(object):
|
||||
attribute."""
|
||||
if self.returncode is None:
|
||||
try:
|
||||
- pid, sts = os.waitpid(self.pid, os.WNOHANG)
|
||||
+ pid, sts = self._waitpid_no_intr(self.pid, os.WNOHANG)
|
||||
if pid == self.pid:
|
||||
self._handle_exitstatus(sts)
|
||||
except os.error:
|
||||
@@ -1107,7 +1173,7 @@ class Popen(object):
|
||||
"""Wait for child process to terminate. Returns returncode
|
||||
attribute."""
|
||||
if self.returncode is None:
|
||||
- pid, sts = os.waitpid(self.pid, 0)
|
||||
+ pid, sts = self._waitpid_no_intr(self.pid, 0)
|
||||
self._handle_exitstatus(sts)
|
||||
return self.returncode
|
||||
|
||||
@@ -1135,27 +1201,33 @@ class Popen(object):
|
||||
|
||||
input_offset = 0
|
||||
while read_set or write_set:
|
||||
- rlist, wlist, xlist = select.select(read_set, write_set, [])
|
||||
+ try:
|
||||
+ rlist, wlist, xlist = select.select(read_set, write_set, [])
|
||||
+ except select.error, e:
|
||||
+ if e[0] == errno.EINTR:
|
||||
+ continue
|
||||
+ else:
|
||||
+ raise
|
||||
|
||||
if self.stdin in wlist:
|
||||
# When select has indicated that the file is writable,
|
||||
# we can write up to PIPE_BUF bytes without risk
|
||||
# blocking. POSIX defines PIPE_BUF >= 512
|
||||
- bytes_written = os.write(self.stdin.fileno(), buffer(input, input_offset, 512))
|
||||
+ bytes_written = self._write_no_intr(self.stdin.fileno(), buffer(input, input_offset, 512))
|
||||
input_offset += bytes_written
|
||||
if input_offset >= len(input):
|
||||
self.stdin.close()
|
||||
write_set.remove(self.stdin)
|
||||
|
||||
if self.stdout in rlist:
|
||||
- data = os.read(self.stdout.fileno(), 1024)
|
||||
+ data = self._read_no_intr(self.stdout.fileno(), 1024)
|
||||
if data == "":
|
||||
self.stdout.close()
|
||||
read_set.remove(self.stdout)
|
||||
stdout.append(data)
|
||||
|
||||
if self.stderr in rlist:
|
||||
- data = os.read(self.stderr.fileno(), 1024)
|
||||
+ data = self._read_no_intr(self.stderr.fileno(), 1024)
|
||||
if data == "":
|
||||
self.stderr.close()
|
||||
read_set.remove(self.stderr)
|
||||
--- Lib/test/test_subprocess.py 2007-03-14 19:16:36.000000000 +0100
|
||||
+++ Lib/test/test_subprocess.py 2007-03-14 19:18:57.000000000 +0100
|
||||
@@ -580,6 +578,34 @@ class ProcessTestCase(unittest.TestCase)
|
||||
os.remove(fname)
|
||||
self.assertEqual(rc, 47)
|
||||
|
||||
+ def test_eintr(self):
|
||||
+ # retries on EINTR for an argv
|
||||
+
|
||||
+ # send ourselves a signal that causes EINTR
|
||||
+ prev_handler = signal.signal(signal.SIGALRM, lambda x,y: 1)
|
||||
+ signal.alarm(1)
|
||||
+ time.sleep(0.5)
|
||||
+
|
||||
+ rc = subprocess.Popen(['sleep', '1'])
|
||||
+ self.assertEqual(rc.wait(), 0)
|
||||
+
|
||||
+ signal.signal(signal.SIGALRM, prev_handler)
|
||||
+
|
||||
+ def test_eintr_out(self):
|
||||
+ # retries on EINTR for a shell call and pipelining
|
||||
+
|
||||
+ # send ourselves a signal that causes EINTR
|
||||
+ prev_handler = signal.signal(signal.SIGALRM, lambda x,y: 1)
|
||||
+ signal.alarm(1)
|
||||
+ time.sleep(0.5)
|
||||
+
|
||||
+ rc = subprocess.Popen("sleep 1; echo hello",
|
||||
+ shell=True, stdout=subprocess.PIPE)
|
||||
+ out = rc.communicate()[0]
|
||||
+ self.assertEqual(rc.returncode, 0)
|
||||
+ self.assertEqual(out, "hello\n")
|
||||
+
|
||||
+ signal.signal(signal.SIGALRM, prev_handler)
|
||||
|
||||
#
|
||||
# Windows tests
|
@ -17,7 +17,7 @@ Group: Development/Languages/Python
|
||||
BuildRoot: %{_tmppath}/%{name}-%{version}-build
|
||||
Summary: Additional Package Documentation for Python.
|
||||
Version: 2.5.1
|
||||
Release: 1
|
||||
Release: 15
|
||||
%define pyver %{version}
|
||||
BuildArch: noarch
|
||||
%define tarname Python-%{pyver}
|
||||
|
@ -1,3 +1,16 @@
|
||||
-------------------------------------------------------------------
|
||||
Fri Jul 27 14:51:03 CEST 2007 - jmatejek@suse.cz
|
||||
|
||||
- removed emacs python-mode and dependency on emacs
|
||||
|
||||
-------------------------------------------------------------------
|
||||
Fri Jun 8 16:33:09 CEST 2007 - jmatejek@suse.cz
|
||||
|
||||
- revisited & explained failing tests
|
||||
- applied EINTR recovery patch (#278622)
|
||||
- experimental replacement of shebang strings,
|
||||
removing dependency on /usr/bin/env
|
||||
|
||||
-------------------------------------------------------------------
|
||||
Thu May 24 18:47:20 CEST 2007 - jmatejek@suse.cz
|
||||
|
||||
|
41
python.spec
41
python.spec
@ -11,25 +11,24 @@
|
||||
# norootforbuild
|
||||
|
||||
Name: python
|
||||
BuildRequires: blt db-devel emacs-nox gcc-c++ gdbm-devel gmp-devel libbz2-devel ncurses-devel openssl-devel readline-devel sqlite-devel tk-devel xorg-x11-devel
|
||||
BuildRequires: blt db-devel gcc-c++ gdbm-devel gmp-devel libbz2-devel ncurses-devel openssl-devel readline-devel sqlite-devel tk-devel xorg-x11-devel
|
||||
Requires: openssl >= 0.9.8e
|
||||
URL: http://www.python.org/
|
||||
License: X11/MIT
|
||||
License: X11/MIT, PSF LICENSE AGREEMENT FOR PYTHON 2.3
|
||||
Group: Development/Languages/Python
|
||||
Autoreqprov: on
|
||||
Obsoletes: python-nothreads python21
|
||||
Summary: Python Interpreter
|
||||
Version: 2.5.1
|
||||
Release: 1
|
||||
Release: 18
|
||||
%define tarname Python-%{version}
|
||||
Source0: %{tarname}.tar.bz2
|
||||
Source6: README.SUSE
|
||||
Source7: suse-start-python-mode.el
|
||||
Source8: pythonstart
|
||||
Source9: python.sh
|
||||
Source10: python.csh
|
||||
#Source11: testfiles.tar.bz2
|
||||
# issues with copyrighted files
|
||||
# issues with copyrighted Unicode testing files
|
||||
Source13: distutils.cfg
|
||||
Patch01: Python-2.3.3-dirs.patch
|
||||
Patch10: python-distutils-rpm-8.patch
|
||||
@ -38,6 +37,7 @@ Patch23: ssl-compat.diff
|
||||
Patch25: python-2.4.2-canonicalize2.patch
|
||||
Patch26: python-2.4-localpath.patch
|
||||
Patch27: python-2.5-https_warn.patch
|
||||
Patch28: python-2.5-subprocess-eintr-safety.patch
|
||||
BuildRoot: %{_tmppath}/%{name}-%{version}-build
|
||||
%define python_version %(echo %{version} | head -c 3)
|
||||
%define idle_name idle
|
||||
@ -95,7 +95,7 @@ Authors:
|
||||
|
||||
%package devel
|
||||
Requires: python = %{version} python-tk
|
||||
Summary: Include Files and Libraries Mandatory for Building Python Modules.
|
||||
Summary: Include Files and Libraries Mandatory for Building Python Modules
|
||||
Group: Development/Languages/Python
|
||||
Autoreqprov: on
|
||||
|
||||
@ -196,12 +196,10 @@ Python2.x, it is part of the core Python distribution.
|
||||
%patch25
|
||||
%patch26
|
||||
%patch27
|
||||
%patch28
|
||||
# some cleanup
|
||||
find . -name .cvsignore -type f -print0 | xargs -0 rm -f
|
||||
find . -name CVS -type d -print0 | xargs -0 rm -rf
|
||||
# replace rest of /usr/local/bin/python with /usr/bin/env python
|
||||
find . -name '*.py' -type f -print0 | xargs -0 grep -lE '^#! ?(/usr/.*bin/)?python' | xargs sed -r -i -e '1s@^#![[:space:]]*(/usr/(local/)?bin/)?python@#!/usr/bin/env python@'
|
||||
# the grep inbetween makes it a) faster and b) compile at all :p
|
||||
|
||||
%build
|
||||
########################################
|
||||
@ -236,10 +234,9 @@ make %{?jobs:-j%jobs} DESTDIR=$RPM_BUILD_ROOT
|
||||
%ifnarch hppa %arm
|
||||
# extensive bsddb test fails (probably on all 64-bit arches):
|
||||
# Berkeley DB library configured to support only private environments
|
||||
# test_file fails in autobuild env. probably a bug in python, will fix/report
|
||||
# test_file fails in autobuild env - "stdin.seek(-1)" wrongly succeeds. probably an issue with autobuild's stdin
|
||||
# test_nis fails in autobuild env. probably a misconfiguration of mbuild servers
|
||||
EXCLUDE="-x test_file -x test_nis"
|
||||
#EXCLUDE=""
|
||||
%ifarch ia64
|
||||
EXCLUDE="$EXCLUDE -x test_mmap -x test_threaded_import"
|
||||
%endif
|
||||
@ -249,13 +246,12 @@ make test TESTOPTS="-l $EXCLUDE"
|
||||
# use network, be verbose:
|
||||
#make test TESTOPTS="-l -u network -v"
|
||||
%endif
|
||||
########################################
|
||||
# precompile emacs stuff
|
||||
########################################
|
||||
emacs --batch --no-site -f batch-byte-compile Misc/python-mode.el
|
||||
|
||||
%install
|
||||
rm -rf $RPM_BUILD_ROOT
|
||||
# replace rest of /usr/local/bin/python with /usr/bin/env python
|
||||
find . -wholename "./Parser" -prune -o -name '*.py' -type f -print0 | xargs -0 grep -lE '^#! *(/usr/.*bin/(env +)?)?python' | xargs sed -r -i -e '1s@^#![[:space:]]*(/usr/(local/)?bin/(env +)?)?python@#!/usr/bin/python@'
|
||||
# the grep inbetween makes it much faster
|
||||
########################################
|
||||
# install it
|
||||
########################################
|
||||
@ -308,13 +304,6 @@ install -d -m755 ${RPM_BUILD_ROOT}/etc/%{idle_name}
|
||||
# install Makefile.pre.in and Makefile.pre
|
||||
cp Makefile Makefile.pre.in Makefile.pre $RPM_BUILD_ROOT%{_libdir}/python%{python_version}/config/
|
||||
########################################
|
||||
# emacs stuff
|
||||
########################################
|
||||
install -d $RPM_BUILD_ROOT%{_prefix}/share/emacs/site-lisp
|
||||
install -p -m644 Misc/python-mode.el $RPM_BUILD_ROOT%{_prefix}/share/emacs/site-lisp
|
||||
install -p -m644 Misc/python-mode.elc $RPM_BUILD_ROOT%{_prefix}/share/emacs/site-lisp
|
||||
install -p -m644 %{S:7} $RPM_BUILD_ROOT%{_prefix}/share/emacs/site-lisp
|
||||
########################################
|
||||
# startup script
|
||||
########################################
|
||||
install -m 644 %{S:8} $RPM_BUILD_ROOT/etc
|
||||
@ -382,7 +371,6 @@ rm -rf $RPM_BUILD_ROOT
|
||||
%defattr(644, root, root, 755)
|
||||
%config /etc/pythonstart
|
||||
%config /etc/profile.d/python.*
|
||||
%{_prefix}/share/emacs/site-lisp/*
|
||||
%dir %{_docdir}/%{name}
|
||||
%doc %{_docdir}/%{name}/README
|
||||
%doc %{_docdir}/%{name}/LICENSE
|
||||
@ -473,6 +461,13 @@ rm -rf $RPM_BUILD_ROOT
|
||||
%attr(755, root, root) %{_bindir}/smtpd.py
|
||||
|
||||
%changelog
|
||||
* Fri Jul 27 2007 - jmatejek@suse.cz
|
||||
- removed emacs python-mode and dependency on emacs
|
||||
* Fri Jun 08 2007 - jmatejek@suse.cz
|
||||
- revisited & explained failing tests
|
||||
- applied EINTR recovery patch (#278622)
|
||||
- experimental replacement of shebang strings,
|
||||
removing dependency on /usr/bin/env
|
||||
* Thu May 24 2007 - jmatejek@suse.cz
|
||||
- update to 2.5.1
|
||||
- bugfix only release, over 150 bugs fixed
|
||||
|
@ -1,3 +0,0 @@
|
||||
(autoload 'python-mode "python-mode")
|
||||
(add-to-list 'auto-mode-alist
|
||||
'("\\.py\\'" . python-mode))
|
Loading…
x
Reference in New Issue
Block a user