303 | 303 |
command,
|
304 | 304 |
*,
|
305 | 305 |
timeout: Optional[float] = None,
|
306 | |
debug=None,
|
307 | 306 |
stdin: Optional[bytes] = None,
|
308 | 307 |
print_stdout: bool = True,
|
309 | 308 |
print_stderr: bool = True,
|
|
323 | 322 |
|
324 | 323 |
:param array command: Command line to be run, specified as array.
|
325 | 324 |
:param timeout: Terminate program execution after this many seconds.
|
326 | |
:param boolean debug: Enable further debug messages. (deprecated)
|
327 | 325 |
:param stdin: Optional bytestring that is passed to command stdin.
|
328 | 326 |
:param boolean print_stdout: Pass stdout through to sys.stdout.
|
329 | 327 |
:param boolean print_stderr: Pass stderr through to sys.stderr.
|
|
356 | 354 |
else:
|
357 | 355 |
assert sys.platform != "win32", "stdin argument not supported on Windows"
|
358 | 356 |
stdin_pipe = subprocess.PIPE
|
359 | |
if debug is not None:
|
360 | |
warnings.warn(
|
361 | |
"Use of the debug parameter is deprecated", DeprecationWarning, stacklevel=3
|
362 | |
)
|
363 | 357 |
|
364 | 358 |
start_time = timeit.default_timer()
|
365 | 359 |
if timeout is not None:
|
|
405 | 399 |
stdout = _NonBlockingStreamReader(
|
406 | 400 |
p.stdout,
|
407 | 401 |
output=print_stdout,
|
408 | |
debug=debug,
|
409 | 402 |
notify=notifier.close,
|
410 | 403 |
callback=callback_stdout,
|
411 | 404 |
)
|
|
414 | 407 |
stderr = _NonBlockingStreamReader(
|
415 | 408 |
p.stderr,
|
416 | 409 |
output=print_stderr,
|
417 | |
debug=debug,
|
418 | 410 |
notify=notifier.close,
|
419 | 411 |
callback=callback_stderr,
|
420 | 412 |
)
|
421 | 413 |
if stdin is not None:
|
422 | 414 |
notifyee, notifier = Pipe(False)
|
423 | 415 |
thread_pipe_pool.append(notifyee)
|
424 | |
_NonBlockingStreamWriter(
|
425 | |
p.stdin, data=stdin, debug=debug, notify=notifier.close
|
426 | |
)
|
|
416 |
_NonBlockingStreamWriter(p.stdin, data=stdin, notify=notifier.close)
|
427 | 417 |
|
428 | 418 |
timeout_encountered = False
|
429 | 419 |
|
430 | 420 |
while (p.returncode is None) and (
|
431 | 421 |
(timeout is None) or (timeit.default_timer() < max_time)
|
432 | 422 |
):
|
433 | |
if debug and timeout is not None:
|
434 | |
logger.debug("still running (T%.2fs)", timeit.default_timer() - max_time)
|
435 | |
|
436 | 423 |
# wait for some time or until a stream is closed
|
437 | 424 |
try:
|
438 | 425 |
if thread_pipe_pool:
|
|
449 | 436 |
if event:
|
450 | 437 |
# One-shot, so remove stream and watch remaining streams
|
451 | 438 |
thread_pipe_pool.pop(0)
|
452 | |
if debug:
|
453 | |
logger.debug("Event received from stream thread")
|
454 | 439 |
else:
|
455 | 440 |
time.sleep(0.5)
|
456 | 441 |
except KeyboardInterrupt:
|
|
464 | 449 |
if p.returncode is None:
|
465 | 450 |
# timeout condition
|
466 | 451 |
timeout_encountered = True
|
467 | |
if debug:
|
468 | |
logger.debug("timeout (T%.2fs)", timeit.default_timer() - max_time)
|
|
452 |
logger.debug("timeout (T%.2fs)", timeit.default_timer() - max_time)
|
469 | 453 |
|
470 | 454 |
# send terminate signal and wait some time for buffers to be read
|
471 | 455 |
p.terminate()
|