/opt/imh-python/lib/python3.9/site-packages/IPython/utils
NameSizeModeActions
tests/-0755rm
__pycache__/-0755rm
capture.py51610644editdlrm
colorable.py7860644editdlrm
coloransi.py69720644editdlrm
contexts.py16190644editdlrm
daemonize.py2000644editdlrm
data.py10150644editdlrm
decorators.py26800644editdlrm
dir2.py22320644editdlrm
docs.py860644editdlrm
encoding.py28430644editdlrm
eventful.py1380644editdlrm
frame.py30480644editdlrm
generics.py7060644editdlrm
importstring.py10500644editdlrm
io.py46310644editdlrm
ipstruct.py118560644editdlrm
jsonutil.py1480644editdlrm
localinterfaces.py1690644editdlrm
log.py1230644editdlrm
module_paths.py23270644editdlrm
openpy.py34170644editdlrm
path.py119370644editdlrm
process.py18780644editdlrm
py3compat.py16020644editdlrm
PyColorize.py108750644editdlrm
sentinel.py4210644editdlrm
shimmodule.py26690644editdlrm
signatures.py4740644editdlrm
strdispatch.py18380644editdlrm
sysinfo.py43650644editdlrm
syspathcontext.py19520644editdlrm
tempdir.py18670644editdlrm
terminal.py32060644editdlrm
text.py244280644editdlrm
timing.py42750644editdlrm
tokenutil.py50830644editdlrm
traitlets.py1430644editdlrm
tz.py13800644editdlrm
ulinecache.py6840644editdlrm
version.py12230644editdlrm
wildcard.py46120644editdlrm
_process_cli.py20200644editdlrm
_process_common.py70030644editdlrm
_process_posix.py86660644editdlrm
_process_win32.py61320644editdlrm
_process_win32_controller.py213290644editdlrm
_sysinfo.py450644editdlrm
__init__.py00644editdlrm
Edit: /opt/imh-python/lib/python3.9/site-packages/IPython/utils/_process_posix.py (8666B)
"""Posix-specific implementation of process utilities. This file is only meant to be imported by process.py, not by end-users. """ #----------------------------------------------------------------------------- # Copyright (C) 2010-2011 The IPython Development Team # # Distributed under the terms of the BSD License. The full license is in # the file COPYING, distributed as part of this software. #----------------------------------------------------------------------------- #----------------------------------------------------------------------------- # Imports #----------------------------------------------------------------------------- # Stdlib import errno import os import subprocess as sp import sys import pexpect # Our own from ._process_common import getoutput, arg_split from IPython.utils.encoding import DEFAULT_ENCODING #----------------------------------------------------------------------------- # Function definitions #----------------------------------------------------------------------------- class ProcessHandler(object): """Execute subprocesses under the control of pexpect. """ # Timeout in seconds to wait on each reading of the subprocess' output. # This should not be set too low to avoid cpu overusage from our side, # since we read in a loop whose period is controlled by this timeout. read_timeout = 0.05 # Timeout to give a process if we receive SIGINT, between sending the # SIGINT to the process and forcefully terminating it. terminate_timeout = 0.2 # File object where stdout and stderr of the subprocess will be written logfile = None # Shell to call for subprocesses to execute _sh = None @property def sh(self): if self._sh is None: shell_name = os.environ.get("SHELL", "sh") self._sh = pexpect.which(shell_name) if self._sh is None: raise OSError('"{}" shell not found'.format(shell_name)) return self._sh def __init__(self, logfile=None, read_timeout=None, terminate_timeout=None): """Arguments are used for pexpect calls.""" self.read_timeout = (ProcessHandler.read_timeout if read_timeout is None else read_timeout) self.terminate_timeout = (ProcessHandler.terminate_timeout if terminate_timeout is None else terminate_timeout) self.logfile = sys.stdout if logfile is None else logfile def getoutput(self, cmd): """Run a command and return its stdout/stderr as a string. Parameters ---------- cmd : str A command to be executed in the system shell. Returns ------- output : str A string containing the combination of stdout and stderr from the subprocess, in whatever order the subprocess originally wrote to its file descriptors (so the order of the information in this string is the correct order as would be seen if running the command in a terminal). """ try: return pexpect.run(self.sh, args=['-c', cmd]).replace('\r\n', '\n') except KeyboardInterrupt: print('^C', file=sys.stderr, end='') def getoutput_pexpect(self, cmd): """Run a command and return its stdout/stderr as a string. Parameters ---------- cmd : str A command to be executed in the system shell. Returns ------- output : str A string containing the combination of stdout and stderr from the subprocess, in whatever order the subprocess originally wrote to its file descriptors (so the order of the information in this string is the correct order as would be seen if running the command in a terminal). """ try: return pexpect.run(self.sh, args=['-c', cmd]).replace('\r\n', '\n') except KeyboardInterrupt: print('^C', file=sys.stderr, end='') def system(self, cmd): """Execute a command in a subshell. Parameters ---------- cmd : str A command to be executed in the system shell. Returns ------- int : child's exitstatus """ # Get likely encoding for the output. enc = DEFAULT_ENCODING # Patterns to match on the output, for pexpect. We read input and # allow either a short timeout or EOF patterns = [pexpect.TIMEOUT, pexpect.EOF] # the index of the EOF pattern in the list. # even though we know it's 1, this call means we don't have to worry if # we change the above list, and forget to change this value: EOF_index = patterns.index(pexpect.EOF) # The size of the output stored so far in the process output buffer. # Since pexpect only appends to this buffer, each time we print we # record how far we've printed, so that next time we only print *new* # content from the buffer. out_size = 0 try: # Since we're not really searching the buffer for text patterns, we # can set pexpect's search window to be tiny and it won't matter. # We only search for the 'patterns' timeout or EOF, which aren't in # the text itself. #child = pexpect.spawn(pcmd, searchwindowsize=1) if hasattr(pexpect, 'spawnb'): child = pexpect.spawnb(self.sh, args=['-c', cmd]) # Pexpect-U else: child = pexpect.spawn(self.sh, args=['-c', cmd]) # Vanilla Pexpect flush = sys.stdout.flush while True: # res is the index of the pattern that caused the match, so we # know whether we've finished (if we matched EOF) or not res_idx = child.expect_list(patterns, self.read_timeout) print(child.before[out_size:].decode(enc, 'replace'), end='') flush() if res_idx==EOF_index: break # Update the pointer to what we've already printed out_size = len(child.before) except KeyboardInterrupt: # We need to send ^C to the process. The ascii code for '^C' is 3 # (the character is known as ETX for 'End of Text', see # curses.ascii.ETX). child.sendline(chr(3)) # Read and print any more output the program might produce on its # way out. try: out_size = len(child.before) child.expect_list(patterns, self.terminate_timeout) print(child.before[out_size:].decode(enc, 'replace'), end='') sys.stdout.flush() except KeyboardInterrupt: # Impatient users tend to type it multiple times pass finally: # Ensure the subprocess really is terminated child.terminate(force=True) # add isalive check, to ensure exitstatus is set: child.isalive() # We follow the subprocess pattern, returning either the exit status # as a positive number, or the terminating signal as a negative # number. # on Linux, sh returns 128+n for signals terminating child processes on Linux # on BSD (OS X), the signal code is set instead if child.exitstatus is None: # on WIFSIGNALED, pexpect sets signalstatus, leaving exitstatus=None if child.signalstatus is None: # this condition may never occur, # but let's be certain we always return an integer. return 0 return -child.signalstatus if child.exitstatus > 128: return -(child.exitstatus - 128) return child.exitstatus # Make system() with a functional interface for outside use. Note that we use # getoutput() from the _common utils, which is built on top of popen(). Using # pexpect to get subprocess output produces difficult to parse output, since # programs think they are talking to a tty and produce highly formatted output # (ls is a good example) that makes them hard. system = ProcessHandler().system def check_pid(pid): try: os.kill(pid, 0) except OSError as err: if err.errno == errno.ESRCH: return False elif err.errno == errno.EPERM: # Don't have permission to signal the process - probably means it exists return True raise else: return True