summaryrefslogtreecommitdiff
path: root/server/red_record_qxl.c
diff options
context:
space:
mode:
Diffstat (limited to 'server/red_record_qxl.c')
-rw-r--r--server/red_record_qxl.c50
1 files changed, 50 insertions, 0 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;
+}