aboutsummaryrefslogtreecommitdiff
path: root/hw/vga.c
diff options
context:
space:
mode:
Diffstat (limited to 'hw/vga.c')
-rw-r--r--hw/vga.c32
1 files changed, 25 insertions, 7 deletions
diff --git a/hw/vga.c b/hw/vga.c
index dd703cf41c..80299ea1d4 100644
--- a/hw/vga.c
+++ b/hw/vga.c
@@ -2390,7 +2390,7 @@ void vga_init_vbe(VGACommonState *s, MemoryRegion *system_memory)
/********************************************************/
/* vga screen dump */
-int ppm_save(const char *filename, struct DisplaySurface *ds)
+void ppm_save(const char *filename, struct DisplaySurface *ds, Error **errp)
{
FILE *f;
uint8_t *d, *d1;
@@ -2402,10 +2402,16 @@ int ppm_save(const char *filename, struct DisplaySurface *ds)
trace_ppm_save(filename, ds);
f = fopen(filename, "wb");
- if (!f)
- return -1;
- fprintf(f, "P6\n%d %d\n%d\n",
- ds->width, ds->height, 255);
+ if (!f) {
+ error_setg(errp, "failed to open file '%s': %s", filename,
+ strerror(errno));
+ return;
+ }
+ ret = fprintf(f, "P6\n%d %d\n%d\n", ds->width, ds->height, 255);
+ if (ret < 0) {
+ linebuf = NULL;
+ goto write_err;
+ }
linebuf = g_malloc(ds->width * 3);
d1 = ds->data;
for(y = 0; y < ds->height; y++) {
@@ -2426,12 +2432,24 @@ int ppm_save(const char *filename, struct DisplaySurface *ds)
d += ds->pf.bytes_per_pixel;
}
d1 += ds->linesize;
+ clearerr(f);
ret = fwrite(linebuf, 1, pbuf - linebuf, f);
(void)ret;
+ if (ferror(f)) {
+ goto write_err;
+ }
}
+
+out:
g_free(linebuf);
fclose(f);
- return 0;
+ return;
+
+write_err:
+ error_setg(errp, "failed to write to file '%s': %s", filename,
+ strerror(errno));
+ unlink(filename);
+ goto out;
}
/* save the vga display in a PPM image even if no display is
@@ -2445,5 +2463,5 @@ static void vga_screen_dump(void *opaque, const char *filename, bool cswitch,
vga_invalidate_display(s);
}
vga_hw_update();
- ppm_save(filename, s->ds->surface);
+ ppm_save(filename, s->ds->surface, errp);
}