From patchwork Mon Apr 5 12:45:34 2010 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Amit Shah X-Patchwork-Id: 49385 Return-Path: X-Original-To: incoming@patchwork.ozlabs.org Delivered-To: patchwork-incoming@bilbo.ozlabs.org Received: from lists.gnu.org (lists.gnu.org [199.232.76.165]) (using TLSv1 with cipher DHE-RSA-AES256-SHA (256/256 bits)) (Client did not present a certificate) by ozlabs.org (Postfix) with ESMTPS id 1306CB7CF3 for ; Mon, 5 Apr 2010 23:03:39 +1000 (EST) Received: from localhost ([127.0.0.1]:56491 helo=lists.gnu.org) by lists.gnu.org with esmtp (Exim 4.43) id 1Nyll1-0000aG-09 for incoming@patchwork.ozlabs.org; Mon, 05 Apr 2010 08:50:23 -0400 Received: from mailman by lists.gnu.org with tmda-scanned (Exim 4.43) id 1Nyli2-0000Br-Ve for qemu-devel@nongnu.org; Mon, 05 Apr 2010 08:47:19 -0400 Received: from [140.186.70.92] (port=47030 helo=eggs.gnu.org) by lists.gnu.org with esmtp (Exim 4.43) id 1Nyli0-0000Ac-LI for qemu-devel@nongnu.org; Mon, 05 Apr 2010 08:47:18 -0400 Received: from Debian-exim by eggs.gnu.org with spam-scanned (Exim 4.69) (envelope-from ) id 1Nylhx-0007ej-Kx for qemu-devel@nongnu.org; Mon, 05 Apr 2010 08:47:16 -0400 Received: from mx1.redhat.com ([209.132.183.28]:50316) by eggs.gnu.org with esmtp (Exim 4.69) (envelope-from ) id 1Nylhx-0007ee-7C for qemu-devel@nongnu.org; Mon, 05 Apr 2010 08:47:13 -0400 Received: from int-mx03.intmail.prod.int.phx2.redhat.com (int-mx03.intmail.prod.int.phx2.redhat.com [10.5.11.16]) by mx1.redhat.com (8.13.8/8.13.8) with ESMTP id o35ClBmA009987 (version=TLSv1/SSLv3 cipher=DHE-RSA-AES256-SHA bits=256 verify=OK); Mon, 5 Apr 2010 08:47:11 -0400 Received: from localhost (vpn-236-74.phx2.redhat.com [10.3.236.74]) by int-mx03.intmail.prod.int.phx2.redhat.com (8.13.8/8.13.8) with ESMTP id o35Cl85M017650; Mon, 5 Apr 2010 08:47:09 -0400 From: Amit Shah To: qemu list Date: Mon, 5 Apr 2010 18:15:34 +0530 Message-Id: <1270471538-31275-2-git-send-email-amit.shah@redhat.com> In-Reply-To: <1270471538-31275-1-git-send-email-amit.shah@redhat.com> References: <1270471538-31275-1-git-send-email-amit.shah@redhat.com> X-Scanned-By: MIMEDefang 2.67 on 10.5.11.16 X-detected-operating-system: by eggs.gnu.org: Genre and OS details not recognized. Cc: Amit Shah , Gerd Hoffmann , Juan Quintela Subject: [Qemu-devel] [PATCH 1/5] char: Let the caller know how many bytes were written in case of incomplete writes X-BeenThere: qemu-devel@nongnu.org X-Mailman-Version: 2.1.5 Precedence: list List-Id: qemu-devel.nongnu.org List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Sender: qemu-devel-bounces+incoming=patchwork.ozlabs.org@nongnu.org Errors-To: qemu-devel-bounces+incoming=patchwork.ozlabs.org@nongnu.org There might be cases where a few bytes would have been sent out to char devices and some not. Currently the return values from qemu_chr_write() to char devs are only -1, indicating an error, or the complete length of the string passed. Make 'len' a pointer instead, and indicate how much of the string was written. The return value will either be the same as 'len' or a negative number indicating an error condition. Signed-off-by: Amit Shah --- console.c | 10 +++--- gdbstub.c | 15 +++++--- hw/bt-hci-csr.c | 8 ++-- hw/debugcon.c | 5 ++- hw/msmouse.c | 5 ++- hw/parallel.c | 5 ++- hw/serial.c | 4 ++- hw/usb-serial.c | 4 +- hw/virtio-console.c | 2 +- monitor.c | 4 ++- net/socket.c | 7 +++- qemu-char.c | 96 +++++++++++++++++++++++++++++++------------------- qemu-char.h | 7 +++- qemu_socket.h | 2 +- slirp/slirp.c | 12 ++++--- 15 files changed, 114 insertions(+), 72 deletions(-) diff --git a/console.c b/console.c index 8bcd00b..058264c 100644 --- a/console.c +++ b/console.c @@ -1078,7 +1078,7 @@ void console_select(unsigned int index) } } -static int console_puts(CharDriverState *chr, const uint8_t *buf, int len) +static int console_puts(CharDriverState *chr, const uint8_t *buf, size_t *len) { TextConsole *s = chr->opaque; int i; @@ -1088,7 +1088,7 @@ static int console_puts(CharDriverState *chr, const uint8_t *buf, int len) s->update_x1 = 0; s->update_y1 = 0; console_show_cursor(s, 0); - for(i = 0; i < len; i++) { + for(i = 0; i < *len; i++) { console_putchar(s, buf[i]); } console_show_cursor(s, 1); @@ -1097,7 +1097,7 @@ static int console_puts(CharDriverState *chr, const uint8_t *buf, int len) s->update_x1 - s->update_x0, s->update_y1 - s->update_y0); } - return len; + return *len; } static void console_send_event(CharDriverState *chr, int event) @@ -1498,11 +1498,11 @@ static void text_console_do_init(CharDriverState *chr, DisplayState *ds, QemuOpt if (chr->label) { char msg[128]; - int len; + size_t len; s->t_attrib.bgcol = COLOR_BLUE; len = snprintf(msg, sizeof(msg), "%s console\r\n", chr->label); - console_puts(chr, (uint8_t*)msg, len); + console_puts(chr, (uint8_t*)msg, &len); s->t_attrib = s->t_attrib_default; } diff --git a/gdbstub.c b/gdbstub.c index 93c4850..1af8c17 100644 --- a/gdbstub.c +++ b/gdbstub.c @@ -376,7 +376,9 @@ static void put_buffer(GDBState *s, const uint8_t *buf, int len) } } #else - qemu_chr_write(s->chr, buf, len); + size_t tmplen = len; + + qemu_chr_write(s->chr, buf, &tmplen); #endif } @@ -2595,22 +2597,23 @@ static void gdb_monitor_output(GDBState *s, const char *msg, int len) put_packet(s, buf); } -static int gdb_monitor_write(CharDriverState *chr, const uint8_t *buf, int len) +static int gdb_monitor_write(CharDriverState *chr, const uint8_t *buf, + size_t *len) { const char *p = (const char *)buf; int max_sz; max_sz = (sizeof(gdbserver_state->last_packet) - 2) / 2; for (;;) { - if (len <= max_sz) { - gdb_monitor_output(gdbserver_state, p, len); + if (*len <= max_sz) { + gdb_monitor_output(gdbserver_state, p, *len); break; } gdb_monitor_output(gdbserver_state, p, max_sz); p += max_sz; - len -= max_sz; + *len -= max_sz; } - return len; + return *len; } #ifndef _WIN32 diff --git a/hw/bt-hci-csr.c b/hw/bt-hci-csr.c index 7300ea6..741c8ff 100644 --- a/hw/bt-hci-csr.c +++ b/hw/bt-hci-csr.c @@ -296,7 +296,7 @@ static int csrhci_data_len(const uint8_t *pkt) } static int csrhci_write(struct CharDriverState *chr, - const uint8_t *buf, int len) + const uint8_t *buf, size_t *len) { struct csrhci_s *s = (struct csrhci_s *) chr->opaque; int plen = s->in_len; @@ -304,8 +304,8 @@ static int csrhci_write(struct CharDriverState *chr, if (!s->enable) return 0; - s->in_len += len; - memcpy(s->inpkt + plen, buf, len); + s->in_len += *len; + memcpy(s->inpkt + plen, buf, *len); while (1) { if (s->in_len >= 2 && plen < 2) @@ -326,7 +326,7 @@ static int csrhci_write(struct CharDriverState *chr, break; } - return len; + return *len; } static void csrhci_out_hci_packet_event(void *opaque, diff --git a/hw/debugcon.c b/hw/debugcon.c index d549091..88cca11 100644 --- a/hw/debugcon.c +++ b/hw/debugcon.c @@ -46,15 +46,16 @@ static void debugcon_ioport_write(void *opaque, uint32_t addr, uint32_t val) { DebugconState *s = opaque; unsigned char ch = val; + size_t tmplen; #ifdef DEBUG_DEBUGCON printf("debugcon: write addr=0x%04x val=0x%02x\n", addr, val); #endif - qemu_chr_write(s->chr, &ch, 1); + tmplen = 1; + qemu_chr_write(s->chr, &ch, &tmplen); } - static uint32_t debugcon_ioport_read(void *opaque, uint32_t addr) { DebugconState *s = opaque; diff --git a/hw/msmouse.c b/hw/msmouse.c index 05f893c..68a848a 100644 --- a/hw/msmouse.c +++ b/hw/msmouse.c @@ -53,10 +53,11 @@ static void msmouse_event(void *opaque, qemu_chr_read(chr, bytes, 4); } -static int msmouse_chr_write (struct CharDriverState *s, const uint8_t *buf, int len) +static int msmouse_chr_write (struct CharDriverState *s, const uint8_t *buf, + size_t *len) { /* Ignore writes to mouse port */ - return len; + return *len; } static void msmouse_chr_close (struct CharDriverState *chr) diff --git a/hw/parallel.c b/hw/parallel.c index 12693d4..b9055ab 100644 --- a/hw/parallel.c +++ b/hw/parallel.c @@ -116,10 +116,13 @@ parallel_ioport_write_sw(void *opaque, uint32_t addr, uint32_t val) s->status |= PARA_STS_ERROR; } else if (val & PARA_CTR_SELECT) { + size_t tmplen; + + tmplen = 1; if (val & PARA_CTR_STROBE) { s->status &= ~PARA_STS_BUSY; if ((s->control & PARA_CTR_STROBE) == 0) - qemu_chr_write(s->chr, &s->dataw, 1); + qemu_chr_write(s->chr, &s->dataw, &tmplen); } else { if (s->control & PARA_CTR_INTEN) { s->irq_pending = 1; diff --git a/hw/serial.c b/hw/serial.c index 90213c4..8d69a4a 100644 --- a/hw/serial.c +++ b/hw/serial.c @@ -311,6 +311,7 @@ static void serial_xmit(void *opaque) { SerialState *s = opaque; uint64_t new_xmit_ts = qemu_get_clock(vm_clock); + size_t tmplen; if (s->tsr_retry <= 0) { if (s->fcr & UART_FCR_FE) { @@ -323,10 +324,11 @@ static void serial_xmit(void *opaque) } } + tmplen = 1; if (s->mcr & UART_MCR_LOOP) { /* in loopback mode, say that we just received a char */ serial_receive1(s, &s->tsr, 1); - } else if (qemu_chr_write(s->chr, &s->tsr, 1) != 1) { + } else if (qemu_chr_write(s->chr, &s->tsr, &tmplen) != 1) { if ((s->tsr_retry > 0) && (s->tsr_retry <= MAX_XMIT_RETRY)) { s->tsr_retry++; qemu_mod_timer(s->transmit_timer, new_xmit_ts + s->char_transmit_time); diff --git a/hw/usb-serial.c b/hw/usb-serial.c index 69f0e44..4b3eaa9 100644 --- a/hw/usb-serial.c +++ b/hw/usb-serial.c @@ -426,14 +426,14 @@ static int usb_serial_handle_data(USBDevice *dev, USBPacket *p) int ret = 0; uint8_t devep = p->devep; uint8_t *data = p->data; - int len = p->len; + size_t len = p->len; int first_len; switch (p->pid) { case USB_TOKEN_OUT: if (devep != 2) goto fail; - qemu_chr_write(s->cs, data, len); + qemu_chr_write(s->cs, data, &len); break; case USB_TOKEN_IN: diff --git a/hw/virtio-console.c b/hw/virtio-console.c index caea11f..144efce 100644 --- a/hw/virtio-console.c +++ b/hw/virtio-console.c @@ -24,7 +24,7 @@ static void flush_buf(VirtIOSerialPort *port, const uint8_t *buf, size_t len) { VirtConsole *vcon = DO_UPCAST(VirtConsole, port, port); - qemu_chr_write(vcon->chr, buf, len); + qemu_chr_write(vcon->chr, buf, &len); } /* Readiness of the guest to accept data on a port */ diff --git a/monitor.c b/monitor.c index f1b4e6b..4a0e1b6 100644 --- a/monitor.c +++ b/monitor.c @@ -232,7 +232,9 @@ static int monitor_read_password(Monitor *mon, ReadLineFunc *readline_func, void monitor_flush(Monitor *mon) { if (mon && mon->outbuf_index != 0 && !mon->mux_out) { - qemu_chr_write(mon->chr, mon->outbuf, mon->outbuf_index); + size_t tmplen = mon->outbuf_index; + + qemu_chr_write(mon->chr, mon->outbuf, &tmplen); mon->outbuf_index = 0; } } diff --git a/net/socket.c b/net/socket.c index 1c4e153..f1337fa 100644 --- a/net/socket.c +++ b/net/socket.c @@ -54,10 +54,13 @@ static ssize_t net_socket_receive(VLANClientState *nc, const uint8_t *buf, size_ { NetSocketState *s = DO_UPCAST(NetSocketState, nc, nc); uint32_t len; + size_t len_len; + len = htonl(size); + len_len = sizeof(len); - send_all(s->fd, (const uint8_t *)&len, sizeof(len)); - return send_all(s->fd, buf, size); + send_all(s->fd, (const uint8_t *)&len, &len_len); + return send_all(s->fd, buf, &size); } static ssize_t net_socket_receive_dgram(VLANClientState *nc, const uint8_t *buf, size_t size) diff --git a/qemu-char.c b/qemu-char.c index 048da3f..d5b1662 100644 --- a/qemu-char.c +++ b/qemu-char.c @@ -130,7 +130,7 @@ void qemu_chr_generic_open(CharDriverState *s) } } -int qemu_chr_write(CharDriverState *s, const uint8_t *buf, int len) +int qemu_chr_write(CharDriverState *s, const uint8_t *buf, size_t *len) { return s->chr_write(s, buf, len); } @@ -169,9 +169,12 @@ void qemu_chr_printf(CharDriverState *s, const char *fmt, ...) { char buf[READ_BUF_LEN]; va_list ap; + size_t len; + va_start(ap, fmt); vsnprintf(buf, sizeof(buf), fmt, ap); - qemu_chr_write(s, (uint8_t *)buf, strlen(buf)); + len = strlen(buf); + qemu_chr_write(s, (uint8_t *)buf, &len); va_end(ap); } @@ -195,9 +198,9 @@ void qemu_chr_add_handlers(CharDriverState *s, s->chr_update_read_handler(s); } -static int null_chr_write(CharDriverState *chr, const uint8_t *buf, int len) +static int null_chr_write(CharDriverState *chr, const uint8_t *buf, size_t *len) { - return len; + return *len; } static CharDriverState *qemu_chr_open_null(QemuOpts *opts) @@ -235,7 +238,7 @@ typedef struct { } MuxDriver; -static int mux_chr_write(CharDriverState *chr, const uint8_t *buf, int len) +static int mux_chr_write(CharDriverState *chr, const uint8_t *buf, size_t *len) { MuxDriver *d = chr->opaque; int ret; @@ -245,7 +248,9 @@ static int mux_chr_write(CharDriverState *chr, const uint8_t *buf, int len) int i; ret = 0; - for (i = 0; i < len; i++) { + for (i = 0; i < *len; i++) { + size_t tmplen; + if (d->linestart) { char buf1[64]; int64_t ti; @@ -262,10 +267,12 @@ static int mux_chr_write(CharDriverState *chr, const uint8_t *buf, int len) (secs / 60) % 60, secs % 60, (int)(ti % 1000)); - d->drv->chr_write(d->drv, (uint8_t *)buf1, strlen(buf1)); + tmplen = strlen(buf1); + d->drv->chr_write(d->drv, (uint8_t *)buf1, &tmplen); d->linestart = 0; } - ret += d->drv->chr_write(d->drv, buf+i, 1); + tmplen = 1; + ret += d->drv->chr_write(d->drv, buf+i, &tmplen); if (buf[i] == '\n') { d->linestart = 1; } @@ -291,6 +298,7 @@ static void mux_print_help(CharDriverState *chr) int i, j; char ebuf[15] = "Escape-Char"; char cbuf[50] = "\n\r"; + size_t tmplen; if (term_escape_char > 0 && term_escape_char < 26) { snprintf(cbuf, sizeof(cbuf), "\n\r"); @@ -300,13 +308,18 @@ static void mux_print_help(CharDriverState *chr) "\n\rEscape-Char set to Ascii: 0x%02x\n\r\n\r", term_escape_char); } - chr->chr_write(chr, (uint8_t *)cbuf, strlen(cbuf)); + tmplen = strlen(cbuf); + chr->chr_write(chr, (uint8_t *)cbuf, &tmplen); for (i = 0; mux_help[i] != NULL; i++) { for (j=0; mux_help[i][j] != '\0'; j++) { - if (mux_help[i][j] == '%') - chr->chr_write(chr, (uint8_t *)ebuf, strlen(ebuf)); - else - chr->chr_write(chr, (uint8_t *)&mux_help[i][j], 1); + + if (mux_help[i][j] == '%') { + tmplen = strlen(ebuf); + chr->chr_write(chr, (uint8_t *)ebuf, &tmplen); + } else { + tmplen = 1; + chr->chr_write(chr, (uint8_t *)&mux_help[i][j], &tmplen); + } } } } @@ -331,7 +344,9 @@ static int mux_proc_byte(CharDriverState *chr, MuxDriver *d, int ch) case 'x': { const char *term = "QEMU: Terminated\n\r"; - chr->chr_write(chr,(uint8_t *)term,strlen(term)); + size_t tmplen = strlen(term); + + chr->chr_write(chr, (uint8_t *)term, &tmplen); exit(0); break; } @@ -470,13 +485,14 @@ static CharDriverState *qemu_chr_open_mux(CharDriverState *drv) #ifdef _WIN32 -int send_all(int fd, const void *buf, int len1) +int send_all(int fd, const void *buf, size_t *len) { - int ret, len; + ssize_t tmplen, ret; - len = len1; - while (len > 0) { - ret = send(fd, buf, len, 0); + tmplen = *len; + *len = 0; + while (tmplen > 0) { + ret = send(fd, buf, tmplen, 0); if (ret < 0) { errno = WSAGetLastError(); if (errno != WSAEWOULDBLOCK) { @@ -486,7 +502,8 @@ int send_all(int fd, const void *buf, int len1) break; } else { buf += ret; - len -= ret; + *len += ret; + tmplen -= ret; } } return len1 - len; @@ -494,13 +511,14 @@ int send_all(int fd, const void *buf, int len1) #else -static int unix_write(int fd, const uint8_t *buf, int len1) +static int unix_write(int fd, const uint8_t *buf, size_t *len) { - int ret, len; + ssize_t tmplen, ret; - len = len1; - while (len > 0) { - ret = write(fd, buf, len); + tmplen = *len; + *len = 0; + while (tmplen > 0) { + ret = write(fd, buf, tmplen); if (ret < 0) { if (errno != EINTR && errno != EAGAIN) return -1; @@ -508,15 +526,16 @@ static int unix_write(int fd, const uint8_t *buf, int len1) break; } else { buf += ret; - len -= ret; + *len += ret; + tmplen -= ret; } } - return len1 - len; + return *len; } -int send_all(int fd, const void *buf, int len1) +int send_all(int fd, const void *buf, size_t *len) { - return unix_write(fd, buf, len1); + return unix_write(fd, buf, len); } #endif /* !_WIN32 */ @@ -530,7 +549,7 @@ typedef struct { #define STDIO_MAX_CLIENTS 1 static int stdio_nb_clients = 0; -static int fd_chr_write(CharDriverState *chr, const uint8_t *buf, int len) +static int fd_chr_write(CharDriverState *chr, const uint8_t *buf, size_t *len) { FDCharDriver *s = chr->opaque; return send_all(s->fd_out, buf, len); @@ -836,7 +855,7 @@ typedef struct { static void pty_chr_update_read_handler(CharDriverState *chr); static void pty_chr_state(CharDriverState *chr, int connected); -static int pty_chr_write(CharDriverState *chr, const uint8_t *buf, int len) +static int pty_chr_write(CharDriverState *chr, const uint8_t *buf, size_t *len) { PtyCharDriver *s = chr->opaque; @@ -1791,11 +1810,11 @@ typedef struct { int max_size; } NetCharDriver; -static int udp_chr_write(CharDriverState *chr, const uint8_t *buf, int len) +static int udp_chr_write(CharDriverState *chr, const uint8_t *buf, size_t *len) { NetCharDriver *s = chr->opaque; - return send(s->fd, (const void *)buf, len, 0); + return send(s->fd, (const void *)buf, *len, 0); } static int udp_chr_read_poll(void *opaque) @@ -1906,14 +1925,14 @@ typedef struct { static void tcp_chr_accept(void *opaque); -static int tcp_chr_write(CharDriverState *chr, const uint8_t *buf, int len) +static int tcp_chr_write(CharDriverState *chr, const uint8_t *buf, size_t *len) { TCPCharDriver *s = chr->opaque; if (s->connected) { return send_all(s->fd, buf, len); } else { /* XXX: indicate an error ? */ - return len; + return *len; } } @@ -2201,8 +2220,9 @@ static CharDriverState *qemu_chr_open_socket(QemuOpts *opts) if (fd < 0) goto fail; - if (!is_waitconnect) + if (!is_waitconnect) { socket_set_nonblock(fd); + } s->connected = 0; s->fd = -1; @@ -2225,7 +2245,9 @@ static CharDriverState *qemu_chr_open_socket(QemuOpts *opts) } else { s->connected = 1; s->fd = fd; - socket_set_nodelay(fd); + if (s->do_nodelay) { + socket_set_nodelay(fd); + } tcp_chr_connect(chr); } diff --git a/qemu-char.h b/qemu-char.h index 3a9427b..8d964f0 100644 --- a/qemu-char.h +++ b/qemu-char.h @@ -1,6 +1,8 @@ #ifndef QEMU_CHAR_H #define QEMU_CHAR_H +#include + #include "qemu-common.h" #include "qemu-queue.h" #include "qemu-option.h" @@ -52,7 +54,7 @@ typedef void IOEventHandler(void *opaque, int event); struct CharDriverState { void (*init)(struct CharDriverState *s); - int (*chr_write)(struct CharDriverState *s, const uint8_t *buf, int len); + int (*chr_write)(struct CharDriverState *s, const uint8_t *buf, size_t *len); void (*chr_update_read_handler)(struct CharDriverState *s); int (*chr_ioctl)(struct CharDriverState *s, int cmd, void *arg); int (*get_msgfd)(struct CharDriverState *s); @@ -67,6 +69,7 @@ struct CharDriverState { QEMUBH *bh; char *label; char *filename; + bool nonblock; QTAILQ_ENTRY(CharDriverState) next; }; @@ -76,7 +79,7 @@ CharDriverState *qemu_chr_open_opts(QemuOpts *opts, CharDriverState *qemu_chr_open(const char *label, const char *filename, void (*init)(struct CharDriverState *s)); void qemu_chr_close(CharDriverState *chr); void qemu_chr_printf(CharDriverState *s, const char *fmt, ...); -int qemu_chr_write(CharDriverState *s, const uint8_t *buf, int len); +int qemu_chr_write(CharDriverState *s, const uint8_t *buf, size_t *len); void qemu_chr_send_event(CharDriverState *s, int event); void qemu_chr_add_handlers(CharDriverState *s, IOCanReadHandler *fd_can_read, diff --git a/qemu_socket.h b/qemu_socket.h index 7ee46ac..004b104 100644 --- a/qemu_socket.h +++ b/qemu_socket.h @@ -35,7 +35,7 @@ int inet_aton(const char *cp, struct in_addr *ia); int qemu_socket(int domain, int type, int protocol); int qemu_accept(int s, struct sockaddr *addr, socklen_t *addrlen); void socket_set_nonblock(int fd); -int send_all(int fd, const void *buf, int len1); +int send_all(int fd, const void *buf, size_t *len); /* New, ipv6-ready socket helper functions, see qemu-sockets.c */ int inet_listen_opts(QemuOpts *opts, int port_offset); diff --git a/slirp/slirp.c b/slirp/slirp.c index 3c785cd..572b109 100644 --- a/slirp/slirp.c +++ b/slirp/slirp.c @@ -798,12 +798,14 @@ int slirp_add_exec(Slirp *slirp, int do_pty, const void *args, ssize_t slirp_send(struct socket *so, const void *buf, size_t len, int flags) { - if (so->s == -1 && so->extra) { - qemu_chr_write(so->extra, buf, len); - return len; - } + if (so->s == -1 && so->extra) { + size_t tmplen = len; + + qemu_chr_write(so->extra, buf, &tmplen); + return len; + } - return send(so->s, buf, len, flags); + return send(so->s, buf, len, flags); } static struct socket *