Skip to content
Snippets Groups Projects
Commit b9a15f07 authored by cody burkard's avatar cody burkard
Browse files

adding old changes

parent f11dbe81
No related branches found
No related tags found
No related merge requests found
......@@ -55,7 +55,7 @@ def __init__( self, mininet, stdin=sys.stdin, script=None ):
Cmd.__init__( self )
info( '*** Starting CLI:\n' )
# Setup history if readline is available
# Set up history if readline is available
try:
import readline
except ImportError:
......@@ -77,7 +77,7 @@ def __init__( self, mininet, stdin=sys.stdin, script=None ):
node.sendInt()
node.monitor()
if self.isatty():
quietRun( 'stty sane' )
quietRun( 'stty echo sane intr "^C"' )
self.cmdloop()
break
except KeyboardInterrupt:
......@@ -352,8 +352,7 @@ def default( self, line ):
for arg in rest ]
rest = ' '.join( rest )
# Run cmd on node:
builtin = isShellBuiltin( first )
node.sendCmd( rest, printPid=( not builtin ) )
node.sendCmd( rest )
self.waitForNode( node )
else:
error( '*** Unknown command: %s\n' % line )
......@@ -361,7 +360,7 @@ def default( self, line ):
# pylint: enable-msg=R0201
def waitForNode( self, node ):
"Wait for a node to finish, and print its output."
"Wait for a node to finish, and print its output."
# Pollers
nodePoller = poll()
nodePoller.register( node.stdout )
......@@ -379,7 +378,7 @@ def waitForNode( self, node ):
if False and self.inputFile:
key = self.inputFile.read( 1 )
if key is not '':
node.write(key)
node.write( key )
else:
self.inputFile = None
if isReadable( self.inPoller ):
......@@ -391,8 +390,12 @@ def waitForNode( self, node ):
if not node.waiting:
break
except KeyboardInterrupt:
# There is an at least one race condition here, since
# it's possible to interrupt ourselves after we've
# read data but before it has been printed.
node.sendInt()
# Helper functions
def isReadable( poller ):
......
......@@ -50,6 +50,7 @@
"""
import os
import pty
import re
import signal
import select
......@@ -123,16 +124,22 @@ def startShell( self ):
return
# mnexec: (c)lose descriptors, (d)etach from tty,
# (p)rint pid, and run in (n)amespace
opts = '-cdp'
opts = '-cd'
if self.inNamespace:
opts += 'n'
# bash -m: enable job control
# bash -m: enable job control, i: force interactive
# -s: pass $* to shell, and make process easy to find in ps
cmd = [ 'mnexec', opts, 'bash', '-ms', 'mininet:' + self.name ]
self.shell = Popen( cmd, stdin=PIPE, stdout=PIPE, stderr=STDOUT,
close_fds=True )
self.stdin = self.shell.stdin
self.stdout = self.shell.stdout
# prompt is set to sentinel chr( 127 )
os.environ[ 'PS1' ] = chr( 127 )
cmd = [ 'mnexec', opts, 'bash', '--norc', '-mis', 'mininet:' + self.name ]
# Spawn a shell subprocess in a pseudo-tty, to disable buffering
# in the subprocess and insulate it from signals (e.g. SIGINT)
# received by the parent
master, slave = pty.openpty()
self.shell = Popen( cmd, stdin=slave, stdout=slave, stderr=slave,
close_fds=False )
self.stdin = os.fdopen( master )
self.stdout = self.stdin
self.pid = self.shell.pid
self.pollOut = select.poll()
self.pollOut.register( self.stdout )
......@@ -145,7 +152,14 @@ def startShell( self ):
self.lastCmd = None
self.lastPid = None
self.readbuf = ''
# Wait for prompt
while True:
data = self.read( 1024 )
if data[ -1 ] == chr( 127 ):
break
self.pollOut.poll()
self.waiting = False
self.cmd( 'stty -echo' )
def cleanup( self ):
"Help python collect its garbage."
......@@ -224,36 +238,29 @@ def sendCmd( self, *args, **kwargs ):
# Replace empty commands with something harmless
cmd = 'echo -n'
self.lastCmd = cmd
printPid = printPid and not isShellBuiltin( cmd )
if len( cmd ) > 0 and cmd[ -1 ] == '&':
# print ^A{pid}\n{sentinel}
cmd += ' printf "\\001%d\n\\177" $! \n'
else:
# print sentinel
cmd += '; printf "\\177"'
if printPid and not isShellBuiltin( cmd ):
if printPid and not isShellBuiltin( cmd ):
if len( cmd ) > 0 and cmd[ -1 ] == '&':
# print ^A{pid}\n so monitor() can set lastPid
cmd += ' printf "\\001%d\n" $! \n'
else:
cmd = 'mnexec -p ' + cmd
self.write( cmd + '\n' )
self.lastPid = None
self.waiting = True
def sendInt( self, sig=signal.SIGINT ):
def sendInt( self, intr=chr( 3 ) ):
"Interrupt running command."
if self.lastPid:
try:
os.kill( self.lastPid, sig )
except OSError:
pass
self.write( intr )
def monitor( self, timeoutms=None ):
def monitor( self, timeoutms=None, findPid=True ):
"""Monitor and return the output of a command.
Set self.waiting to False if command has completed.
timeoutms: timeout in ms or None to wait indefinitely."""
self.waitReadable( timeoutms )
data = self.read( 1024 )
# Look for PID
marker = chr( 1 ) + r'\d+\n'
if chr( 1 ) in data:
marker = chr( 1 ) + r'\d+\r\n'
if findPid and chr( 1 ) in data:
markers = re.findall( marker, data )
if markers:
self.lastPid = int( markers[ 0 ][ 1: ] )
......@@ -322,7 +329,10 @@ def popen( self, *args, **kwargs ):
# Shell requires a string, not a list!
if defaults.get( 'shell', False ):
cmd = ' '.join( cmd )
return Popen( cmd, **defaults )
old = signal.signal( signal.SIGINT, signal.SIG_IGN )
popen = Popen( cmd, **defaults )
signal.signal( signal.SIGINT, old )
return popen
def pexec( self, *args, **kwargs ):
"""Execute a command using popen
......
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