@@ -227,9 +227,7 @@ def resume(self):
227
227
def write (self , data ):
228
228
"""Write str to stdin of the process being run"""
229
229
for line in data .splitlines ():
230
- if not self .write_line (line ):
231
- return False
232
- return True
230
+ self .write_line (line )
233
231
234
232
def write_line (self , line ):
235
233
"""Write line to stdin of the process being run
@@ -244,8 +242,6 @@ def write_line(self, line):
244
242
self .command_process .stdin .flush ()
245
243
except (OSError , IOError ):
246
244
self .kill ()
247
- return False
248
- return True
249
245
250
246
def read_line (self , timeout = 0 ):
251
247
"""Read line from child process
@@ -316,6 +312,7 @@ def is_alive(self):
316
312
sub_result = self .command_process .poll ()
317
313
if sub_result is None :
318
314
return True
315
+ self .child_queue .put (None )
319
316
self ._is_alive = False
320
317
return False
321
318
@@ -324,6 +321,7 @@ def start(self, shell_command):
324
321
if self .is_alive :
325
322
raise SandboxError ("Tried to run command with one in progress." )
326
323
working_directory = self .working_directory
324
+ self .child_queue = Queue ()
327
325
shell_command = shlex .split (shell_command .replace ('\\ ' ,'/' ))
328
326
try :
329
327
self .command_process = subprocess .Popen (shell_command ,
@@ -342,11 +340,12 @@ def start(self, shell_command):
342
340
args = (self .command_process .stderr , self .stderr_queue ))
343
341
stderr_monitor .daemon = True
344
342
stderr_monitor .start ()
343
+ Thread (target = self ._child_writer ).start ()
345
344
346
345
def kill (self ):
347
346
"""Stops the sandbox.
348
347
349
- Stops down the sandbox, cleaning up any spawned processes, threads, and
348
+ Shuts down the sandbox, cleaning up any spawned processes, threads, and
350
349
other resources. The shell command running inside the sandbox may be
351
350
suddenly terminated.
352
351
@@ -357,6 +356,7 @@ def kill(self):
357
356
except OSError :
358
357
pass
359
358
self .command_process .wait ()
359
+ self .child_queue .put (None )
360
360
361
361
def retrieve (self ):
362
362
"""Copy the working directory back out of the sandbox."""
@@ -399,17 +399,25 @@ def resume(self):
399
399
except (ValueError , AttributeError , OSError ):
400
400
pass
401
401
402
+ def _child_writer (self ):
403
+ queue = self .child_queue
404
+ stdin = self .command_process .stdin
405
+ while True :
406
+ ln = queue .get ()
407
+ if ln is None :
408
+ break
409
+ try :
410
+ stdin .write (ln )
411
+ stdin .flush ()
412
+ except (OSError , IOError ):
413
+ self .kill ()
414
+ break
415
+
402
416
def write (self , str ):
403
417
"""Write str to stdin of the process being run"""
404
418
if not self .is_alive :
405
419
return False
406
- try :
407
- self .command_process .stdin .write (str )
408
- self .command_process .stdin .flush ()
409
- except (OSError , IOError ):
410
- self .kill ()
411
- return False
412
- return True
420
+ self .child_queue .put (str )
413
421
414
422
def write_line (self , line ):
415
423
"""Write line to stdin of the process being run
@@ -419,13 +427,7 @@ def write_line(self, line):
419
427
"""
420
428
if not self .is_alive :
421
429
return False
422
- try :
423
- self .command_process .stdin .write (line + "\n " )
424
- self .command_process .stdin .flush ()
425
- except (OSError , IOError ):
426
- self .kill ()
427
- return False
428
- return True
430
+ self .child_queue .put (line + "\n " )
429
431
430
432
def read_line (self , timeout = 0 ):
431
433
"""Read line from child process
@@ -495,10 +497,7 @@ def main():
495
497
print ()
496
498
sandbox .start (" " .join (args ))
497
499
for line in options .send_lines :
498
- if not sandbox .write_line (line ):
499
- print ("Could not send line '%s'" % (line ,), file = sys .stderr )
500
- sandbox .kill ()
501
- sys .exit (1 )
500
+ sandbox .write_line (line )
502
501
print ("sent: " + line )
503
502
time .sleep (options .send_delay )
504
503
while True :
0 commit comments