[virt-tools-list] [PATCH v2 1/3] remote-viewer: learn '-' as URI for standard input connection file

marcandre.lureau at redhat.com marcandre.lureau at redhat.com
Tue Nov 14 15:56:01 UTC 2017


From: Marc-André Lureau <marcandre.lureau at redhat.com>

Some users want the ability to set connection details without writing
to a file or passing command line arguments.

Learn to read the connection file from standard input for such use
case.

This allows a parent process to set the connection details without
intermediary file.

Signed-off-by: Marc-André Lureau <marcandre.lureau at redhat.com>
Reviewed-by: Victor Toso <victortoso at redhat.com>
---
 man/remote-viewer.pod  |  3 +++
 src/remote-viewer.c    | 46 ++++++++++++++++++++++++++++++++++++++++------
 src/virt-viewer-file.c | 31 +++++++++++++++++++++++++------
 src/virt-viewer-file.h |  2 ++
 4 files changed, 70 insertions(+), 12 deletions(-)

diff --git a/man/remote-viewer.pod b/man/remote-viewer.pod
index 60ea3a6..8428c80 100644
--- a/man/remote-viewer.pod
+++ b/man/remote-viewer.pod
@@ -18,6 +18,9 @@ entry and a list of previously successfully accessed URI.
 The URI can also point to a connection settings file, see the CONNECTION FILE
 section for a description of the format.
 
+If URI is '-', then remote-viewer will read the standard input as a
+connection settings file and attempt to connect using it.
+
 =head1 OPTIONS
 
 The following options are accepted when running C<remote-viewer>:
diff --git a/src/remote-viewer.c b/src/remote-viewer.c
index fb5376c..e082178 100644
--- a/src/remote-viewer.c
+++ b/src/remote-viewer.c
@@ -1084,6 +1084,22 @@ remote_viewer_session_connected(VirtViewerSession *session,
     g_free(uri);
 }
 
+static gchar *
+read_all_stdin(gsize *len, GError **err)
+{
+    GIOChannel *ioc = g_io_channel_unix_new(fileno(stdin));
+    gchar *content = NULL;
+    GIOStatus status;
+
+    status = g_io_channel_read_to_end(ioc, &content, len, err);
+    g_assert(status != G_IO_STATUS_AGAIN && status != G_IO_STATUS_EOF);
+
+    g_io_channel_unref(ioc);
+    g_assert((content && !*err) || (!content && *err));
+
+    return content;
+}
+
 static gboolean
 remote_viewer_initial_connect(RemoteViewer *self, const gchar *type,
                               VirtViewerFile *vvfile, GError **error)
@@ -1174,16 +1190,34 @@ retry_dialog:
 
         g_debug("Opening display to %s", guri);
 
-        file = g_file_new_for_commandline_arg(guri);
-        if (g_file_query_exists(file, NULL)) {
-            gchar *path = g_file_get_path(file);
-            vvfile = virt_viewer_file_new(path, &error);
-            g_free(path);
+        if (!g_strcmp0(guri, "-")) {
+            gsize len = 0;
+            gchar *buf = read_all_stdin(&len, &error);
+
             if (error) {
-                g_prefix_error(&error, _("Invalid file %s: "), guri);
+                g_prefix_error(&error, _("Failed to read stdin: "));
                 g_warning("%s", error->message);
                 goto cleanup;
             }
+
+            vvfile = virt_viewer_file_new_from_buffer(buf, len, &error);
+            g_free(buf);
+        } else {
+            file = g_file_new_for_commandline_arg(guri);
+            if (g_file_query_exists(file, NULL)) {
+                gchar *path = g_file_get_path(file);
+                vvfile = virt_viewer_file_new(path, &error);
+                g_free(path);
+            }
+        }
+
+        if (error) {
+            g_prefix_error(&error, _("Invalid file %s: "), guri);
+            g_warning("%s", error->message);
+            goto cleanup;
+        }
+
+        if (vvfile) {
             g_object_get(G_OBJECT(vvfile), "type", &type, NULL);
         } else if (virt_viewer_util_extract_host(guri, &type, NULL, NULL, NULL, NULL) < 0 || type == NULL) {
             g_set_error_literal(&error,
diff --git a/src/virt-viewer-file.c b/src/virt-viewer-file.c
index 9ff2a05..1b0c310 100644
--- a/src/virt-viewer-file.c
+++ b/src/virt-viewer-file.c
@@ -139,16 +139,15 @@ enum  {
 };
 
 VirtViewerFile*
-virt_viewer_file_new(const gchar* location, GError** error)
+virt_viewer_file_new_from_buffer(const gchar* data, gsize len,
+                                 GError** error)
 {
     GError* inner_error = NULL;
-
-    g_return_val_if_fail (location != NULL, NULL);
-
     VirtViewerFile* self = VIRT_VIEWER_FILE(g_object_new(VIRT_VIEWER_TYPE_FILE, NULL));
     GKeyFile* keyfile = self->priv->keyfile;
 
-    g_key_file_load_from_file(keyfile, location,
+    g_return_val_if_fail(data != NULL, NULL);
+    g_key_file_load_from_data(keyfile, data, len,
                               G_KEY_FILE_KEEP_COMMENTS | G_KEY_FILE_KEEP_TRANSLATIONS,
                               &inner_error);
     if (inner_error != NULL) {
@@ -166,7 +165,27 @@ virt_viewer_file_new(const gchar* location, GError** error)
         return NULL;
     }
 
-    if (virt_viewer_file_get_delete_this_file(self) &&
+    return self;
+}
+
+VirtViewerFile*
+virt_viewer_file_new(const gchar* location, GError** error)
+{
+    VirtViewerFile *self;
+    gchar *buf;
+    gsize len;
+
+    g_return_val_if_fail (location != NULL, NULL);
+
+    if (!g_file_get_contents(location, &buf, &len, error)) {
+        return NULL;
+    }
+
+    self = virt_viewer_file_new_from_buffer(buf, len, error);
+    g_free(buf);
+
+
+    if (self && virt_viewer_file_get_delete_this_file(self) &&
         !g_getenv("VIRT_VIEWER_KEEP_FILE")) {
         if (g_unlink(location) != 0)
             g_warning("failed to remove %s", location);
diff --git a/src/virt-viewer-file.h b/src/virt-viewer-file.h
index 6b783f9..15c61d0 100644
--- a/src/virt-viewer-file.h
+++ b/src/virt-viewer-file.h
@@ -50,6 +50,8 @@ struct _VirtViewerFileClass
 GType virt_viewer_file_get_type(void);
 
 VirtViewerFile* virt_viewer_file_new(const gchar* path, GError** error);
+VirtViewerFile* virt_viewer_file_new_from_buffer(const gchar* buf, gsize len,
+                                                 GError** error);
 gboolean virt_viewer_file_is_set(VirtViewerFile* self, const gchar* key);
 
 gchar* virt_viewer_file_get_ca(VirtViewerFile* self);
-- 
2.15.0.125.g8f49766d64




More information about the virt-tools-list mailing list