By using the 'unix:' prefix notation, similar to the migration uri, we can now dump to a UNIX socket. IO is still sync --- hw/vga.c | 64 +++++++++++++++++++++++++++++++++++++++++++++++++++++++++- qemu-file.h | 1 + 2 files changed, 63 insertions(+), 2 deletions(-)
diff --git a/hw/vga.c b/hw/vga.c index 24af4a1..bb5df70 100644 --- a/hw/vga.c +++ b/hw/vga.c @@ -30,6 +30,7 @@ #include "pixel_ops.h" #include "qemu-timer.h" #include "xen.h" +#include "qemu_socket.h" //#define DEBUG_VGA //#define DEBUG_VGA_MEM @@ -37,6 +38,14 @@ //#define DEBUG_BOCHS_VBE +#ifdef DEBUG_VGA +#define DPRINTF(fmt, ...) \ + do { printf("vga: " fmt, ## __VA_ARGS__); } while (0) +#else +#define DPRINTF(fmt, ...) \ + do { } while (0) +#endif + /* * Video Graphics Array (VGA) * @@ -2362,7 +2371,58 @@ void vga_init_vbe(VGACommonState *s, MemoryRegion *system_memory) /********************************************************/ /* vga screen dump */ -int ppm_save(const char *filename, struct DisplaySurface *ds) +#if !defined(WIN32) +static QEMUFile *qemu_fopen_unix(const char *path, const char *mode) +{ + struct sockaddr_un addr; + int ret, fd; + + addr.sun_family = AF_UNIX; + snprintf(addr.sun_path, sizeof(addr.sun_path), "%s", path); + + fd = qemu_socket(PF_UNIX, SOCK_STREAM, 0); + if (fd == -1) { + DPRINTF("Unable to open socket: %s\n", strerror(errno)); + return NULL; + } + + do { + ret = connect(fd, (struct sockaddr *)&addr, sizeof(addr)); + if (ret == -1) { + ret = -errno; + } + } while (ret == -EINTR); + + if (ret < 0) { + DPRINTF("connect failed: %s\n": strerror(errno)); + return NULL; + } + + return qemu_fopen_socket(fd, mode); +} +#endif + +QEMUFile *qemu_fopen_uri(const char *uri, const char *mode) +{ + QEMUFile *f = NULL; + const char *p; + + g_return_val_if_fail(uri != NULL, NULL); + g_return_val_if_fail(mode != NULL, NULL); + +#if !defined(WIN32) + if (strstart(uri, "unix:", &p)) { + f = qemu_fopen_unix(p, mode); + } +#endif + if (f == NULL) { + f = qemu_fopen(uri, mode); + } + + return f; +} + +int ppm_save(const char *uri, struct DisplaySurface *ds) { QEMUFile *f; uint8_t *d, *d1; @@ -2372,7 +2432,7 @@ int ppm_save(const char *filename, struct DisplaySurface *ds) char *linebuf, *pbuf; gchar *header; - f = qemu_fopen(filename, "wb"); + f = qemu_fopen_uri(uri, "wb"); g_return_val_if_fail(f != NULL, -1); header = g_strdup_printf("P6\n%d %d\n%d\n", ds->width, ds->height, 255); diff --git a/qemu-file.h b/qemu-file.h index efd6b1c..0914d83 100644 --- a/qemu-file.h +++ b/qemu-file.h @@ -68,6 +68,7 @@ QEMUFile *qemu_fopen_ops(void *opaque, QEMUFilePutBufferFunc *put_buffer, QEMUFile *qemu_fopen(const char *filename, const char *mode); QEMUFile *qemu_fdopen(int fd, const char *mode); QEMUFile *qemu_fopen_socket(int fd, const char *mode); +QEMUFile *qemu_fopen_uri(const char *uri, const char *mode); QEMUFile *qemu_popen(FILE *popen_file, const char *mode); QEMUFile *qemu_popen_cmd(const char *command, const char *mode); int qemu_stdio_fd(QEMUFile *f); -- 1.7.7.6