On Mon, Mar 12, 2012 at 02:11:30PM +0100, Marc-André Lureau wrote: > 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);
It would be even more broadly useful if the screendump command was extended to allow a file descriptor to be just passed across to QEMU, avoiding the need to interact with the filesystem namespace at all. Regards, Daniel -- |: http://berrange.com -o- http://www.flickr.com/photos/dberrange/ :| |: http://libvirt.org -o- http://virt-manager.org :| |: http://autobuild.org -o- http://search.cpan.org/~danberr/ :| |: http://entangle-photo.org -o- http://live.gnome.org/gtk-vnc :|