summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorThomas Kluyver <takowl@gmail.com>2014-12-19 17:11:34 -0800
committerThomas Kluyver <takowl@gmail.com>2014-12-19 17:11:34 -0800
commit341ff08260657fa10ba719ce31d9da6013c24749 (patch)
tree042d176df068f9235c5f8106d43d7164a76cf9dd
parent77357d107b1ebb38287695149d7cf1e66df4addd (diff)
parent40e1aa43d60cfcc213c441ff66cf54d049c12317 (diff)
downloadpexpect-341ff08260657fa10ba719ce31d9da6013c24749.tar.gz
Merge pull request #158 from takluyver/preexec_fn
Expose preexec_fn from ptyprocess
-rw-r--r--pexpect/pty_spawn.py20
-rwxr-xr-xtests/test_misc.py4
2 files changed, 17 insertions, 7 deletions
diff --git a/pexpect/pty_spawn.py b/pexpect/pty_spawn.py
index b3fbeca..0663926 100644
--- a/pexpect/pty_spawn.py
+++ b/pexpect/pty_spawn.py
@@ -37,7 +37,7 @@ class spawn(SpawnBase):
def __init__(self, command, args=[], timeout=30, maxread=2000,
searchwindowsize=None, logfile=None, cwd=None, env=None,
- ignore_sighup=True, echo=True):
+ ignore_sighup=True, echo=True, preexec_fn=None):
'''This is the constructor. The command parameter may be a string that
includes a command and any arguments to the command. For example::
@@ -166,6 +166,10 @@ class spawn(SpawnBase):
using setecho(False) followed by waitnoecho(). However, for some
platforms such as Solaris, this is not possible, and should be
disabled immediately on spawn.
+
+ If preexec_fn is given, it will be called in the child process before
+ launching the given command. This is useful to e.g. reset inherited
+ signal handlers.
'''
super(spawn, self).__init__(timeout=timeout, maxread=maxread, searchwindowsize=searchwindowsize,
logfile=logfile)
@@ -182,7 +186,7 @@ class spawn(SpawnBase):
self.args = None
self.name = '<pexpect factory incomplete>'
else:
- self._spawn(command, args)
+ self._spawn(command, args, preexec_fn)
def __str__(self):
'''This returns a human-readable string that represents the state of
@@ -218,7 +222,7 @@ class spawn(SpawnBase):
s.append('delayafterterminate: ' + str(self.delayafterterminate))
return '\n'.join(s)
- def _spawn(self, command, args=[]):
+ def _spawn(self, command, args=[], preexec_fn=None):
'''This starts the given command in a child process. This does all the
fork/exec type of stuff for a pty. This is called by __init__. If args
is empty then command will be parsed (split on spaces) and args will be
@@ -264,9 +268,15 @@ class spawn(SpawnBase):
assert self.pid is None, 'The pid member must be None.'
assert self.command is not None, 'The command member must not be None.'
- kwargs = {'echo': self.echo}
+ kwargs = {'echo': self.echo, 'preexec_fn': preexec_fn}
if self.ignore_sighup:
- kwargs['before_exec'] = [lambda: signal.signal(signal.SIGHUP, signal.SIG_IGN)]
+ def preexec_wrapper():
+ "Set SIGHUP to be ignored, then call the real preexec_fn"
+ signal.signal(signal.SIGHUP, signal.SIG_IGN)
+ if preexec_fn is not None:
+ preexec_fn()
+ kwargs['preexec_fn'] = preexec_wrapper
+
self.ptyproc = self.ptyprocess_class.spawn(self.args, env=self.env,
cwd=self.cwd, **kwargs)
diff --git a/tests/test_misc.py b/tests/test_misc.py
index 28df570..be3d1e7 100755
--- a/tests/test_misc.py
+++ b/tests/test_misc.py
@@ -307,9 +307,9 @@ class TestCaseMisc(PexpectTestCase.PexpectTestCase):
" test forced self.__fork_pty() and __pty_make_controlling_tty "
# given,
class spawn_ourptyfork(pexpect.spawn):
- def _spawn(self, command, args=[]):
+ def _spawn(self, command, args=[], preexec_fn=None):
self.use_native_pty_fork = False
- pexpect.spawn._spawn(self, command, args)
+ pexpect.spawn._spawn(self, command, args, preexec_fn)
# exercise,
p = spawn_ourptyfork('cat', echo=False)