@@ -371,6 +371,7 @@ class pywintypes:
371371 error = IOError
372372else :
373373 import select
374+ _has_poll = hasattr (select , 'poll' )
374375 import errno
375376 import fcntl
376377 import pickle
@@ -383,6 +384,11 @@ class pywintypes:
383384except :
384385 MAXFD = 256
385386
387+ # When select or poll has indicated that the file is writable,
388+ # we can write up to _PIPE_BUF bytes without risk of blocking.
389+ # POSIX defines PIPE_BUF as >= 512.
390+ _PIPE_BUF = getattr (select , 'PIPE_BUF' , 512 )
391+
386392_active = []
387393
388394def _cleanup ():
@@ -1173,19 +1179,103 @@ def wait(self):
11731179
11741180
11751181 def _communicate (self , input ):
1176- read_set = []
1177- write_set = []
1178- stdout = None # Return
1179- stderr = None # Return
1180-
11811182 if self .stdin :
11821183 # Flush stdio buffer. This might block, if the user has
11831184 # been writing to .stdin in an uncontrolled fashion.
11841185 self .stdin .flush ()
1185- if input :
1186- write_set .append (self .stdin )
1187- else :
1186+ if not input :
11881187 self .stdin .close ()
1188+
1189+ if _has_poll :
1190+ stdout , stderr = self ._communicate_with_poll (input )
1191+ else :
1192+ stdout , stderr = self ._communicate_with_select (input )
1193+
1194+ # All data exchanged. Translate lists into strings.
1195+ if stdout is not None :
1196+ stdout = b'' .join (stdout )
1197+ if stderr is not None :
1198+ stderr = b'' .join (stderr )
1199+
1200+ # Translate newlines, if requested.
1201+ # This also turns bytes into strings.
1202+ if self .universal_newlines :
1203+ if stdout is not None :
1204+ stdout = self ._translate_newlines (stdout ,
1205+ self .stdout .encoding )
1206+ if stderr is not None :
1207+ stderr = self ._translate_newlines (stderr ,
1208+ self .stderr .encoding )
1209+
1210+ self .wait ()
1211+ return (stdout , stderr )
1212+
1213+
1214+ def _communicate_with_poll (self , input ):
1215+ stdout = None # Return
1216+ stderr = None # Return
1217+ fd2file = {}
1218+ fd2output = {}
1219+
1220+ poller = select .poll ()
1221+ def register_and_append (file_obj , eventmask ):
1222+ poller .register (file_obj .fileno (), eventmask )
1223+ fd2file [file_obj .fileno ()] = file_obj
1224+
1225+ def close_unregister_and_remove (fd ):
1226+ poller .unregister (fd )
1227+ fd2file [fd ].close ()
1228+ fd2file .pop (fd )
1229+
1230+ if self .stdin and input :
1231+ register_and_append (self .stdin , select .POLLOUT )
1232+
1233+ select_POLLIN_POLLPRI = select .POLLIN | select .POLLPRI
1234+ if self .stdout :
1235+ register_and_append (self .stdout , select_POLLIN_POLLPRI )
1236+ fd2output [self .stdout .fileno ()] = stdout = []
1237+ if self .stderr :
1238+ register_and_append (self .stderr , select_POLLIN_POLLPRI )
1239+ fd2output [self .stderr .fileno ()] = stderr = []
1240+
1241+ input_offset = 0
1242+ while fd2file :
1243+ try :
1244+ ready = poller .poll ()
1245+ except select .error as e :
1246+ if e .args [0 ] == errno .EINTR :
1247+ continue
1248+ raise
1249+
1250+ # XXX Rewrite these to use non-blocking I/O on the
1251+ # file objects; they are no longer using C stdio!
1252+
1253+ for fd , mode in ready :
1254+ if mode & select .POLLOUT :
1255+ chunk = input [input_offset : input_offset + _PIPE_BUF ]
1256+ input_offset += os .write (fd , chunk )
1257+ if input_offset >= len (input ):
1258+ close_unregister_and_remove (fd )
1259+ elif mode & select_POLLIN_POLLPRI :
1260+ data = os .read (fd , 4096 )
1261+ if not data :
1262+ close_unregister_and_remove (fd )
1263+ fd2output [fd ].append (data )
1264+ else :
1265+ # Ignore hang up or errors.
1266+ close_unregister_and_remove (fd )
1267+
1268+ return (stdout , stderr )
1269+
1270+
1271+ def _communicate_with_select (self , input ):
1272+ read_set = []
1273+ write_set = []
1274+ stdout = None # Return
1275+ stderr = None # Return
1276+
1277+ if self .stdin and input :
1278+ write_set .append (self .stdin )
11891279 if self .stdout :
11901280 read_set .append (self .stdout )
11911281 stdout = []
@@ -1206,10 +1296,7 @@ def _communicate(self, input):
12061296 # file objects; they are no longer using C stdio!
12071297
12081298 if self .stdin in wlist :
1209- # When select has indicated that the file is writable,
1210- # we can write up to PIPE_BUF bytes without risk
1211- # blocking. POSIX defines PIPE_BUF >= 512
1212- chunk = input [input_offset : input_offset + 512 ]
1299+ chunk = input [input_offset : input_offset + _PIPE_BUF ]
12131300 bytes_written = os .write (self .stdin .fileno (), chunk )
12141301 input_offset += bytes_written
12151302 if input_offset >= len (input ):
@@ -1230,25 +1317,9 @@ def _communicate(self, input):
12301317 read_set .remove (self .stderr )
12311318 stderr .append (data )
12321319
1233- # All data exchanged. Translate lists into strings.
1234- if stdout is not None :
1235- stdout = b"" .join (stdout )
1236- if stderr is not None :
1237- stderr = b"" .join (stderr )
1238-
1239- # Translate newlines, if requested.
1240- # This also turns bytes into strings.
1241- if self .universal_newlines :
1242- if stdout is not None :
1243- stdout = self ._translate_newlines (stdout ,
1244- self .stdout .encoding )
1245- if stderr is not None :
1246- stderr = self ._translate_newlines (stderr ,
1247- self .stderr .encoding )
1248-
1249- self .wait ()
12501320 return (stdout , stderr )
12511321
1322+
12521323 def send_signal (self , sig ):
12531324 """Send a signal to the process
12541325 """
0 commit comments