| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869 |
- #!/usr/bin/env python3
- """Minimal QMP client for the PCL PoC VM."""
- import json
- import socket
- class QMPError(RuntimeError):
- pass
- class QMP:
- def __init__(self, path, timeout=10.0):
- self.sock = socket.socket(socket.AF_UNIX, socket.SOCK_STREAM)
- self.sock.settimeout(timeout)
- self.sock.connect(path)
- self.f = self.sock.makefile("rwb", buffering=0)
- greeting = self._read()
- if "QMP" not in greeting:
- raise QMPError("not a QMP greeting: %r" % (greeting,))
- self._send({"execute": "qmp_capabilities"})
- self._read()
- def _read(self):
- line = self.f.readline()
- if not line:
- raise EOFError("QMP closed")
- return json.loads(line.decode("utf-8", "replace"))
- def _send(self, obj):
- self.f.write((json.dumps(obj) + "\n").encode("utf-8"))
- def cmd(self, name, args=None, timeout=15.0):
- self.sock.settimeout(timeout)
- request = {"execute": name}
- if args is not None:
- request["arguments"] = args
- self._send(request)
- while True:
- message = self._read()
- if "return" in message or "error" in message:
- return message
- def sendkey(self, key="spc"):
- return self.cmd(
- "human-monitor-command", {"command-line": "sendkey %s" % key}
- )
- def screendump(self, path):
- return self.cmd("screendump", {"filename": path})
- def status(self):
- return self.cmd("query-status", timeout=3.0)
- def quit(self):
- try:
- self.cmd("quit", timeout=3.0)
- except Exception:
- pass
- def close(self):
- try:
- self.f.close()
- except Exception:
- pass
- try:
- self.sock.close()
- except Exception:
- pass
|