cinap_lenrekadd hg and python4bb9e2215 years agoHistory
1246 lines · 42.6 KB · Python
RawDownload
            # OSError, 1 means some other error.            errpipe_read, errpipe_write = os.pipe()            self._set_cloexec_flag(errpipe_write)             self.pid = os.fork()            self._child_created = True            if self.pid == 0:                # Child                try:                    # Close parent's pipe ends                    if p2cwrite:                        os.close(p2cwrite)                    if c2pread:                        os.close(c2pread)                    if errread:                        os.close(errread)                    os.close(errpipe_read)                     # Dup fds for child                    if p2cread:                        os.dup2(p2cread, 0)                    if c2pwrite:                        os.dup2(c2pwrite, 1)                    if errwrite:                        os.dup2(errwrite, 2)                     # Close pipe fds.  Make sure we don't close the same                    # fd more than once, or standard fds.                    if p2cread and p2cread not in (0,):                        os.close(p2cread)                    if c2pwrite and c2pwrite not in (p2cread, 1):                        os.close(c2pwrite)                    if errwrite and errwrite not in (p2cread, c2pwrite, 2):                        os.close(errwrite)                     # Close all other fds, if asked for                    if close_fds:                        self._close_fds(but=errpipe_write)                     if cwd is not None:                        os.chdir(cwd)                     if preexec_fn:                        apply(preexec_fn)                     if env is None:                        os.execvp(executable, args)                    else:                        os.execvpe(executable, args, env)                 except:                    exc_type, exc_value, tb = sys.exc_info()                    # Save the traceback and attach it to the exception object                    exc_lines = traceback.format_exception(exc_type,                                                           exc_value,                                                           tb)                    exc_value.child_traceback = ''.join(exc_lines)                    os.write(errpipe_write, pickle.dumps(exc_value))                 # This exitcode won't be reported to applications, so it                # really doesn't matter what we return.                os._exit(255)             # Parent            os.close(errpipe_write)            if p2cread and p2cwrite:                os.close(p2cread)            if c2pwrite and c2pread:                os.close(c2pwrite)            if errwrite and errread:                os.close(errwrite)             # Wait for exec to fail or succeed; possibly raising exception            data = os.read(errpipe_read, 1048576) # Exceptions limited to 1 MB            os.close(errpipe_read)            if data != "":                os.waitpid(self.pid, 0)                child_exception = pickle.loads(data)                raise child_exception          def _handle_exitstatus(self, sts):            if os.WIFSIGNALED(sts):                self.returncode = -os.WTERMSIG(sts)            elif os.WIFEXITED(sts):                self.returncode = os.WEXITSTATUS(sts)            else:                # Should never happen                raise RuntimeError("Unknown child exit status!")          def poll(self, _deadstate=None):            """Check if child process has terminated.  Returns returncode            attribute."""            if self.returncode is None:                try:                    pid, sts = os.waitpid(self.pid, os.WNOHANG)                    if pid == self.pid:                        self._handle_exitstatus(sts)                except os.error:                    if _deadstate is not None:                        self.returncode = _deadstate            return self.returncode          def wait(self):            """Wait for child process to terminate.  Returns returncode            attribute."""            if self.returncode is None:                pid, sts = os.waitpid(self.pid, 0)                self._handle_exitstatus(sts)            return self.returncode          def _communicate(self, input):            read_set = []            write_set = []            stdout = None # Return            stderr = None # Return             if self.stdin:                # Flush stdio buffer.  This might block, if the user has                # been writing to .stdin in an uncontrolled fashion.                self.stdin.flush()                if input:                    write_set.append(self.stdin)                else:                    self.stdin.close()            if self.stdout:                read_set.append(self.stdout)                stdout = []            if self.stderr:                read_set.append(self.stderr)                stderr = []             input_offset = 0            while read_set or write_set:                rlist, wlist, xlist = select.select(read_set, write_set, [])                 if self.stdin in wlist:                    # When select has indicated that the file is writable,                    # we can write up to PIPE_BUF bytes without risk                    # blocking.  POSIX defines PIPE_BUF >= 512                    bytes_written = os.write(self.stdin.fileno(), buffer(input, input_offset, 512))                    input_offset += bytes_written                     if input_offset >= len(input):                        self.stdin.close()                        write_set.remove(self.stdin)                 if self.stdout in rlist:                    data = os.read(self.stdout.fileno(), 1024)                    if data == "":                        self.stdout.close()                        read_set.remove(self.stdout)                    stdout.append(data)                 if self.stderr in rlist:                    data = os.read(self.stderr.fileno(), 1024)                    if data == "":                        self.stderr.close()                        read_set.remove(self.stderr)                    stderr.append(data)             # All data exchanged.  Translate lists into strings.            if stdout is not None:                stdout = ''.join(stdout)            if stderr is not None:                stderr = ''.join(stderr)             # Translate newlines, if requested.  We cannot let the file            # object do the translation: It is based on stdio, which is            # impossible to combine with select (unless forcing no            # buffering).            if self.universal_newlines and hasattr(file, 'newlines'):                if stdout:                    stdout = self._translate_newlines(stdout)                if stderr:                    stderr = self._translate_newlines(stderr)             self.wait()            return (stdout, stderr)  def _demo_posix():    #    # Example 1: Simple redirection: Get process list    #    plist = Popen(["ps"], stdout=PIPE).communicate()[0]    print "Process list:"    print plist     #    # Example 2: Change uid before executing child    #    if os.getuid() == 0:        p = Popen(["id"], preexec_fn=lambda: os.setuid(100))        p.wait()     #    # Example 3: Connecting several subprocesses    #    print "Looking for 'hda'..."    p1 = Popen(["dmesg"], stdout=PIPE)    p2 = Popen(["grep", "hda"], stdin=p1.stdout, stdout=PIPE)    print repr(p2.communicate()[0])     #    # Example 4: Catch execution error    #    print    print "Trying a weird file..."    try:        print Popen(["/this/path/does/not/exist"]).communicate()    except OSError, e:        if e.errno == errno.ENOENT:            print "The file didn't exist.  I thought so..."            print "Child traceback:"            print e.child_traceback        else:            print "Error", e.errno    else:        print >>sys.stderr, "Gosh.  No error."  def _demo_windows():    #    # Example 1: Connecting several subprocesses    #    print "Looking for 'PROMPT' in set output..."    p1 = Popen("set", stdout=PIPE, shell=True)    p2 = Popen('find "PROMPT"', stdin=p1.stdout, stdout=PIPE)    print repr(p2.communicate()[0])     #    # Example 2: Simple execution of program    #    print "Executing calc..."    p = Popen("calc")    p.wait()  if __name__ == "__main__":    if mswindows:        _demo_windows()    else:        _demo_posix()

Lines 1001–1246 of 1246. Previous lines

Keyboard shortcuts

General

Show keyboard shortcuts
?
Focus the current search
/

Issues and pull requests

Open filters
f

Issues, pull requests and Inbox

Select next item
j↓
Select previous item
k↑
Open selected item
Enter
Dismiss filters or clear selection
Esc

Repository code

Go to file
t