[PATCH 09/10 V2] send-key: Expose the new API in virsh

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

 



Signed-off-by: Lai Jiangshan <laijs@xxxxxxxxxxxxxx>
---
 tools/virsh.c   |  102 +++++++++++++++++++++++++++++++++++++++++++++++++++++++
 tools/virsh.pod |    4 ++
 2 files changed, 106 insertions(+), 0 deletions(-)

diff --git a/tools/virsh.c b/tools/virsh.c
index d13c12b..7b5847f 100644
--- a/tools/virsh.c
+++ b/tools/virsh.c
@@ -33,6 +33,8 @@
 #include <signal.h>
 #include <poll.h>
 
+#include <libvirt/virtkeys.h>
+
 #include <libxml/parser.h>
 #include <libxml/tree.h>
 #include <libxml/xpath.h>
@@ -3182,6 +3184,105 @@ cmdInjectNMI(vshControl *ctl, const vshCmd *cmd)
 }
 
 /*
+ * "send-key" command
+ */
+static const vshCmdInfo info_send_key[] = {
+    {"help", N_("Send keycodes to the guest")},
+    {"desc", N_("Send keycodes to the guest, the keycodes must be integers\n"
+                "    Examples:\n\n"
+                "        virsh # send-key <domain> 37 18 21\n"
+                "        virsh # send-key <domain> --holdtime 1000 0x15 18 0xf\n"
+                )},
+    {NULL, NULL}
+};
+
+static const vshCmdOptDef opts_send_key[] = {
+    {"domain", VSH_OT_DATA, VSH_OFLAG_REQ, N_("domain name, id or uuid")},
+    {"codeset", VSH_OT_STRING, VSH_OFLAG_REQ_OPT, N_("the codeset of keycodes, default:linux")},
+    {"holdtime", VSH_OT_INT, VSH_OFLAG_REQ_OPT,
+                 N_("the time (in millsecond) how long the keys will be held")},
+    {"keycode", VSH_OT_ARGV, VSH_OFLAG_REQ, N_("the key code")},
+    {NULL, 0, 0, NULL}
+};
+
+static int get_integer_keycode(const char *key_name)
+{
+    long val;
+    char *endptr;
+
+    val = strtol(key_name, &endptr, 0);
+    if (*endptr != '\0' || val > 255 || val <= 0)
+         return -1;
+
+    return val;
+}
+
+static bool
+cmdSendKey(vshControl *ctl, const vshCmd *cmd)
+{
+    virDomainPtr dom;
+    int ret = false;
+    const char *codeset_option;
+    int codeset;
+    int holdtime;
+    int count = 0;
+    const vshCmdOpt *opt;
+    int keycode;
+    unsigned int keycodes[MAX_SEND_KEY];
+
+    if (!vshConnectionUsability(ctl, ctl->conn))
+        return false;
+
+    if (!(dom = vshCommandOptDomain(ctl, cmd, NULL)))
+        return false;
+
+    if (vshCommandOptString(cmd, "codeset", &codeset_option) <= 0)
+        codeset_option = "default";
+
+    if (vshCommandOptInt(cmd, "holdtime", &holdtime) <= 0)
+        holdtime = 0;
+
+    if (STREQ(codeset_option, "default") || STREQ(codeset_option, "linux")) {
+        codeset = LIBVIRT_KEYCODE_LINUX;
+    } else if (STREQ(codeset_option, "xt")) {
+        codeset = LIBVIRT_KEYCODE_XT;
+    } else if (STREQ(codeset_option, "atset1")) {
+        codeset = LIBVIRT_KEYCODE_ATSET1;
+    } else if (STREQ(codeset_option, "atset2")) {
+        codeset = LIBVIRT_KEYCODE_ATSET2;
+    } else if (STREQ(codeset_option, "atset3")) {
+        codeset = LIBVIRT_KEYCODE_ATSET3;
+    } else {
+        vshError(ctl, _("unknown codeset: '%s'"), codeset_option);
+        goto free_domain;
+    }
+
+    for_each_variable_arg(cmd, opt) {
+        if (count == MAX_SEND_KEY) {
+            vshError(ctl, _("too many keycode"));
+            goto free_domain;
+        }
+
+        if ((keycode = get_integer_keycode(opt->data)) > 0)
+            goto get_keycode;
+
+        vshError(ctl, _("invalid keycode: '%s'"), opt->data);
+        goto free_domain;
+
+get_keycode:
+        keycodes[count] = keycode;
+        count++;
+    }
+
+    if (!(virDomainSendKey(dom, codeset, holdtime, keycodes, count, 0) < 0))
+            ret = true;
+
+free_domain:
+    virDomainFree(dom);
+    return ret;
+}
+
+/*
  * "setmemory" command
  */
 static const vshCmdInfo info_setmem[] = {
@@ -11095,6 +11196,7 @@ static const vshCmdDef domManagementCmds[] = {
     {"dumpxml", cmdDumpXML, opts_dumpxml, info_dumpxml, 0},
     {"edit", cmdEdit, opts_edit, info_edit, 0},
     {"inject-nmi", cmdInjectNMI, opts_inject_nmi, info_inject_nmi, 0},
+    {"send-key", cmdSendKey, opts_send_key, info_send_key},
     {"managedsave", cmdManagedSave, opts_managedsave, info_managedsave, 0},
     {"managedsave-remove", cmdManagedSaveRemove, opts_managedsaveremove,
      info_managedsaveremove, 0},
diff --git a/tools/virsh.pod b/tools/virsh.pod
index 7ed3003..03b1418 100644
--- a/tools/virsh.pod
+++ b/tools/virsh.pod
@@ -296,6 +296,10 @@ scheduling by the hypervisor.
 
 Inject NMI to the guest
 
+=item B<send-key> I<domain-id> I<--codeset> B<codeset> I<--holdtime> B<holdtime> B<keycode>...
+
+Send keys to the guest
+
 =item B<shutdown>
 
 The domain is in the process of shutting down, i.e. the guest operating system
-- 
1.7.4.4

--
libvir-list mailing list
libvir-list@xxxxxxxxxx
https://www.redhat.com/mailman/listinfo/libvir-list


[Index of Archives]     [Virt Tools]     [Libvirt Users]     [Lib OS Info]     [Fedora Users]     [Fedora Desktop]     [Fedora SELinux]     [Big List of Linux Books]     [Yosemite News]     [KDE Users]     [Fedora Tools]