def _process_output_no_watchers( # pylint: disable=too-many-arguments session: Session, channel: Channel, encoding: str, stdout_stream: StringIO, stderr_stream: StringIO, timeout: NullableTiming, timeout_read_data_chunk: NullableTiming) -> bool: eof_result = stdout_size = stderr_size = LIBSSH2_ERROR_EAGAIN if timeout: end_time = perf_counter() + timeout else: end_time = float_info.max while eof_result == LIBSSH2_ERROR_EAGAIN or stdout_size == LIBSSH2_ERROR_EAGAIN or stdout_size > 0 or \ stderr_size == LIBSSH2_ERROR_EAGAIN or stderr_size > 0: # pylint: disable=consider-using-in if perf_counter() > end_time: return False with session.lock: if stdout_size == LIBSSH2_ERROR_EAGAIN and stderr_size == LIBSSH2_ERROR_EAGAIN: # pylint: disable=consider-using-in session.simple_select(timeout=timeout_read_data_chunk) eof_result = channel.wait_eof() stdout_size, stdout_chunk = channel.read() stderr_size, stderr_chunk = channel.read_stderr() if stdout_chunk and stdout_stream is not None: stdout_stream.write(stdout_chunk.decode(encoding)) if stderr_chunk and stderr_stream is not None: stderr_stream.write(stderr_chunk.decode(encoding)) return True
def _read_output( # pylint: disable=too-many-arguments,too-many-branches self, session: Session, channel: Channel, timeout: NullableTiming, timeout_read_data: NullableTiming, stdout_stream: Queue, stderr_stream: Queue): """Reads data from ssh session, split it into lines and forward lines into stderr ad stdout pipes It is required for it to be fast, that is why there is code duplications and non-pythonic code """ # pylint: disable=too-many-locals stdout_remainder = stderr_remainder = b'' if timeout is None: end_time = float_info.max else: end_time = perf_counter() + timeout eof_result = stdout_size = stderr_size = 1 while eof_result == LIBSSH2_ERROR_EAGAIN or stdout_size == LIBSSH2_ERROR_EAGAIN or \ stdout_size > 0 or stderr_size == LIBSSH2_ERROR_EAGAIN or stderr_size > 0: # pylint: disable=consider-using-in if not self._can_run.is_set(): break if perf_counter() > end_time: self.timeout_reached = True break with session.lock: if stdout_size == LIBSSH2_ERROR_EAGAIN and stderr_size == LIBSSH2_ERROR_EAGAIN: # pylint: disable=consider-using-in session.simple_select(timeout=timeout_read_data) stdout_size, stdout_chunk = channel.read() stderr_size, stderr_chunk = channel.read_stderr() eof_result = channel.eof() if stdout_chunk and stdout_stream is not None: data_splitted = stdout_chunk.split(LINESEP) if len(data_splitted) == 1: stdout_remainder = stdout_remainder + data_splitted.pop() else: if stdout_remainder: stdout_stream.put(stdout_remainder + data_splitted.pop(0)) stdout_remainder = data_splitted.pop() for chunk in data_splitted: stdout_stream.put(chunk) if stderr_chunk and stderr_stream is not None: data_splitted = stderr_chunk.split(LINESEP) if len(data_splitted) == 1: stderr_remainder = stderr_remainder + data_splitted.pop() else: if stderr_remainder: stderr_stream.put(stderr_remainder + data_splitted.pop(0)) stderr_remainder = data_splitted.pop() for chunk in data_splitted: stderr_stream.put(chunk) if stdout_remainder: stdout_stream.put(stdout_remainder) if stderr_remainder: stderr_stream.put(stderr_remainder)