diff options
Diffstat (limited to 'server/red_record_qxl.c')
-rw-r--r-- | server/red_record_qxl.c | 50 |
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; +} |