diff --git a/pcl_expect.py b/pcl_expect.py
index e53afb36999153533963536500fbf3cdfaf301ce..1578d37cb318be07a2c475890e7ab09f77f54d4b 100644
--- a/pcl_expect.py
+++ b/pcl_expect.py
@@ -1,4 +1,6 @@
+import fcntl
 import os
+import pty
 import re
 import select
 import sets
@@ -17,6 +19,14 @@ timeout = 10.0
 # Default is to raise an exception.
 timeout_raises_exception = True
 
+# When a new pty is created by spawn(), the terminal settings will be
+# inherited from the settings of stdin of the current process.
+# Setting inherit_stty to False will disable this inheritance.  After
+# the inheritance (if any), if stty_init is set to a string, stty will
+# be run with that string as its argument.
+inherit_stty = True
+stty_init = None
+
 #
 # Internal code
 #
@@ -66,6 +76,52 @@ class popen(expectable):
     def close(self):
         return self.__cmd.close()
 
+def set_cloexec_flag(fd):
+    old = fcntl.fcntl(fd, fcntl.F_GETFD)
+    fcntl.fcntl(fd, fcntl.F_SETFD, old | fcntl.FD_CLOEXEC)
+
+class spawn(expectable):
+    def __init__(self, cmd):
+        if inherit_stty:
+            f = os.popen("stty -g")
+            settings = f.read()
+            f.close()
+
+        if isinstance(cmd, types.StringTypes):
+            cmd = cmd.split(" ")
+        (r, w) = os.pipe()
+        set_cloexec_flag(w)
+        self.__child, self.__pty = pty.fork()
+        if self.__child == 0:
+            try:
+                os.close(r)
+                if inherit_stty:
+                    os.system("stty %s" % settings)
+                if stty_init is not None:
+                    os.system("stty %s" % stty_init)
+                try:
+                    os.execvp(cmd[0], cmd)
+                except OSError:
+                    os.write(w, "exec failed\n")
+            finally:
+                os._exit(1)
+        else:
+            os.close(w)
+            res = os.read(r, 100)
+            os.close(r)
+            if res != "":
+                os.close(self.__pty)
+                os.waitpid(self.__child, 0)
+                raise OSError("exec failed")
+            expectable.__init__(self, self.__pty)
+
+    def send(self, s):
+        os.write(self.__pty, s)
+
+    def close(self):
+        os.close(self.__pty)
+        return os.waitpid(self.__child, 0)
+
 class impl:
     def __init__(self, timeout = None):
         self.__first = True