blob: a4eda3923d653f599882d051914ab83908d7c274 [file] [log] [blame]
Guido van Rossum54f22ed2000-02-04 15:10:34 +00001"""Spawn a command with pipes to its stdin, stdout, and optionally stderr.
2
3The normal os.popen(cmd, mode) call spawns a shell command and provides a
4file interface to just the input or output of the process depending on
5whether mode is 'r' or 'w'. This module provides the functions popen2(cmd)
6and popen3(cmd) which return two or three pipes to the spawned command.
7"""
8
Guido van Rossum9a22de11995-01-12 12:29:47 +00009import os
10import sys
Guido van Rossum9a22de11995-01-12 12:29:47 +000011
Skip Montanaro57fd45e2002-03-12 19:48:03 +000012__all__ = ["popen2", "popen3", "popen4"]
Skip Montanaro352674d2001-02-07 23:14:30 +000013
Martin v. Löwisf563c8b2003-10-06 21:34:33 +000014try:
15 MAXFD = os.sysconf('SC_OPEN_MAX')
16except (AttributeError, ValueError):
17 MAXFD = 256
Guido van Rossum9a22de11995-01-12 12:29:47 +000018
Guido van Rossum0357d021997-08-11 03:27:24 +000019_active = []
20
21def _cleanup():
22 for inst in _active[:]:
Guido van Rossum45e2fbc1998-03-26 21:13:24 +000023 inst.poll()
Guido van Rossum0357d021997-08-11 03:27:24 +000024
25class Popen3:
Guido van Rossum54f22ed2000-02-04 15:10:34 +000026 """Class representing a child process. Normally instances are created
27 by the factory functions popen2() and popen3()."""
28
Fred Draked75e63a2000-09-28 19:07:53 +000029 sts = -1 # Child not completed yet
30
Fred Drakeb5aa4072003-07-07 21:36:19 +000031 def __init__(self, cmd, capturestderr=False, bufsize=-1):
Guido van Rossum54f22ed2000-02-04 15:10:34 +000032 """The parameter 'cmd' is the shell command to execute in a
Johannes Gijsbers9fc97892004-10-11 18:12:20 +000033 sub-process. On UNIX, 'cmd' may be a sequence, in which case arguments
34 will be passed directly to the program without shell intervention (as
35 with os.spawnv()). If 'cmd' is a string it will be passed to the shell
36 (as with os.system()). The 'capturestderr' flag, if true, specifies
37 that the object should capture standard error output of the child
38 process. The default is false. If the 'bufsize' parameter is
39 specified, it specifies the size of the I/O buffers to/from the child
40 process."""
Fred Draked75e63a2000-09-28 19:07:53 +000041 _cleanup()
Martin v. Löwisbd8dbab2006-03-23 18:18:35 +000042 self.cmd = cmd
Guido van Rossum45e2fbc1998-03-26 21:13:24 +000043 p2cread, p2cwrite = os.pipe()
44 c2pread, c2pwrite = os.pipe()
45 if capturestderr:
46 errout, errin = os.pipe()
47 self.pid = os.fork()
48 if self.pid == 0:
49 # Child
Fred Draked75e63a2000-09-28 19:07:53 +000050 os.dup2(p2cread, 0)
51 os.dup2(c2pwrite, 1)
Guido van Rossum45e2fbc1998-03-26 21:13:24 +000052 if capturestderr:
Fred Draked75e63a2000-09-28 19:07:53 +000053 os.dup2(errin, 2)
54 self._run_child(cmd)
Guido van Rossum45e2fbc1998-03-26 21:13:24 +000055 os.close(p2cread)
56 self.tochild = os.fdopen(p2cwrite, 'w', bufsize)
57 os.close(c2pwrite)
58 self.fromchild = os.fdopen(c2pread, 'r', bufsize)
59 if capturestderr:
60 os.close(errin)
61 self.childerr = os.fdopen(errout, 'r', bufsize)
62 else:
63 self.childerr = None
Guido van Rossum45e2fbc1998-03-26 21:13:24 +000064 _active.append(self)
Guido van Rossum54f22ed2000-02-04 15:10:34 +000065
Fred Draked75e63a2000-09-28 19:07:53 +000066 def _run_child(self, cmd):
Walter Dörwald65230a22002-06-03 15:58:32 +000067 if isinstance(cmd, basestring):
Fred Draked75e63a2000-09-28 19:07:53 +000068 cmd = ['/bin/sh', '-c', cmd]
69 for i in range(3, MAXFD):
70 try:
71 os.close(i)
Skip Montanaro1c90d7a2002-03-24 20:48:26 +000072 except OSError:
Fred Draked75e63a2000-09-28 19:07:53 +000073 pass
74 try:
75 os.execvp(cmd[0], cmd)
76 finally:
77 os._exit(1)
78
Guido van Rossum0357d021997-08-11 03:27:24 +000079 def poll(self):
Guido van Rossum54f22ed2000-02-04 15:10:34 +000080 """Return the exit status of the child process if it has finished,
81 or -1 if it hasn't finished yet."""
Guido van Rossum45e2fbc1998-03-26 21:13:24 +000082 if self.sts < 0:
83 try:
84 pid, sts = os.waitpid(self.pid, os.WNOHANG)
85 if pid == self.pid:
86 self.sts = sts
87 _active.remove(self)
88 except os.error:
89 pass
90 return self.sts
Guido van Rossum54f22ed2000-02-04 15:10:34 +000091
Guido van Rossum0357d021997-08-11 03:27:24 +000092 def wait(self):
Guido van Rossum54f22ed2000-02-04 15:10:34 +000093 """Wait for and return the exit status of the child process."""
Guido van Rossum3800ef72003-06-02 19:12:01 +000094 if self.sts < 0:
95 pid, sts = os.waitpid(self.pid, 0)
96 if pid == self.pid:
97 self.sts = sts
98 _active.remove(self)
Guido van Rossum45e2fbc1998-03-26 21:13:24 +000099 return self.sts
Guido van Rossumcaa9f231997-04-21 14:15:55 +0000100
Fred Drake31f182e2000-08-28 17:20:05 +0000101
Fred Draked75e63a2000-09-28 19:07:53 +0000102class Popen4(Popen3):
103 childerr = None
104
105 def __init__(self, cmd, bufsize=-1):
106 _cleanup()
107 p2cread, p2cwrite = os.pipe()
108 c2pread, c2pwrite = os.pipe()
109 self.pid = os.fork()
110 if self.pid == 0:
111 # Child
112 os.dup2(p2cread, 0)
113 os.dup2(c2pwrite, 1)
114 os.dup2(c2pwrite, 2)
115 self._run_child(cmd)
116 os.close(p2cread)
117 self.tochild = os.fdopen(p2cwrite, 'w', bufsize)
118 os.close(c2pwrite)
119 self.fromchild = os.fdopen(c2pread, 'r', bufsize)
120 _active.append(self)
121
122
Andrew MacIntyre5cef5712002-02-24 05:32:32 +0000123if sys.platform[:3] == "win" or sys.platform == "os2emx":
Fred Draked75e63a2000-09-28 19:07:53 +0000124 # Some things don't make sense on non-Unix platforms.
Tim Petersd2152182000-10-03 23:07:13 +0000125 del Popen3, Popen4
Fred Draked75e63a2000-09-28 19:07:53 +0000126
127 def popen2(cmd, bufsize=-1, mode='t'):
Johannes Gijsbers9fc97892004-10-11 18:12:20 +0000128 """Execute the shell command 'cmd' in a sub-process. On UNIX, 'cmd' may
129 be a sequence, in which case arguments will be passed directly to the
130 program without shell intervention (as with os.spawnv()). If 'cmd' is a
131 string it will be passed to the shell (as with os.system()). If
132 'bufsize' is specified, it sets the buffer size for the I/O pipes. The
133 file objects (child_stdout, child_stdin) are returned."""
Fredrik Lundh9ac81f62000-07-09 23:35:24 +0000134 w, r = os.popen2(cmd, mode, bufsize)
135 return r, w
Guido van Rossumcaa9f231997-04-21 14:15:55 +0000136
Fred Draked75e63a2000-09-28 19:07:53 +0000137 def popen3(cmd, bufsize=-1, mode='t'):
Johannes Gijsbers9fc97892004-10-11 18:12:20 +0000138 """Execute the shell command 'cmd' in a sub-process. On UNIX, 'cmd' may
139 be a sequence, in which case arguments will be passed directly to the
140 program without shell intervention (as with os.spawnv()). If 'cmd' is a
141 string it will be passed to the shell (as with os.system()). If
142 'bufsize' is specified, it sets the buffer size for the I/O pipes. The
143 file objects (child_stdout, child_stdin, child_stderr) are returned."""
Fredrik Lundh9ac81f62000-07-09 23:35:24 +0000144 w, r, e = os.popen3(cmd, mode, bufsize)
145 return r, w, e
Fredrik Lundhbb7eeff2000-07-09 17:59:32 +0000146
Fred Draked75e63a2000-09-28 19:07:53 +0000147 def popen4(cmd, bufsize=-1, mode='t'):
Johannes Gijsbers9fc97892004-10-11 18:12:20 +0000148 """Execute the shell command 'cmd' in a sub-process. On UNIX, 'cmd' may
149 be a sequence, in which case arguments will be passed directly to the
150 program without shell intervention (as with os.spawnv()). If 'cmd' is a
151 string it will be passed to the shell (as with os.system()). If
152 'bufsize' is specified, it sets the buffer size for the I/O pipes. The
153 file objects (child_stdout_stderr, child_stdin) are returned."""
Fredrik Lundh9ac81f62000-07-09 23:35:24 +0000154 w, r = os.popen4(cmd, mode, bufsize)
155 return r, w
156else:
Fred Draked75e63a2000-09-28 19:07:53 +0000157 def popen2(cmd, bufsize=-1, mode='t'):
Johannes Gijsbers9fc97892004-10-11 18:12:20 +0000158 """Execute the shell command 'cmd' in a sub-process. On UNIX, 'cmd' may
159 be a sequence, in which case arguments will be passed directly to the
160 program without shell intervention (as with os.spawnv()). If 'cmd' is a
161 string it will be passed to the shell (as with os.system()). If
162 'bufsize' is specified, it sets the buffer size for the I/O pipes. The
163 file objects (child_stdout, child_stdin) are returned."""
Fred Drakeb5aa4072003-07-07 21:36:19 +0000164 inst = Popen3(cmd, False, bufsize)
Fred Draked75e63a2000-09-28 19:07:53 +0000165 return inst.fromchild, inst.tochild
166
167 def popen3(cmd, bufsize=-1, mode='t'):
Johannes Gijsbers9fc97892004-10-11 18:12:20 +0000168 """Execute the shell command 'cmd' in a sub-process. On UNIX, 'cmd' may
169 be a sequence, in which case arguments will be passed directly to the
170 program without shell intervention (as with os.spawnv()). If 'cmd' is a
171 string it will be passed to the shell (as with os.system()). If
172 'bufsize' is specified, it sets the buffer size for the I/O pipes. The
173 file objects (child_stdout, child_stdin, child_stderr) are returned."""
Fred Drakeb5aa4072003-07-07 21:36:19 +0000174 inst = Popen3(cmd, True, bufsize)
Fred Draked75e63a2000-09-28 19:07:53 +0000175 return inst.fromchild, inst.tochild, inst.childerr
176
177 def popen4(cmd, bufsize=-1, mode='t'):
Johannes Gijsbers9fc97892004-10-11 18:12:20 +0000178 """Execute the shell command 'cmd' in a sub-process. On UNIX, 'cmd' may
179 be a sequence, in which case arguments will be passed directly to the
180 program without shell intervention (as with os.spawnv()). If 'cmd' is a
181 string it will be passed to the shell (as with os.system()). If
182 'bufsize' is specified, it sets the buffer size for the I/O pipes. The
183 file objects (child_stdout_stderr, child_stdin) are returned."""
Fred Draked75e63a2000-09-28 19:07:53 +0000184 inst = Popen4(cmd, bufsize)
185 return inst.fromchild, inst.tochild
Guido van Rossum0357d021997-08-11 03:27:24 +0000186
Skip Montanaro352674d2001-02-07 23:14:30 +0000187 __all__.extend(["Popen3", "Popen4"])
Tim Peters658cba62001-02-09 20:06:00 +0000188
Guido van Rossum0357d021997-08-11 03:27:24 +0000189def _test():
Martin v. Löwisbd8dbab2006-03-23 18:18:35 +0000190 # When the test runs, there shouldn't be any open pipes
191 _cleanup()
192 assert not _active, "Active pipes when test starts " + repr([c.cmd for c in _active])
Tim Peters84f28db2000-08-20 05:57:36 +0000193 cmd = "cat"
Tim Peters36208572000-09-01 20:38:55 +0000194 teststr = "ab cd\n"
Tim Peters84f28db2000-08-20 05:57:36 +0000195 if os.name == "nt":
196 cmd = "more"
Tim Peters36208572000-09-01 20:38:55 +0000197 # "more" doesn't act the same way across Windows flavors,
198 # sometimes adding an extra newline at the start or the
199 # end. So we strip whitespace off both ends for comparison.
200 expected = teststr.strip()
Guido van Rossum0357d021997-08-11 03:27:24 +0000201 print "testing popen2..."
Tim Peters84f28db2000-08-20 05:57:36 +0000202 r, w = popen2(cmd)
Guido van Rossum0357d021997-08-11 03:27:24 +0000203 w.write(teststr)
204 w.close()
Tim Peters36208572000-09-01 20:38:55 +0000205 got = r.read()
206 if got.strip() != expected:
Walter Dörwald70a6b492004-02-12 17:35:32 +0000207 raise ValueError("wrote %r read %r" % (teststr, got))
Guido van Rossum0357d021997-08-11 03:27:24 +0000208 print "testing popen3..."
Fredrik Lundhbb7eeff2000-07-09 17:59:32 +0000209 try:
Tim Peters84f28db2000-08-20 05:57:36 +0000210 r, w, e = popen3([cmd])
Fredrik Lundhbb7eeff2000-07-09 17:59:32 +0000211 except:
Tim Peters84f28db2000-08-20 05:57:36 +0000212 r, w, e = popen3(cmd)
Guido van Rossum0357d021997-08-11 03:27:24 +0000213 w.write(teststr)
214 w.close()
Tim Peters36208572000-09-01 20:38:55 +0000215 got = r.read()
216 if got.strip() != expected:
Walter Dörwald70a6b492004-02-12 17:35:32 +0000217 raise ValueError("wrote %r read %r" % (teststr, got))
Tim Peters36208572000-09-01 20:38:55 +0000218 got = e.read()
219 if got:
Andrew M. Kuchlingbfd7d6a2005-02-10 13:24:50 +0000220 raise ValueError("unexpected %r on stderr" % (got,))
Guido van Rossum068d5721999-04-20 12:27:31 +0000221 for inst in _active[:]:
222 inst.wait()
Tim Peters36208572000-09-01 20:38:55 +0000223 if _active:
224 raise ValueError("_active not empty")
Guido van Rossum0357d021997-08-11 03:27:24 +0000225 print "All OK"
226
227if __name__ == '__main__':
228 _test()