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 <stdbool.h>
+
 #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 *
