summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--server/red_record_qxl.c50
-rw-r--r--server/red_record_qxl.h2
-rw-r--r--server/red_worker.c2
3 files changed, 53 insertions, 1 deletions
diff --git a/server/red_record_qxl.c b/server/red_record_qxl.c
index d96fb799..6a0b8fde 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 b737db89..0b74dc4c 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 7d7858e8..a80dc934 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);
}