⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 process.py

📁 wxPython的基本示例程序
💻 PY
📖 第 1 页 / 共 5 页
字号:
    def read(self, nBytes=-1):        # nBytes <= 0 means "read everything"        #   Note that we are changing the "read everything" cue to        #   include 0, because actually doing        #   win32file.ReadFile(<handle>, 0) results in every subsequent        #   read returning 0, i.e. it shuts down the pipe.        if self._descriptor is not None:            if nBytes <= 0:                text, self._lineBuf = self._lineBuf, ""                while 1:                    t = os.read(self._descriptor, 4092)                    if not t:                        break                    else:                        text += t            else:                if len(self._lineBuf) >= nBytes:                    text, self._lineBuf =\                        self._lineBuf[:nBytes], self._lineBuf[nBytes:]                else:                    nBytesToGo = nBytes - len(self._lineBuf)                    text = self._lineBuf + os.read(self._descriptor,                                                   nBytesToGo)                    self._lineBuf = ""            return text        elif self._handle is not None:            if nBytes <= 0:                text, self._lineBuf = self._lineBuf, ""                while 1:                    t = self._win32Read(4092)                    if not t:                        break                    else:                        text += t            else:                if len(self._lineBuf) >= nBytes:                    text, self._lineBuf =\                        self._lineBuf[:nBytes], self._lineBuf[nBytes:]                else:                    nBytesToGo = nBytes - len(self._lineBuf)                    text, self._lineBuf =\                        self._lineBuf + self._win32Read(nBytesToGo), ""            return text        elif self._file is not None:            return self._file.read(nBytes)        else:               raise "FileHandle.read: no handle to read with"    def readline(self):        if self._descriptor is not None or self._handle is not None:            while 1:                #XXX This is not portable to the Mac.                idx = self._lineBuf.find('\n')                if idx != -1:                    line, self._lineBuf =\                        self._lineBuf[:idx+1], self._lineBuf[idx+1:]                    break                else:                    lengthBefore = len(self._lineBuf)                    t = self.read(4092)                    if len(t) <= lengthBefore: # no new data was read                        line, self._lineBuf = self._lineBuf, ""                        break                    else:                        self._lineBuf += t            return line        elif self._file is not None:            return self._file.readline()        else:            raise "FileHandle.readline: no handle to read with"    def readlines(self):        if self._descriptor is not None or self._handle is not None:            lines = []            while 1:                line = self.readline()                if line:                    lines.append(line)                else:                    break            return lines        elif self._file is not None:            return self._file.readlines()        else:            raise "FileHandle.readline: no handle to read with"    def write(self, text):        if self._descriptor is not None:            os.write(self._descriptor, text)        elif self._handle is not None:            try:                errCode, nBytesWritten = win32file.WriteFile(self._handle, text)            except pywintypes.error, ex:                # Ingore errors like "The pipe is being closed.", for                # now.                log.info("[%s] _FileWrapper.write: error writing to pipe, "\                         "ignored", id(self))                return            assert errCode == 0,\                   "Why is 'errCode' from WriteFile non-zero? %r" % errCode            if not nBytesWritten:                # No bytes written signifies that the pipe has been                # closed on the child's end.                log.info("[%s] _FileWrapper.write: observed close of pipe",                         id(self))                return            else:                log.info("[%s] _FileWrapper.write: wrote %d bytes to pipe: %r",                         id(self), len(text), text)        elif self._file is not None:            self._file.write(text)        else:               raise "FileHandle.write: nothing to write with"    def close(self):        """Close all associated file objects and handles."""        log.debug("[%s] _FileWrapper.close()", id(self))        if not self._closed:            self._closed = 1            if self._file is not None:                log.debug("[%s] _FileWrapper.close: close file", id(self))                self._file.close()                log.debug("[%s] _FileWrapper.close: done file close", id(self))            if self._descriptor is not None:                try:                    os.close(self._descriptor)                except OSError, ex:                    if ex.errno == 9:                        # Ignore: OSError: [Errno 9] Bad file descriptor                        # XXX *Should* we be ignoring this? It appears very                        #     *in*frequently in test_wait.py.                        log.debug("[%s] _FileWrapper.close: closing "\                                  "descriptor raised OSError", id(self))                    else:                        raise            if self._handle is not None:                log.debug("[%s] _FileWrapper.close: close handle", id(self))                try:                    win32api.CloseHandle(self._handle)                except win32api.error:                    log.debug("[%s] _FileWrapper.close: closing handle raised",                              id(self))                    pass                log.debug("[%s] _FileWrapper.close: done closing handle",                          id(self))    def __repr__(self):        return "<_FileWrapper: file:%r fd:%r os_handle:%r>"\               % (self._file, self._descriptor, self._handle)class _CountingCloser:    """Call .close() on the given object after own .close() is called    the precribed number of times.    """    def __init__(self, objectsToClose, count):        """        "objectsToClose" is a list of object on which to call .close().        "count" is the number of times this object's .close() method            must be called before .close() is called on the given objects.        """        self.objectsToClose = objectsToClose        self.count = count        if self.count <= 0:            raise ProcessError("illegal 'count' value: %s" % self.count)    def close(self):        self.count -= 1        log.debug("[%d] _CountingCloser.close(): count=%d", id(self),                  self.count)        if self.count == 0:            for objectToClose in self.objectsToClose:                objectToClose.close()#---- public interfaceclass Process:    """Create a process.    One can optionally specify the starting working directory, the    process environment, and std handles to have the child process    inherit (all defaults are the parent's current settings). 'wait' and    'kill' method allow for control of the child's termination.    """    # TODO:    #   - Rename this or merge it with ProcessOpen somehow.    #    if sys.platform.startswith("win"):        # .wait() argument constants        INFINITE = win32event.INFINITE        # .wait() return error codes        WAIT_FAILED = win32event.WAIT_FAILED        WAIT_TIMEOUT = win32event.WAIT_TIMEOUT        # creation "flags" constants        # XXX Should drop these and just document usage of        #     win32process.CREATE_* constants on windows.        CREATE_NEW_CONSOLE = win32process.CREATE_NEW_CONSOLE    else:        # .wait() argument constants        INFINITE = 0        # .wait() return error codes        WAIT_TIMEOUT = 258        WAIT_FAILED = -1        # creation "flags" constants        CREATE_NEW_CONSOLE = 0x10 # same as win32process.CREATE_NEW_CONSOLE    def __init__(self, cmd, cwd=None, env=None, flags=0):        """Create a child process.        "cmd" is a command string or argument vector to spawn.        "cwd" is a working directory in which to start the child process.        "env" is an environment dictionary for the child.        "flags" are system-specific process creation flags. On Windows            this can be a bitwise-OR of any of the win32process.CREATE_*            constants (Note: win32process.CREATE_NEW_PROCESS_GROUP is always            OR'd in). On Unix, this is currently ignored.        """        log.info("Process.__init__(cmd=%r, cwd=%r, env=%r, flags=%r)",                 cmd, cwd, env, flags)        self._cmd = cmd        if not self._cmd:            raise ProcessError("You must specify a command.")        self._cwd = cwd        self._env = env        self._flags = flags        if sys.platform.startswith("win"):            self._flags |= win32process.CREATE_NEW_PROCESS_GROUP        if sys.platform.startswith("win"):            self._startOnWindows()        else:            self.__retvalCache = None            self._startOnUnix()    def _runChildOnUnix(self):        #XXX Errors running the child do *not* get communicated back.        #XXX Perhaps we should *always* prefix with '/bin/sh -c'? There is a        #    disparity btwn how this works on Linux and Windows.        if isinstance(self._cmd, types.StringTypes):            # This is easier than trying to reproduce shell interpretation to            # separate the arguments.            cmd = ['/bin/sh', '-c', self._cmd]        else:            cmd = self._cmd        # Close all file descriptors (except std*) inherited from the parent.        MAXFD = 256 # Max number of file descriptors (os.getdtablesize()???)        for i in range(3, MAXFD):            try:                os.close(i)            except OSError:                pass        try:            if self._env:                os.execvpe(cmd[0], cmd, self._env)            else:                os.execvp(cmd[0], cmd)        finally:            os._exit(1)  # Should never get here.    def _forkAndExecChildOnUnix(self):        """Fork and start the child process.        Sets self._pid as a side effect.        """        pid = os.fork()        if pid == 0: # child            self._runChildOnUnix()        # parent        self._pid = pid    def _startOnUnix(self):        if self._cwd:            oldDir = os.getcwd()            try:                os.chdir(self._cwd)            except OSError, ex:                raise ProcessError(msg=str(ex), errno=ex.errno)        self._forkAndExecChildOnUnix()        # parent        if self._cwd:            os.chdir(oldDir)    def _startOnWindows(self):        if type(self._cmd) in (types.ListType, types.TupleType):            # And arg vector was passed in.            cmd = _joinArgv(self._cmd)        else:            cmd = self._cmd        si = win32process.STARTUPINFO()         si.dwFlags = win32process.STARTF_USESHOWWINDOW        si.wShowWindow = SW_SHOWDEFAULT        if not (self._flags & self.CREATE_NEW_CONSOLE):            #XXX This is hacky.            # We cannot then use _fixupCommand because this will cause a            # shell to be openned as the command is launched. Therefore need            # to ensure be have the full path to the executable to launch.            try:                cmd = _whichFirstArg(cmd, self._env)            except ProcessError:                # Could not find the command, perhaps it is an internal                # shell command -- fallback to _fixupCommand                cmd = _fixupCommand(cmd, self._env)        else:            cmd = _fixupCommand(cmd, self._env)        log.debug("cmd = %r", cmd)        # Start the child process.

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -