[34] | 1 | # |
---|
| 2 | # Copyright (c) 2001, 2002, 2003, 2004 Python Software Foundation; All Rights Reserved |
---|
| 3 | # |
---|
| 4 | # PSF LICENSE AGREEMENT FOR PYTHON 2.3 |
---|
| 5 | # ------------------------------------ |
---|
| 6 | # |
---|
| 7 | # 1. This LICENSE AGREEMENT is between the Python Software Foundation |
---|
| 8 | # ("PSF"), and the Individual or Organization ("Licensee") accessing and |
---|
| 9 | # otherwise using Python 2.3 software in source or binary form and its |
---|
| 10 | # associated documentation. |
---|
| 11 | # |
---|
| 12 | # 2. Subject to the terms and conditions of this License Agreement, PSF |
---|
| 13 | # hereby grants Licensee a nonexclusive, royalty-free, world-wide |
---|
| 14 | # license to reproduce, analyze, test, perform and/or display publicly, |
---|
| 15 | # prepare derivative works, distribute, and otherwise use Python 2.3 |
---|
| 16 | # alone or in any derivative version, provided, however, that PSF's |
---|
| 17 | # License Agreement and PSF's notice of copyright, i.e., "Copyright (c) |
---|
| 18 | # 2001, 2002, 2003, 2004 Python Software Foundation; All Rights Reserved" are |
---|
| 19 | # retained in Python 2.3 alone or in any derivative version prepared by |
---|
| 20 | # Licensee. |
---|
| 21 | # |
---|
| 22 | # 3. In the event Licensee prepares a derivative work that is based on |
---|
| 23 | # or incorporates Python 2.3 or any part thereof, and wants to make |
---|
| 24 | # the derivative work available to others as provided herein, then |
---|
| 25 | # Licensee hereby agrees to include in any such work a brief summary of |
---|
| 26 | # the changes made to Python 2.3. |
---|
| 27 | # |
---|
| 28 | # 4. PSF is making Python 2.3 available to Licensee on an "AS IS" |
---|
| 29 | # basis. PSF MAKES NO REPRESENTATIONS OR WARRANTIES, EXPRESS OR |
---|
| 30 | # IMPLIED. BY WAY OF EXAMPLE, BUT NOT LIMITATION, PSF MAKES NO AND |
---|
| 31 | # DISCLAIMS ANY REPRESENTATION OR WARRANTY OF MERCHANTABILITY OR FITNESS |
---|
| 32 | # FOR ANY PARTICULAR PURPOSE OR THAT THE USE OF PYTHON 2.3 WILL NOT |
---|
| 33 | # INFRINGE ANY THIRD PARTY RIGHTS. |
---|
| 34 | # |
---|
| 35 | # 5. PSF SHALL NOT BE LIABLE TO LICENSEE OR ANY OTHER USERS OF PYTHON |
---|
| 36 | # 2.3 FOR ANY INCIDENTAL, SPECIAL, OR CONSEQUENTIAL DAMAGES OR LOSS AS |
---|
| 37 | # A RESULT OF MODIFYING, DISTRIBUTING, OR OTHERWISE USING PYTHON 2.3, |
---|
| 38 | # OR ANY DERIVATIVE THEREOF, EVEN IF ADVISED OF THE POSSIBILITY THEREOF. |
---|
| 39 | # |
---|
| 40 | # 6. This License Agreement will automatically terminate upon a material |
---|
| 41 | # breach of its terms and conditions. |
---|
| 42 | # |
---|
| 43 | # 7. Nothing in this License Agreement shall be deemed to create any |
---|
| 44 | # relationship of agency, partnership, or joint venture between PSF and |
---|
| 45 | # Licensee. This License Agreement does not grant permission to use PSF |
---|
| 46 | # trademarks or trade name in a trademark sense to endorse or promote |
---|
| 47 | # products or services of Licensee, or any third party. |
---|
| 48 | # |
---|
| 49 | # 8. By copying, installing or otherwise using Python 2.3, Licensee |
---|
| 50 | # agrees to be bound by the terms and conditions of this License |
---|
| 51 | # Agreement. |
---|
| 52 | # |
---|
| 53 | # Modifications: Copyright (c) 2005 Christian Limpach <Christian.Limpach@cl.cam.ac.uk> |
---|
| 54 | # - add support for excluding a list of file descriptors from being |
---|
| 55 | # closed, allowing access to those file descriptors from the command. |
---|
| 56 | # |
---|
| 57 | |
---|
| 58 | """Spawn a command with pipes to its stdin, stdout, and optionally stderr. |
---|
| 59 | |
---|
| 60 | The normal os.popen(cmd, mode) call spawns a shell command and provides a |
---|
| 61 | file interface to just the input or output of the process depending on |
---|
| 62 | whether mode is 'r' or 'w'. This module provides the functions xpopen2(cmd) |
---|
| 63 | and xpopen3(cmd) which return two or three pipes to the spawned command. |
---|
| 64 | Optionally exclude a list of file descriptors from being closed, allowing |
---|
| 65 | access to those file descriptors from the command. |
---|
| 66 | """ |
---|
| 67 | |
---|
| 68 | import os |
---|
| 69 | import sys |
---|
| 70 | |
---|
| 71 | try: |
---|
| 72 | MAXFD = os.sysconf('SC_OPEN_MAX') |
---|
| 73 | except (AttributeError, ValueError): |
---|
| 74 | MAXFD = 256 |
---|
| 75 | |
---|
| 76 | _active = [] |
---|
| 77 | |
---|
| 78 | def _cleanup(): |
---|
| 79 | for inst in _active[:]: |
---|
| 80 | inst.poll() |
---|
| 81 | |
---|
| 82 | class xPopen3: |
---|
| 83 | """Class representing a child process. Normally instances are created |
---|
| 84 | by the factory functions popen2() and popen3().""" |
---|
| 85 | |
---|
| 86 | sts = -1 # Child not completed yet |
---|
| 87 | |
---|
| 88 | def __init__(self, cmd, capturestderr=False, bufsize=-1, passfd=()): |
---|
| 89 | """The parameter 'cmd' is the shell command to execute in a |
---|
| 90 | sub-process. The 'capturestderr' flag, if true, specifies that |
---|
| 91 | the object should capture standard error output of the child process. |
---|
| 92 | The default is false. If the 'bufsize' parameter is specified, it |
---|
| 93 | specifies the size of the I/O buffers to/from the child process.""" |
---|
| 94 | _cleanup() |
---|
| 95 | self.passfd = passfd |
---|
| 96 | p2cread, p2cwrite = os.pipe() |
---|
| 97 | c2pread, c2pwrite = os.pipe() |
---|
| 98 | if capturestderr: |
---|
| 99 | errout, errin = os.pipe() |
---|
| 100 | self.pid = os.fork() |
---|
| 101 | if self.pid == 0: |
---|
| 102 | # Child |
---|
| 103 | os.dup2(p2cread, 0) |
---|
| 104 | os.dup2(c2pwrite, 1) |
---|
| 105 | if capturestderr: |
---|
| 106 | os.dup2(errin, 2) |
---|
| 107 | self._run_child(cmd) |
---|
| 108 | os.close(p2cread) |
---|
| 109 | self.tochild = os.fdopen(p2cwrite, 'w', bufsize) |
---|
| 110 | os.close(c2pwrite) |
---|
| 111 | self.fromchild = os.fdopen(c2pread, 'r', bufsize) |
---|
| 112 | if capturestderr: |
---|
| 113 | os.close(errin) |
---|
| 114 | self.childerr = os.fdopen(errout, 'r', bufsize) |
---|
| 115 | else: |
---|
| 116 | self.childerr = None |
---|
| 117 | _active.append(self) |
---|
| 118 | |
---|
| 119 | def _run_child(self, cmd): |
---|
| 120 | if isinstance(cmd, basestring): |
---|
| 121 | cmd = ['/bin/sh', '-c', cmd] |
---|
| 122 | for i in range(3, MAXFD): |
---|
| 123 | if i in self.passfd: |
---|
| 124 | continue |
---|
| 125 | try: |
---|
| 126 | os.close(i) |
---|
| 127 | except OSError: |
---|
| 128 | pass |
---|
| 129 | try: |
---|
| 130 | os.execvp(cmd[0], cmd) |
---|
| 131 | finally: |
---|
| 132 | os._exit(127) |
---|
| 133 | |
---|
| 134 | def poll(self): |
---|
| 135 | """Return the exit status of the child process if it has finished, |
---|
| 136 | or -1 if it hasn't finished yet.""" |
---|
| 137 | if self.sts < 0: |
---|
| 138 | try: |
---|
| 139 | pid, sts = os.waitpid(self.pid, os.WNOHANG) |
---|
| 140 | if pid == self.pid: |
---|
| 141 | self.sts = sts |
---|
| 142 | _active.remove(self) |
---|
| 143 | except os.error: |
---|
| 144 | pass |
---|
| 145 | return self.sts |
---|
| 146 | |
---|
| 147 | def wait(self): |
---|
| 148 | """Wait for and return the exit status of the child process.""" |
---|
| 149 | if self.sts < 0: |
---|
| 150 | pid, sts = os.waitpid(self.pid, 0) |
---|
| 151 | if pid == self.pid: |
---|
| 152 | self.sts = sts |
---|
| 153 | _active.remove(self) |
---|
| 154 | return self.sts |
---|
| 155 | |
---|
| 156 | |
---|
| 157 | def xpopen2(cmd, bufsize=-1, mode='t', passfd=[]): |
---|
| 158 | """Execute the shell command 'cmd' in a sub-process. If 'bufsize' is |
---|
| 159 | specified, it sets the buffer size for the I/O pipes. The file objects |
---|
| 160 | (child_stdout, child_stdin) are returned.""" |
---|
| 161 | inst = xPopen3(cmd, False, bufsize, passfd) |
---|
| 162 | return inst.fromchild, inst.tochild |
---|
| 163 | |
---|
| 164 | def xpopen3(cmd, bufsize=-1, mode='t', passfd=[]): |
---|
| 165 | """Execute the shell command 'cmd' in a sub-process. If 'bufsize' is |
---|
| 166 | specified, it sets the buffer size for the I/O pipes. The file objects |
---|
| 167 | (child_stdout, child_stdin, child_stderr) are returned.""" |
---|
| 168 | inst = xPopen3(cmd, True, bufsize, passfd) |
---|
| 169 | return inst.fromchild, inst.tochild, inst.childerr |
---|