Skip to content
Snippets Groups Projects
Commit 4065511a authored by Bob Lantz's avatar Bob Lantz
Browse files

Detach shells from tty; monitoring changes.

Call netns using setsid to detach from the tty; this is
intended to fix the problem of control-C killing your network.

sendInt() doesn't actually work - hopefully we can fix this in the
future, but it's tricky since we want to detach the many shells from
our tty, but then optionally send tty interrupts to them! Ideally we
would either know the pid of the subprocess or be able to send a signal
to bash to get it to interrupt its subprocess.

waitOutput() now uses monitor. We also handle sentinels
coming in the middle of output (but default at end should
still work well.)
parent 2ad03eea
No related branches found
No related tags found
No related merge requests found
......@@ -66,8 +66,9 @@ def __init__( self, name, inNamespace=True,
defaultIP: default IP address for intf 0"""
self.name = name
closeFds = False # speed vs. memory use
# setsid is necessary to detach from tty
# xpg_echo is needed so we can echo our sentinel in sendCmd
cmd = [ '/bin/bash', '-O', 'xpg_echo' ]
cmd = [ '/usr/bin/setsid', '/bin/bash', '-O', 'xpg_echo' ]
self.inNamespace = inNamespace
if self.inNamespace:
cmd = [ 'netns' ] + cmd
......@@ -143,20 +144,22 @@ def sendCmd( self, cmd ):
self.write( cmd + separator + ' echo -n "\\0177" \n' )
self.waiting = True
def sendInt( self ):
"""Placeholder for function to interrupt running subprocess.
This is a tricky problem to solve."""
self.write( chr( 3 ) )
def monitor( self ):
"Monitor the output of a command, returning (done?, data)."
assert self.waiting
self.waitReadable()
data = self.read( 1024 )
if len( data ) > 0 and data[ -1 ] == chr( 0177 ):
if len( data ) > 0 and data[ -1 ] == chr( 127 ):
self.waiting = False
return True, data[ :-1 ]
else:
return False, data
def sendInt( self ):
"Send ^C, hopefully interrupting an interactive subprocess."
self.write( chr( 3 ) )
elif chr( 127 ) in data:
return True, data.replace( chr( 127 ), '' )
return False, data
def waitOutput( self, verbose=False ):
"""Wait for a command to complete.
......@@ -165,18 +168,12 @@ def waitOutput( self, verbose=False ):
the output, including trailing newline.
verbose: print output interactively"""
log = info if verbose else debug
assert self.waiting
output = ''
while True:
self.waitReadable()
data = self.read( 1024 )
if len( data ) > 0 and data[ -1 ] == chr( 0177 ):
output += data[ :-1 ]
log( output )
break
else:
output += data
self.waiting = False
done = False
while not done:
done, data = self.monitor()
output += data
log( data )
return output
def cmd( self, cmd, verbose=False ):
......
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment