Rewrite using class, to make waiting for processes possible;
by default children are waited for automatically.
diff --git a/Lib/popen2.py b/Lib/popen2.py
index d2867c6..ae89f94 100644
--- a/Lib/popen2.py
+++ b/Lib/popen2.py
@@ -2,49 +2,97 @@
 import sys
 import string
 
-MAXFD = 100	# Max number of file descriptors (os.getdtablesize()???)
+MAXFD = 256	# Max number of file descriptors (os.getdtablesize()???)
 
-def _popen2(cmd, capturestderr=0):
+_active = []
+
+def _cleanup():
+    for inst in _active[:]:
+	inst.poll()
+
+class Popen3:
+    def __init__(self, cmd, capturestderr=0):
 	cmd = ['/bin/sh', '-c', cmd]
 	p2cread, p2cwrite = os.pipe()
 	c2pread, c2pwrite = os.pipe()
 	if capturestderr:
-		errout, errin = os.pipe()
-	pid = os.fork()
-	if pid == 0:
-		# Child
-		os.close(0)
-		os.close(1)
-		if os.dup(p2cread) <> 0:
-			sys.stderr.write('popen2: bad read dup\n')
-		if os.dup(c2pwrite) <> 1:
-			sys.stderr.write('popen2: bad write dup\n')
-		if capturestderr:
-			os.close(2)
-			if os.dup(errin) <> 2: pass
-		for i in range(3, MAXFD):
-			try:
-				os.close(i)
-			except: pass
+	    errout, errin = os.pipe()
+	self.pid = os.fork()
+	if self.pid == 0:
+	    # Child
+	    os.close(0)
+	    os.close(1)
+	    if os.dup(p2cread) <> 0:
+		sys.stderr.write('popen2: bad read dup\n')
+	    if os.dup(c2pwrite) <> 1:
+		sys.stderr.write('popen2: bad write dup\n')
+	    if capturestderr:
+		os.close(2)
+		if os.dup(errin) <> 2: pass
+	    for i in range(3, MAXFD):
 		try:
-			os.execv(cmd[0], cmd)
-		finally:
-			os._exit(1)
-		# Shouldn't come here, I guess
+		    os.close(i)
+		except: pass
+	    try:
+		os.execv(cmd[0], cmd)
+	    finally:
 		os._exit(1)
+	    # Shouldn't come here, I guess
+	    os._exit(1)
 	os.close(p2cread)
-	tochild = os.fdopen(p2cwrite, 'w')
+	self.tochild = os.fdopen(p2cwrite, 'w')
 	os.close(c2pwrite)
-	fromchild = os.fdopen(c2pread, 'r')
+	self.fromchild = os.fdopen(c2pread, 'r')
 	if capturestderr:
-		os.close(errin)
-		childerr = os.fdopen(errout, 'r')
-		return fromchild, tochild, childerr
+	    os.close(errin)
+	    self.childerr = os.fdopen(errout, 'r')
 	else:
-		return fromchild, tochild, None
+	    self.childerr = None
+	self.sts = -1 # Child not completed yet
+	_active.append(self)
+    def poll(self):
+	if self.sts < 0:
+	    try:
+		pid, sts = os.waitpid(self.pid, os.WNOHANG)
+		if pid == self.pid:
+		    self.sts = sts
+		    _active.remove(self)
+	    except os.error:
+		pass
+	return self.sts
+    def wait(self):
+	pid, sts = os.waitpid(self.pid, 0)
+	if pid == self.pid:
+	    self.sts = sts
+	    _active.remove(self)
+	return self.sts
 
 def popen2(cmd):
-	return _popen2(cmd, 0)[:2]
+    _cleanup()
+    inst = Popen3(cmd, 0)
+    return inst.fromchild, inst.tochild
 
 def popen3(cmd):
-	return _popen2(cmd, 1)
+    _cleanup()
+    inst = Popen3(cmd, 1)
+    return inst.fromchild, inst.tochild, inst.childerr
+
+def _test():
+    teststr = "abc\n"
+    print "testing popen2..."
+    r, w = popen2('cat')
+    w.write(teststr)
+    w.close()
+    assert r.read() == teststr
+    print "testing popen3..."
+    r, w, e = popen3('cat')
+    w.write(teststr)
+    w.close()
+    assert r.read() == teststr
+    assert e.read() == ""
+    _cleanup()
+    assert not _active
+    print "All OK"
+
+if __name__ == '__main__':
+    _test()