qemu-monitor: migrate to Python!

Just came across the telnet in the stdlib, and got rid of the ugly expect
dependency, nice.

Also implement stdin input now that we have a sane language.
This commit is contained in:
Ciro Santilli 六四事件 法轮功
2018-11-10 00:00:00 +00:00
parent d697640584
commit 6c355c80d3
3 changed files with 50 additions and 27 deletions

View File

@@ -8017,12 +8017,16 @@ or send one command such as `info qtree` and quit the monitor:
./qemu-monitor info qtree ./qemu-monitor info qtree
.... ....
or equivalently:
....
echo 'info qtree' | ./qemu-monitor
....
Source: link:qemu-monitor[] Source: link:qemu-monitor[]
`qemu-monitor` uses the `-monitor` QEMU command line option, which makes the monitor listen from a socket. `qemu-monitor` uses the `-monitor` QEMU command line option, which makes the monitor listen from a socket.
`qemu-monitor` does not support input from an stdin pipe currently, see comments on the source for rationale.
Alternatively, from text mode: Alternatively, from text mode:
.... ....

View File

@@ -88,9 +88,9 @@ automake \
bc \ bc \
bison \ bison \
build-essential \ build-essential \
ccache \
coreutils \ coreutils \
cpio \ cpio \
expect \
flex \ flex \
gcc-aarch64-linux-gnu \ gcc-aarch64-linux-gnu \
gcc-arm-linux-gnueabihf \ gcc-arm-linux-gnueabihf \
@@ -114,7 +114,6 @@ pexpect==4.6.0 \
" "
if "$gem5"; then if "$gem5"; then
pkgs="${pkgs}\ pkgs="${pkgs}\
ccache \
diod \ diod \
libgoogle-perftools-dev \ libgoogle-perftools-dev \
protobuf-compiler \ protobuf-compiler \

View File

@@ -1,24 +1,44 @@
#!/usr/bin/env expect #!/usr/bin/env python3
# Ee have to use expect since QEMU 2.12: just piping commands
# into telnet stopped working at that version.
spawn telnet localhost 45454
set prompt "\n(qemu) "
expect $prompt
if {$argc > 0} {
send "[concat [join $argv " "]]\r"
expect $prompt
} else {
interact
}
# In order to treat input from stdin, we would need to differentiate between input from pipe vs terminal. import os
# For bash we can do it as: import sys
# https://stackoverflow.com/questions/911168/how-to-detect-if-my-shell-script-is-running-through-a-pipe import telnetlib
# but no one knows for Tcl:
# https://stackoverflow.com/questions/43660612/how-to-check-if-stdin-stdout-are-connected-to-a-terminal-in-tcl import common
# One option would also be to have a bash wrapper that calls this tcl script.
# Related: https://stackoverflow.com/questions/10237872/expect-redirect-stdin prompt = b'\n(qemu) '
#while {[gets stdin line] > 0} {
#expect $prompt parser = common.get_argparse({
#send "$line\r" 'description': '''\
#} Run a command on the QEMU monitor of a running QEMU instance
If the stdin is a terminal, open an interact shell. Otherwise,
run commands from stdin and quit.
'''
})
parser.add_argument(
'command',
help='If given, run this command and quit',
nargs='*',
)
args = common.setup(parser)
def write_and_read(tn, cmd, prompt):
tn.write(cmd.encode('utf-8'))
return '\n'.join(tn.read_until(prompt).decode('utf-8').splitlines()[1:])[:-len(prompt)]
with telnetlib.Telnet('localhost', common.qemu_monitor_port) as tn:
# Couldn't disable server echo, so just removing the write for now.
# https://stackoverflow.com/questions/12421799/how-to-disable-telnet-echo-in-python-telnetlib
# sock = tn.get_socket()
# sock.send(telnetlib.IAC + telnetlib.WILL + telnetlib.ECHO)
if os.isatty(sys.stdin.fileno()):
if args.command == []:
print(tn.read_until(prompt).decode('utf-8'), end='')
tn.interact()
else:
tn.read_until(prompt)
print(write_and_read(tn, ' '.join(args.command) + '\n', prompt))
else:
tn.read_until(prompt)
print(write_and_read(tn, sys.stdin.read() + '\n', prompt))