Mercurial > ~astiob > upreckon > hgweb
comparison unix.py @ 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 |
comparison
equal
deleted
inserted
replaced
127:f5b8a0c0e3cb | 128:42c8f5c152a5 |
---|---|
20 from signal import SIGTERM, SIGKILL | 20 from signal import SIGTERM, SIGKILL |
21 except ImportError: | 21 except ImportError: |
22 SIGTERM = 15 | 22 SIGTERM = 15 |
23 SIGKILL = 9 | 23 SIGKILL = 9 |
24 | 24 |
25 __all__ = 'call', 'kill', 'terminate', 'pause', 'clock' | 25 __all__ = 'call', 'kill', 'terminate', 'wait', 'pause', 'clock' |
26 | 26 |
27 | 27 |
28 if not sys.stdin.isatty(): | 28 if not sys.stdin.isatty(): |
29 pause = lambda: sys.stdin.read(1) | 29 pause = lambda: sys.stdin.read(1) |
30 catch_escape = False | 30 catch_escape = False |
184 if sys.exc_info()[1].args[0] != EINTR: | 184 if sys.exc_info()[1].args[0] != EINTR: |
185 raise | 185 raise |
186 if case.process.poll() is None: | 186 if case.process.poll() is None: |
187 raise testcases.WallTimeLimitExceeded | 187 raise testcases.WallTimeLimitExceeded |
188 else: | 188 else: |
189 case.process.wait() | 189 wait(case.process) |
190 else: | 190 else: |
191 if not case.maxwalltime: | 191 if not case.maxwalltime: |
192 try: | 192 try: |
193 while case.process.poll() is None: | 193 while case.process.poll() is None: |
194 s = select((sys.stdin, sigchld_pipe_read), (), ()) | 194 s = select((sys.stdin, sigchld_pipe_read), (), ()) |
195 if (s[0] == [sys.stdin] and | 195 if (s[0] == [sys.stdin] and |
196 sys.stdin.read(1) == '\33'): | 196 sys.stdin.read(1) == '\33'): |
197 raise testcases.CanceledByUser | 197 raise testcases.CanceledByUser |
198 except (SelectError, IOError): | 198 except (SelectError, IOError, OSError): |
199 if sys.exc_info()[1].args[0] != EINTR: | 199 if sys.exc_info()[1].args[0] != EINTR: |
200 raise | 200 raise |
201 else: | 201 else: |
202 case.process.poll() | 202 case.process.poll() |
203 else: | 203 else: |
211 if (s[0] == [sys.stdin] and | 211 if (s[0] == [sys.stdin] and |
212 sys.stdin.read(1) == '\33'): | 212 sys.stdin.read(1) == '\33'): |
213 raise testcases.CanceledByUser | 213 raise testcases.CanceledByUser |
214 else: | 214 else: |
215 raise testcases.WallTimeLimitExceeded | 215 raise testcases.WallTimeLimitExceeded |
216 except (SelectError, IOError): | 216 except (SelectError, IOError, OSError): |
217 if sys.exc_info()[1].args[0] != EINTR: | 217 if sys.exc_info()[1].args[0] != EINTR: |
218 raise | 218 raise |
219 else: | 219 else: |
220 case.process.poll() | 220 case.process.poll() |
221 finally: | 221 finally: |
257 # To do this, we not only require os.wait4 to be present but also | 257 # To do this, we not only require os.wait4 to be present but also |
258 # assume things about the implementation of subprocess.Popen. | 258 # assume things about the implementation of subprocess.Popen. |
259 try: | 259 try: |
260 def waitpid_emu(pid, options, _wait4=os.wait4): | 260 def waitpid_emu(pid, options, _wait4=os.wait4): |
261 global last_rusage | 261 global last_rusage |
262 while True: | 262 pid, status, last_rusage = _wait4(pid, options) |
263 try: | |
264 pid, status, last_rusage = _wait4(pid, options) | |
265 except OSError: | |
266 if sys.exc_info()[1].errno != EINTR: | |
267 raise | |
268 else: | |
269 break | |
270 return pid, status | 263 return pid, status |
271 _waitpid = os.waitpid | 264 _waitpid = os.waitpid |
272 os.waitpid = waitpid_emu | 265 os.waitpid = waitpid_emu |
273 try: | 266 try: |
274 defaults = Popen._internal_poll.__func__.__defaults__ | 267 defaults = Popen._internal_poll.__func__.__defaults__ |
296 def terminate(process): | 289 def terminate(process): |
297 try: | 290 try: |
298 process.terminate() | 291 process.terminate() |
299 except AttributeError: | 292 except AttributeError: |
300 os.kill(process.pid, SIGTERM) | 293 os.kill(process.pid, SIGTERM) |
294 | |
295 | |
296 # subprocess in Python 2.6- is not guarded against EINTR | |
297 try: | |
298 from errno import EINTR | |
299 except ImportError: | |
300 wait = Popen.wait | |
301 else: | |
302 def wait(process): | |
303 while True: | |
304 try: | |
305 return process.wait() | |
306 except OSError: | |
307 if sys.exc_info()[1].errno != EINTR: | |
308 raise |