X-Git-Url: https://git.proxmox.com/?a=blobdiff_plain;f=buffered_file.c;h=f170aa046f507571fc65490b3820bcc28407b264;hb=a4d8e8daee324e230b0155915f562743f4fff5d8;hp=b5e2baff46be925646a9f35ae4af2f58bf8f2ba7;hpb=56d7a964a5664d3778a0b7a369a5f350d0fe099f;p=qemu.git diff --git a/buffered_file.c b/buffered_file.c index b5e2baff4..f170aa046 100644 --- a/buffered_file.c +++ b/buffered_file.c @@ -9,12 +9,13 @@ * This work is licensed under the terms of the GNU GPL, version 2. See * the COPYING file in the top-level directory. * + * Contributions after 2012-01-13 are licensed under the terms of the + * GNU GPL, version 2 or (at your option) any later version. */ #include "qemu-common.h" #include "hw/hw.h" #include "qemu-timer.h" -#include "sysemu.h" #include "qemu-char.h" #include "buffered_file.h" @@ -28,7 +29,6 @@ typedef struct QEMUFileBuffered BufferedCloseFunc *close; void *opaque; QEMUFile *file; - int has_error; int freeze_output; size_t bytes_xfer; size_t xfer_limit; @@ -57,7 +57,7 @@ static void buffered_append(QEMUFileBuffered *s, s->buffer_capacity += size + 1024; - tmp = qemu_realloc(s->buffer, s->buffer_capacity); + tmp = g_realloc(s->buffer, s->buffer_capacity); if (tmp == NULL) { fprintf(stderr, "qemu file buffer expansion failed\n"); exit(1); @@ -73,9 +73,11 @@ static void buffered_append(QEMUFileBuffered *s, static void buffered_flush(QEMUFileBuffered *s) { size_t offset = 0; + int error; - if (s->has_error) { - DPRINTF("flush when error, bailing\n"); + error = qemu_file_get_error(s->file); + if (error != 0) { + DPRINTF("flush when error, bailing: %s\n", strerror(-error)); return; } @@ -94,7 +96,7 @@ static void buffered_flush(QEMUFileBuffered *s) if (ret <= 0) { DPRINTF("error flushing data, %zd\n", ret); - s->has_error = 1; + qemu_file_set_error(s->file, ret); break; } else { DPRINTF("flushed %zd byte(s)\n", ret); @@ -110,14 +112,15 @@ static void buffered_flush(QEMUFileBuffered *s) static int buffered_put_buffer(void *opaque, const uint8_t *buf, int64_t pos, int size) { QEMUFileBuffered *s = opaque; - int offset = 0; + int offset = 0, error; ssize_t ret; DPRINTF("putting %d bytes at %" PRId64 "\n", size, pos); - if (s->has_error) { - DPRINTF("flush when error, bailing\n"); - return -EINVAL; + error = qemu_file_get_error(s->file); + if (error) { + DPRINTF("flush when error, bailing: %s\n", strerror(-error)); + return error; } DPRINTF("unfreezing output\n"); @@ -140,7 +143,7 @@ static int buffered_put_buffer(void *opaque, const uint8_t *buf, int64_t pos, in if (ret <= 0) { DPRINTF("error putting\n"); - s->has_error = 1; + qemu_file_set_error(s->file, ret); offset = -EINVAL; break; } @@ -174,29 +177,37 @@ static int buffered_close(void *opaque) DPRINTF("closing\n"); - while (!s->has_error && s->buffer_size) { + while (!qemu_file_get_error(s->file) && s->buffer_size) { buffered_flush(s); if (s->freeze_output) - s->wait_for_unfreeze(s); + s->wait_for_unfreeze(s->opaque); } ret = s->close(s->opaque); qemu_del_timer(s->timer); qemu_free_timer(s->timer); - qemu_free(s->buffer); - qemu_free(s); + g_free(s->buffer); + g_free(s); return ret; } +/* + * The meaning of the return values is: + * 0: We can continue sending + * 1: Time to stop + * negative: There has been an error + */ static int buffered_rate_limit(void *opaque) { QEMUFileBuffered *s = opaque; + int ret; - if (s->has_error) - return 0; - + ret = qemu_file_get_error(s->file); + if (ret) { + return ret; + } if (s->freeze_output) return 1; @@ -209,9 +220,9 @@ static int buffered_rate_limit(void *opaque) static int64_t buffered_set_rate_limit(void *opaque, int64_t new_rate) { QEMUFileBuffered *s = opaque; - if (s->has_error) + if (qemu_file_get_error(s->file)) { goto out; - + } if (new_rate > SIZE_MAX) { new_rate = SIZE_MAX; } @@ -233,7 +244,7 @@ static void buffered_rate_tick(void *opaque) { QEMUFileBuffered *s = opaque; - if (s->has_error) { + if (qemu_file_get_error(s->file)) { buffered_close(s); return; } @@ -260,7 +271,7 @@ QEMUFile *qemu_fopen_ops_buffered(void *opaque, { QEMUFileBuffered *s; - s = qemu_mallocz(sizeof(*s)); + s = g_malloc0(sizeof(*s)); s->opaque = opaque; s->xfer_limit = bytes_per_sec / 10;