components/python/python34/patches/28-pty.patch
author John Beck <John.Beck@Oracle.COM>
Wed, 26 Apr 2017 13:55:01 -0700
changeset 7953 d240e0693286
permissions -rw-r--r--
25954183 Python pty.spawn is getting stuck

This patch comes from upstream: http://bugs.python.org/issue26228
It has not yet been committed, but seems on track to be, and we need
it to fix a bug.

--- Python-3.4.6/Lib/pty.py.~1~	2017-01-16 23:57:41.000000000 +0000
+++ Python-3.4.6/Lib/pty.py	2017-04-26 13:42:05.837992313 +0000
@@ -137,7 +137,7 @@
         if master_fd in rfds:
             data = master_read(master_fd)
             if not data:  # Reached EOF.
-                fds.remove(master_fd)
+                return
             else:
                 os.write(STDOUT_FILENO, data)
         if STDIN_FILENO in rfds:
@@ -153,7 +153,15 @@
         argv = (argv,)
     pid, master_fd = fork()
     if pid == CHILD:
-        os.execlp(argv[0], *argv)
+        try:
+            os.execlp(argv[0], *argv)
+        except:
+            # If we wanted to be really clever, we would use
+            # the same method as subprocess() to pass the error
+            # back to the parent.  For now just dump stack trace.
+            traceback.print_exc()
+        finally:
+            os._exit(1)
     try:
         mode = tty.tcgetattr(STDIN_FILENO)
         tty.setraw(STDIN_FILENO)
@@ -163,6 +171,10 @@
     try:
         _copy(master_fd, master_read, stdin_read)
     except OSError:
+        # Some OSes never return an EOF on pty, just raise
+        # an error instead.
+        pass
+    finally:
         if restore:
             tty.tcsetattr(STDIN_FILENO, tty.TCSAFLUSH, mode)
 
--- Python-3.4.6/Lib/test/test_pty.py.~1~	2017-01-16 23:57:43.000000000 +0000
+++ Python-3.4.6/Lib/test/test_pty.py	2017-04-26 13:42:05.838370945 +0000
@@ -280,7 +280,7 @@
         socketpair[1].close()
         os.close(write_to_stdin_fd)
 
-        # Expect two select calls, the last one will cause IndexError
+        # Expect two select calls, then a normal return on master EOF
         pty.select = self._mock_select
         self.select_rfds_lengths.append(2)
         self.select_rfds_results.append([mock_stdin_fd, masters[0]])
@@ -288,8 +288,7 @@
         # both encountered an EOF before the second select call.
         self.select_rfds_lengths.append(0)
 
-        with self.assertRaises(IndexError):
-            pty._copy(masters[0])
+        pty._copy(masters[0])
 
 
 def test_main(verbose=None):