]> Git Repo - qemu.git/commitdiff
qmp-shell: add persistent command history
authorJohn Snow <[email protected]>
Thu, 27 Apr 2017 22:36:28 +0000 (18:36 -0400)
committerMarkus Armbruster <[email protected]>
Tue, 9 May 2017 07:14:40 +0000 (09:14 +0200)
Use the existing readline history function we are utilizing
to provide persistent command history across instances of qmp-shell.

This assists entering debug commands across sessions that may be
interrupted by QEMU sessions terminating, where the qmp-shell has
to be relaunched.

Signed-off-by: John Snow <[email protected]>
Message-Id: <20170427223628[email protected]>
Reviewed-by: Stefan Hajnoczi <[email protected]>
Reviewed-by: Kashyap Chamarthy <[email protected]>
Tested-by: Kashyap Chamarthy <[email protected]>
Signed-off-by: Markus Armbruster <[email protected]>
scripts/qmp/qmp-shell

index eccb88a4e8b448c5d49d11d69d4a6213e2cc84f7..6ece6e7c814e2b735e42b3038c4a03369235103f 100755 (executable)
@@ -70,6 +70,9 @@ import json
 import ast
 import readline
 import sys
 import ast
 import readline
 import sys
+import os
+import errno
+import atexit
 
 class QMPCompleter(list):
     def complete(self, text, state):
 
 class QMPCompleter(list):
     def complete(self, text, state):
@@ -109,6 +112,8 @@ class QMPShell(qmp.QEMUMonitorProtocol):
         self._pretty = pretty
         self._transmode = False
         self._actions = list()
         self._pretty = pretty
         self._transmode = False
         self._actions = list()
+        self._histfile = os.path.join(os.path.expanduser('~'),
+                                      '.qmp-shell_history')
 
     def __get_address(self, arg):
         """
 
     def __get_address(self, arg):
         """
@@ -132,11 +137,27 @@ class QMPShell(qmp.QEMUMonitorProtocol):
     def __completer_setup(self):
         self._completer = QMPCompleter()
         self._fill_completion()
     def __completer_setup(self):
         self._completer = QMPCompleter()
         self._fill_completion()
+        readline.set_history_length(1024)
         readline.set_completer(self._completer.complete)
         readline.parse_and_bind("tab: complete")
         # XXX: default delimiters conflict with some command names (eg. query-),
         # clearing everything as it doesn't seem to matter
         readline.set_completer_delims('')
         readline.set_completer(self._completer.complete)
         readline.parse_and_bind("tab: complete")
         # XXX: default delimiters conflict with some command names (eg. query-),
         # clearing everything as it doesn't seem to matter
         readline.set_completer_delims('')
+        try:
+            readline.read_history_file(self._histfile)
+        except Exception as e:
+            if isinstance(e, IOError) and e.errno == errno.ENOENT:
+                # File not found. No problem.
+                pass
+            else:
+                print "Failed to read history '%s'; %s" % (self._histfile, e)
+        atexit.register(self.__save_history)
+
+    def __save_history(self):
+        try:
+            readline.write_history_file(self._histfile)
+        except Exception as e:
+            print "Failed to save history file '%s'; %s" % (self._histfile, e)
 
     def __parse_value(self, val):
         try:
 
     def __parse_value(self, val):
         try:
This page took 0.028737 seconds and 4 git commands to generate.