[Spice-devel] [PATCH v5 6/6] Allow to specify a filter for record output

Frediano Ziglio fziglio at redhat.com
Fri Aug 21 01:46:08 PDT 2015


This allows compressions using external programs or any type
of filters.

Signed-off-by: Frediano Ziglio <fziglio at redhat.com>
---
 server/red_record_qxl.c | 50 +++++++++++++++++++++++++++++++++++++++++++++++++
 server/red_record_qxl.h |  2 ++
 server/red_worker.c     |  2 +-
 3 files changed, 53 insertions(+), 1 deletion(-)

diff --git a/server/red_record_qxl.c b/server/red_record_qxl.c
index d96fb79..6a0b8fd 100644
--- a/server/red_record_qxl.c
+++ b/server/red_record_qxl.c
@@ -21,6 +21,8 @@
 
 #include <stdbool.h>
 #include <inttypes.h>
+#include <fcntl.h>
+#include <glib.h>
 #include "red_worker.h"
 #include "red_common.h"
 #include "red_memslots.h"
@@ -825,3 +827,51 @@ void red_record_qxl_command(FILE *fd, RedMemSlotInfo *slots,
         break;
     }
 }
+
+static void out_setup(gpointer user_data)
+{
+    int fd = GPOINTER_TO_INT(user_data);
+
+    dup2(fd, 1);
+    close(fd);
+    fcntl(1, F_SETFD, 0);
+}
+
+FILE *red_record_open_file(const char *record_filename)
+{
+    const char *filter;
+    FILE *f;
+
+    f = fopen(record_filename, "w+");
+    if (!f)
+        return NULL;
+
+    filter = getenv("SPICE_WORKER_RECORD_FILTER");
+    if (filter) {
+        gint argc;
+        gchar **argv = NULL;
+        GError *error = NULL;
+        GPid child_pid;
+        gboolean ret;
+        gint fd_in;
+
+        if (!g_shell_parse_argv(filter, &argc, &argv, &error)) {
+            fclose(f);
+            return NULL;
+        }
+
+        ret = g_spawn_async_with_pipes(NULL, argv, NULL, G_SPAWN_SEARCH_PATH, out_setup,
+                                       GINT_TO_POINTER(fileno(f)), &child_pid,
+                                       &fd_in, NULL, NULL, &error);
+
+        g_strfreev(argv);
+        if (!ret) {
+            g_error_free(error);
+            fclose(f);
+            return NULL;
+        }
+        dup2(fd_in, fileno(f));
+        close(fd_in);
+    }
+    return f;
+}
diff --git a/server/red_record_qxl.h b/server/red_record_qxl.h
index b737db8..0b74dc4 100644
--- a/server/red_record_qxl.h
+++ b/server/red_record_qxl.h
@@ -31,4 +31,6 @@ void red_record_event(FILE *fd, int what, uint32_t type, unsigned long ts);
 void red_record_qxl_command(FILE *fd, RedMemSlotInfo *slots,
                             QXLCommandExt ext_cmd, unsigned long ts);
 
+FILE *red_record_open_file(const char *record_filename);
+
 #endif
diff --git a/server/red_worker.c b/server/red_worker.c
index 7d7858e..a80dc93 100644
--- a/server/red_worker.c
+++ b/server/red_worker.c
@@ -12107,7 +12107,7 @@ static void red_init(RedWorker *worker, WorkerInitData *init_data)
     if (record_filename) {
         static const char header[] = "SPICE_REPLAY 1\n";
 
-        worker->record_fd = fopen(record_filename, "w+");
+        worker->record_fd = red_record_open_file(record_filename);
         if (worker->record_fd == NULL) {
             spice_error("failed to open recording file %s\n", record_filename);
         }
-- 
2.4.3



More information about the Spice-devel mailing list