changeset 128:42c8f5c152a5

Fixed EINTR fatally breaking poll/wait on Python 2.6- (for real this time)
author Oleg Oshmyan <chortos@inbox.lv>
date Mon, 16 May 2011 21:31:43 +0100
parents f5b8a0c0e3cb
children 580f0f4687c3
files testcases.py unix.py win32.py
diffstat 3 files changed, 26 insertions(+), 19 deletions(-) [+]
line wrap: on
line diff
--- a/testcases.py	Mon May 16 02:53:24 2011 +0100
+++ b/testcases.py	Mon May 16 21:31:43 2011 +0100
@@ -196,9 +196,8 @@
 					terminate(case.process)
 				except Exception:
 					time.sleep(0)
-					case.process.poll()
 				else:
-					case.process.wait()
+					wait(case.process)
 					break
 			else:
 				# If killing the process is unsuccessful three times in a row,
@@ -208,9 +207,8 @@
 						kill(case.process)
 					except Exception:
 						time.sleep(0)
-						case.process.poll()
 					else:
-						case.process.wait()
+						wait(case.process)
 						break
 		if case.files_to_delete:
 			for name in case.files_to_delete:
--- a/unix.py	Mon May 16 02:53:24 2011 +0100
+++ b/unix.py	Mon May 16 21:31:43 2011 +0100
@@ -22,7 +22,7 @@
 	SIGTERM = 15
 	SIGKILL = 9
 
-__all__ = 'call', 'kill', 'terminate', 'pause', 'clock'
+__all__ = 'call', 'kill', 'terminate', 'wait', 'pause', 'clock'
 
 
 if not sys.stdin.isatty():
@@ -186,7 +186,7 @@
 					if case.process.poll() is None:
 						raise testcases.WallTimeLimitExceeded
 				else:
-					case.process.wait()
+					wait(case.process)
 			else:
 				if not case.maxwalltime:
 					try:
@@ -195,7 +195,7 @@
 							if (s[0] == [sys.stdin] and
 							    sys.stdin.read(1) == '\33'):
 								raise testcases.CanceledByUser
-					except (SelectError, IOError):
+					except (SelectError, IOError, OSError):
 						if sys.exc_info()[1].args[0] != EINTR:
 							raise
 						else:
@@ -213,7 +213,7 @@
 									raise testcases.CanceledByUser
 							else:
 								raise testcases.WallTimeLimitExceeded
-					except (SelectError, IOError):
+					except (SelectError, IOError, OSError):
 						if sys.exc_info()[1].args[0] != EINTR:
 							raise
 						else:
@@ -259,14 +259,7 @@
 try:
 	def waitpid_emu(pid, options, _wait4=os.wait4):
 		global last_rusage
-		while True:
-			try:
-				pid, status, last_rusage = _wait4(pid, options)
-			except OSError:
-				if sys.exc_info()[1].errno != EINTR:
-					raise
-			else:
-				break
+		pid, status, last_rusage = _wait4(pid, options)
 		return pid, status
 	_waitpid = os.waitpid
 	os.waitpid = waitpid_emu
@@ -297,4 +290,19 @@
 	try:
 		process.terminate()
 	except AttributeError:
-		os.kill(process.pid, SIGTERM)
\ No newline at end of file
+		os.kill(process.pid, SIGTERM)
+
+
+# subprocess in Python 2.6- is not guarded against EINTR
+try:
+	from errno import EINTR
+except ImportError:
+	wait = Popen.wait
+else:
+	def wait(process):
+		while True:
+			try:
+				return process.wait()
+			except OSError:
+				if sys.exc_info()[1].errno != EINTR:
+					raise
\ No newline at end of file
--- a/win32.py	Mon May 16 02:53:24 2011 +0100
+++ b/win32.py	Mon May 16 21:31:43 2011 +0100
@@ -47,7 +47,7 @@
 else:
 	ProcessTimes = namedtuple('ProcessTimes', 'kernel user')
 
-__all__ = 'call', 'kill', 'terminate', 'pause', 'clock'
+__all__ = 'call', 'kill', 'terminate', 'wait', 'pause', 'clock'
 
 
 from functools import wraps
@@ -545,4 +545,5 @@
 		process.terminate()
 	except AttributeError:
 		TerminateProcess(process._handle, 1)
-terminate = kill
\ No newline at end of file
+terminate = kill
+wait = subprocess.Popen.wait
\ No newline at end of file