Source code for headlessvim.process

#!/usr/bin/env python
# -*- coding:utf-8 -*-

"""
.. note:: This module is not designed to be used by user.
"""

import contextlib
import distutils.spawn
import fcntl
import os
import pty
import select
import subprocess


[docs]class Process(object): """ A class representing a background *Vim* process. """ def __init__(self, executable, args, env): """ :param str executable: command name to execute *Vim* :param args: arguments to execute *Vim* :type args: None or string or list of string :param env: environment variables to execute *Vim* :type env: None or dict of (string, string) """ self._executable = distutils.spawn.find_executable(executable) self._args = args self._env = env self._open_process()
[docs] def terminate(self): """ Terminate this process. Use this method rather than ``self.kill``. """ with self._close(): self._process.terminate()
[docs] def kill(self): """ Kill this process. Use this only when the process seems to be hanging up. """ with self._close(): self._process.kill()
[docs] def check_readable(self, timeout): """ Poll ``self.stdout`` and return True if it is readable. :param float timeout: seconds to wait I/O :return: True if readable, else False :rtype: boolean """ rlist, wlist, xlist = select.select([self._stdout], [], [], timeout) return bool(len(rlist))
[docs] def is_alive(self): """ Check if the process is alive. :return: True if the process is alive, else False :rtype: boolean """ return self._process.poll() is None
@property def executable(self): """ :return: the absolute path to the process. :rtype: strIng """ return self._executable @property def args(self): """ :return: launch arguments of the process. :rtype: string or list of string """ return self._args @property def stdin(self): """ :return: file-like object representing the standard input of the process :rtype: flie-like object """ return self._stdin @property def stdout(self): """ :return: non blocking file-like object representing the standard output of the process :rtype: file-like object """ return self._stdout def _open_process(self): master, slave = pty.openpty() self._process = subprocess.Popen(self._args, executable=self._executable, stdin=slave, stdout=slave, stderr=subprocess.STDOUT, env=self._env) self._open_stream(master) def _open_stream(self, fd): self._make_nonblock(fd) self._stdout = os.fdopen(fd, 'rb') self._stdin = os.fdopen(os.dup(fd), 'wb') def _close_stream(self): if not self._stdout.closed: self._stdout.close() if not self._stdin.closed: self._stdin.close() @contextlib.contextmanager def _close(self): self._close_stream() yield self._process.wait() def _make_nonblock(self, fd): fcntl.fcntl(fd, fcntl.F_SETFL, os.O_NONBLOCK)