[libvirt] [PATCH 2/8] virsh: Add vshDomainCompleter

Tomas Meszaros exo at tty.sk
Thu Aug 8 14:38:45 UTC 2013


Function vshDomainCompler returns domains names.

Michal Privoznik recommended to add global variable __my_conn
so we can get the list of domains from the virConnecTListAllDomains().

vshReconnect() is called before the first command is executed
in order to provide autocompletion for the very first command.
---
 tools/virsh.c | 53 +++++++++++++++++++++++++++++++++++++++++++++++++++++
 tools/virsh.h |  2 ++
 2 files changed, 55 insertions(+)

diff --git a/tools/virsh.c b/tools/virsh.c
index f65dc79..af31b9a 100644
--- a/tools/virsh.c
+++ b/tools/virsh.c
@@ -88,6 +88,8 @@ static char *progname;
 
 static const vshCmdGrp cmdGroups[];
 
+virConnectPtr *__my_conn;
+
 /* Bypass header poison */
 #undef strdup
 
@@ -2502,6 +2504,51 @@ vshCloseLogFile(vshControl *ctl)
 
 #ifdef USE_READLINE
 
+/* -------------
+ * Completers
+ * -------------
+ */
+
+char **
+vshDomainCompleter(unsigned int flags)
+{
+    virDomainPtr *domains;
+    size_t i;
+    char **names = NULL;
+    int ndomains;
+
+    if (!*__my_conn)
+        return NULL;
+
+    ndomains = virConnectListAllDomains(*__my_conn, &domains, flags);
+
+    if (ndomains < 0)
+        return NULL;
+
+    names = vshMalloc(NULL, sizeof(char *) * (ndomains + 1));
+
+    if (!names)
+        return NULL;
+
+    for (i = 0; i < ndomains; i++) {
+        char *name = (char *)virDomainGetName(domains[i]);
+        if (VIR_STRDUP(names[i], name) < 0) {
+            virDomainFree(domains[i]);
+            goto cleanup;
+        }
+        virDomainFree(domains[i]);
+    }
+    names[i] = NULL;
+    VIR_FREE(domains);
+    return names;
+
+cleanup:
+    for (i = 0; names[i]; i++)
+        VIR_FREE(names[i]);
+    VIR_FREE(names);
+    return NULL;
+}
+
 /* -----------------
  * Readline stuff
  * -----------------
@@ -3158,6 +3205,7 @@ main(int argc, char **argv)
     ctl->debug = VSH_DEBUG_DEFAULT;
     ctl->escapeChar = "^]";     /* Same default as telnet */
 
+    __my_conn = &ctl->conn;
 
     if (!setlocale(LC_ALL, "")) {
         perror("setlocale");
@@ -3219,6 +3267,11 @@ main(int argc, char **argv)
             exit(EXIT_FAILURE);
         }
 
+        /* Need to connect immediately after start in order to provide
+         * autocompletion for the very first command.
+         */
+        vshReconnect(ctl);
+
         do {
             const char *prompt = ctl->readonly ? VSH_PROMPT_RO : VSH_PROMPT_RW;
             ctl->cmdstr =
diff --git a/tools/virsh.h b/tools/virsh.h
index e07b546..c4a9c13 100644
--- a/tools/virsh.h
+++ b/tools/virsh.h
@@ -254,6 +254,8 @@ struct _vshCmdGrp {
     const vshCmdDef *commands;
 };
 
+char **vshDomainCompleter(unsigned int flags);
+
 void vshError(vshControl *ctl, const char *format, ...)
     ATTRIBUTE_FMT_PRINTF(2, 3);
 void vshOpenLogFile(vshControl *ctl);
-- 
1.8.3.1




More information about the libvir-list mailing list