blob: 54543bed0f8d355c72ec37a09b0dbb2ede7b45fd [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()
Guido van Rossum45e2fbc1998-03-26 21:13:24 +000042 p2cread, p2cwrite = os.pipe()
43 c2pread, c2pwrite = os.pipe()
44 if capturestderr:
45 errout, errin = os.pipe()
46 self.pid = os.fork()
47 if self.pid == 0:
48 # Child
Fred Draked75e63a2000-09-28 19:07:53 +000049 os.dup2(p2cread, 0)
50 os.dup2(c2pwrite, 1)
Guido van Rossum45e2fbc1998-03-26 21:13:24 +000051 if capturestderr:
Fred Draked75e63a2000-09-28 19:07:53 +000052 os.dup2(errin, 2)
53 self._run_child(cmd)
Guido van Rossum45e2fbc1998-03-26 21:13:24 +000054 os.close(p2cread)
55 self.tochild = os.fdopen(p2cwrite, 'w', bufsize)
56 os.close(c2pwrite)
57 self.fromchild = os.fdopen(c2pread, 'r', bufsize)
58 if capturestderr:
59 os.close(errin)
60 self.childerr = os.fdopen(errout, 'r', bufsize)
61 else:
62 self.childerr = None
Guido van Rossum45e2fbc1998-03-26 21:13:24 +000063 _active.append(self)
Guido van Rossum54f22ed2000-02-04 15:10:34 +000064
Fred Draked75e63a2000-09-28 19:07:53 +000065 def _run_child(self, cmd):
Walter Dörwald65230a22002-06-03 15:58:32 +000066 if isinstance(cmd, basestring):
Fred Draked75e63a2000-09-28 19:07:53 +000067 cmd = ['/bin/sh', '-c', cmd]
68 for i in range(3, MAXFD):
69 try:
70 os.close(i)
Skip Montanaro1c90d7a2002-03-24 20:48:26 +000071 except OSError:
Fred Draked75e63a2000-09-28 19:07:53 +000072 pass
73 try:
74 os.execvp(cmd[0], cmd)
75 finally:
76 os._exit(1)
77
Guido van Rossum0357d021997-08-11 03:27:24 +000078 def poll(self):
Guido van Rossum54f22ed2000-02-04 15:10:34 +000079 """Return the exit status of the child process if it has finished,
80 or -1 if it hasn't finished yet."""
Guido van Rossum45e2fbc1998-03-26 21:13:24 +000081 if self.sts < 0:
82 try:
83 pid, sts = os.waitpid(self.pid, os.WNOHANG)
84 if pid == self.pid:
85 self.sts = sts
86 _active.remove(self)
87 except os.error:
88 pass
89 return self.sts
Guido van Rossum54f22ed2000-02-04 15:10:34 +000090
Guido van Rossum0357d021997-08-11 03:27:24 +000091 def wait(self):
Guido van Rossum54f22ed2000-02-04 15:10:34 +000092 """Wait for and return the exit status of the child process."""
Guido van Rossum3800ef72003-06-02 19:12:01 +000093 if self.sts < 0:
94 pid, sts = os.waitpid(self.pid, 0)
95 if pid == self.pid:
96 self.sts = sts
97 _active.remove(self)
Guido van Rossum45e2fbc1998-03-26 21:13:24 +000098 return self.sts
Guido van Rossumcaa9f231997-04-21 14:15:55 +000099
Fred Drake31f182e2000-08-28 17:20:05 +0000100
Fred Draked75e63a2000-09-28 19:07:53 +0000101class Popen4(Popen3):
102 childerr = None
103
104 def __init__(self, cmd, bufsize=-1):
105 _cleanup()
106 p2cread, p2cwrite = os.pipe()
107 c2pread, c2pwrite = os.pipe()
108 self.pid = os.fork()
109 if self.pid == 0:
110 # Child
111 os.dup2(p2cread, 0)
112 os.dup2(c2pwrite, 1)
113 os.dup2(c2pwrite, 2)
114 self._run_child(cmd)
115 os.close(p2cread)
116 self.tochild = os.fdopen(p2cwrite, 'w', bufsize)
117 os.close(c2pwrite)
118 self.fromchild = os.fdopen(c2pread, 'r', bufsize)
119 _active.append(self)
120
121
Andrew MacIntyre5cef5712002-02-24 05:32:32 +0000122if sys.platform[:3] == "win" or sys.platform == "os2emx":
Fred Draked75e63a2000-09-28 19:07:53 +0000123 # Some things don't make sense on non-Unix platforms.
Tim Petersd2152182000-10-03 23:07:13 +0000124 del Popen3, Popen4
Fred Draked75e63a2000-09-28 19:07:53 +0000125
126 def popen2(cmd, bufsize=-1, mode='t'):
Johannes Gijsbers9fc97892004-10-11 18:12:20 +0000127 """Execute the shell command 'cmd' in a sub-process. On UNIX, 'cmd' may
128 be a sequence, in which case arguments will be passed directly to the
129 program without shell intervention (as with os.spawnv()). If 'cmd' is a
130 string it will be passed to the shell (as with os.system()). If
131 'bufsize' is specified, it sets the buffer size for the I/O pipes. The
132 file objects (child_stdout, child_stdin) are returned."""
Fredrik Lundh9ac81f62000-07-09 23:35:24 +0000133 w, r = os.popen2(cmd, mode, bufsize)
134 return r, w
Guido van Rossumcaa9f231997-04-21 14:15:55 +0000135
Fred Draked75e63a2000-09-28 19:07:53 +0000136 def popen3(cmd, bufsize=-1, mode='t'):
Johannes Gijsbers9fc97892004-10-11 18:12:20 +0000137 """Execute the shell command 'cmd' in a sub-process. On UNIX, 'cmd' may
138 be a sequence, in which case arguments will be passed directly to the
139 program without shell intervention (as with os.spawnv()). If 'cmd' is a
140 string it will be passed to the shell (as with os.system()). If
141 'bufsize' is specified, it sets the buffer size for the I/O pipes. The
142 file objects (child_stdout, child_stdin, child_stderr) are returned."""
Fredrik Lundh9ac81f62000-07-09 23:35:24 +0000143 w, r, e = os.popen3(cmd, mode, bufsize)
144 return r, w, e
Fredrik Lundhbb7eeff2000-07-09 17:59:32 +0000145
Fred Draked75e63a2000-09-28 19:07:53 +0000146 def popen4(cmd, bufsize=-1, mode='t'):
Johannes Gijsbers9fc97892004-10-11 18:12:20 +0000147 """Execute the shell command 'cmd' in a sub-process. On UNIX, 'cmd' may
148 be a sequence, in which case arguments will be passed directly to the
149 program without shell intervention (as with os.spawnv()). If 'cmd' is a
150 string it will be passed to the shell (as with os.system()). If
151 'bufsize' is specified, it sets the buffer size for the I/O pipes. The
152 file objects (child_stdout_stderr, child_stdin) are returned."""
Fredrik Lundh9ac81f62000-07-09 23:35:24 +0000153 w, r = os.popen4(cmd, mode, bufsize)
154 return r, w
155else:
Fred Draked75e63a2000-09-28 19:07:53 +0000156 def popen2(cmd, bufsize=-1, mode='t'):
Johannes Gijsbers9fc97892004-10-11 18:12:20 +0000157 """Execute the shell command 'cmd' in a sub-process. On UNIX, 'cmd' may
158 be a sequence, in which case arguments will be passed directly to the
159 program without shell intervention (as with os.spawnv()). If 'cmd' is a
160 string it will be passed to the shell (as with os.system()). If
161 'bufsize' is specified, it sets the buffer size for the I/O pipes. The
162 file objects (child_stdout, child_stdin) are returned."""
Fred Drakeb5aa4072003-07-07 21:36:19 +0000163 inst = Popen3(cmd, False, bufsize)
Fred Draked75e63a2000-09-28 19:07:53 +0000164 return inst.fromchild, inst.tochild
165
166 def popen3(cmd, bufsize=-1, mode='t'):
Johannes Gijsbers9fc97892004-10-11 18:12:20 +0000167 """Execute the shell command 'cmd' in a sub-process. On UNIX, 'cmd' may
168 be a sequence, in which case arguments will be passed directly to the
169 program without shell intervention (as with os.spawnv()). If 'cmd' is a
170 string it will be passed to the shell (as with os.system()). If
171 'bufsize' is specified, it sets the buffer size for the I/O pipes. The
172 file objects (child_stdout, child_stdin, child_stderr) are returned."""
Fred Drakeb5aa4072003-07-07 21:36:19 +0000173 inst = Popen3(cmd, True, bufsize)
Fred Draked75e63a2000-09-28 19:07:53 +0000174 return inst.fromchild, inst.tochild, inst.childerr
175
176 def popen4(cmd, bufsize=-1, mode='t'):
Johannes Gijsbers9fc97892004-10-11 18:12:20 +0000177 """Execute the shell command 'cmd' in a sub-process. On UNIX, 'cmd' may
178 be a sequence, in which case arguments will be passed directly to the
179 program without shell intervention (as with os.spawnv()). If 'cmd' is a
180 string it will be passed to the shell (as with os.system()). If
181 'bufsize' is specified, it sets the buffer size for the I/O pipes. The
182 file objects (child_stdout_stderr, child_stdin) are returned."""
Fred Draked75e63a2000-09-28 19:07:53 +0000183 inst = Popen4(cmd, bufsize)
184 return inst.fromchild, inst.tochild
Guido van Rossum0357d021997-08-11 03:27:24 +0000185
Skip Montanaro352674d2001-02-07 23:14:30 +0000186 __all__.extend(["Popen3", "Popen4"])
Tim Peters658cba62001-02-09 20:06:00 +0000187
Guido van Rossum0357d021997-08-11 03:27:24 +0000188def _test():
Tim Peters84f28db2000-08-20 05:57:36 +0000189 cmd = "cat"
Tim Peters36208572000-09-01 20:38:55 +0000190 teststr = "ab cd\n"
Tim Peters84f28db2000-08-20 05:57:36 +0000191 if os.name == "nt":
192 cmd = "more"
Tim Peters36208572000-09-01 20:38:55 +0000193 # "more" doesn't act the same way across Windows flavors,
194 # sometimes adding an extra newline at the start or the
195 # end. So we strip whitespace off both ends for comparison.
196 expected = teststr.strip()
Guido van Rossum0357d021997-08-11 03:27:24 +0000197 print "testing popen2..."
Tim Peters84f28db2000-08-20 05:57:36 +0000198 r, w = popen2(cmd)
Guido van Rossum0357d021997-08-11 03:27:24 +0000199 w.write(teststr)
200 w.close()
Tim Peters36208572000-09-01 20:38:55 +0000201 got = r.read()
202 if got.strip() != expected:
Walter Dörwald70a6b492004-02-12 17:35:32 +0000203 raise ValueError("wrote %r read %r" % (teststr, got))
Guido van Rossum0357d021997-08-11 03:27:24 +0000204 print "testing popen3..."
Fredrik Lundhbb7eeff2000-07-09 17:59:32 +0000205 try:
Tim Peters84f28db2000-08-20 05:57:36 +0000206 r, w, e = popen3([cmd])
Fredrik Lundhbb7eeff2000-07-09 17:59:32 +0000207 except:
Tim Peters84f28db2000-08-20 05:57:36 +0000208 r, w, e = popen3(cmd)
Guido van Rossum0357d021997-08-11 03:27:24 +0000209 w.write(teststr)
210 w.close()
Tim Peters36208572000-09-01 20:38:55 +0000211 got = r.read()
212 if got.strip() != expected:
Walter Dörwald70a6b492004-02-12 17:35:32 +0000213 raise ValueError("wrote %r read %r" % (teststr, got))
Tim Peters36208572000-09-01 20:38:55 +0000214 got = e.read()
215 if got:
Andrew M. Kuchlingbfd7d6a2005-02-10 13:24:50 +0000216 raise ValueError("unexpected %r on stderr" % (got,))
Guido van Rossum068d5721999-04-20 12:27:31 +0000217 for inst in _active[:]:
218 inst.wait()
Tim Peters36208572000-09-01 20:38:55 +0000219 if _active:
220 raise ValueError("_active not empty")
Guido van Rossum0357d021997-08-11 03:27:24 +0000221 print "All OK"
222
223if __name__ == '__main__':
224 _test()