Diff for /qemu/qemu-char.c between versions 1.1.1.11 and 1.1.1.12

version 1.1.1.11, 2018/04/24 18:56:03 version 1.1.1.12, 2018/04/24 19:17:07
Line 31 Line 31
 #include "hw/usb.h"  #include "hw/usb.h"
 #include "hw/baum.h"  #include "hw/baum.h"
 #include "hw/msmouse.h"  #include "hw/msmouse.h"
 #include "qemu-objects.h"  #include "qmp-commands.h"
   
 #include <unistd.h>  #include <unistd.h>
 #include <fcntl.h>  #include <fcntl.h>
Line 106 Line 106
 static QTAILQ_HEAD(CharDriverStateHead, CharDriverState) chardevs =  static QTAILQ_HEAD(CharDriverStateHead, CharDriverState) chardevs =
     QTAILQ_HEAD_INITIALIZER(chardevs);      QTAILQ_HEAD_INITIALIZER(chardevs);
   
 static void qemu_chr_event(CharDriverState *s, int event)  void qemu_chr_be_event(CharDriverState *s, int event)
 {  {
     /* Keep track if the char device is open */      /* Keep track if the char device is open */
     switch (event) {      switch (event) {
Line 126  static void qemu_chr_event(CharDriverSta Line 126  static void qemu_chr_event(CharDriverSta
 static void qemu_chr_generic_open_bh(void *opaque)  static void qemu_chr_generic_open_bh(void *opaque)
 {  {
     CharDriverState *s = opaque;      CharDriverState *s = opaque;
     qemu_chr_event(s, CHR_EVENT_OPENED);      qemu_chr_be_event(s, CHR_EVENT_OPENED);
     qemu_bh_delete(s->bh);      qemu_bh_delete(s->bh);
     s->bh = NULL;      s->bh = NULL;
 }  }
Line 139  void qemu_chr_generic_open(CharDriverSta Line 139  void qemu_chr_generic_open(CharDriverSta
     }      }
 }  }
   
 int qemu_chr_write(CharDriverState *s, const uint8_t *buf, int len)  int qemu_chr_fe_write(CharDriverState *s, const uint8_t *buf, int len)
 {  {
     return s->chr_write(s, buf, len);      return s->chr_write(s, buf, len);
 }  }
   
 int qemu_chr_ioctl(CharDriverState *s, int cmd, void *arg)  int qemu_chr_fe_ioctl(CharDriverState *s, int cmd, void *arg)
 {  {
     if (!s->chr_ioctl)      if (!s->chr_ioctl)
         return -ENOTSUP;          return -ENOTSUP;
     return s->chr_ioctl(s, cmd, arg);      return s->chr_ioctl(s, cmd, arg);
 }  }
   
 int qemu_chr_can_read(CharDriverState *s)  int qemu_chr_be_can_write(CharDriverState *s)
 {  {
     if (!s->chr_can_read)      if (!s->chr_can_read)
         return 0;          return 0;
     return s->chr_can_read(s->handler_opaque);      return s->chr_can_read(s->handler_opaque);
 }  }
   
 void qemu_chr_read(CharDriverState *s, uint8_t *buf, int len)  void qemu_chr_be_write(CharDriverState *s, uint8_t *buf, int len)
 {  {
     s->chr_read(s->handler_opaque, buf, len);      s->chr_read(s->handler_opaque, buf, len);
 }  }
   
 int qemu_chr_get_msgfd(CharDriverState *s)  int qemu_chr_fe_get_msgfd(CharDriverState *s)
 {  {
     return s->get_msgfd ? s->get_msgfd(s) : -1;      return s->get_msgfd ? s->get_msgfd(s) : -1;
 }  }
Line 179  void qemu_chr_accept_input(CharDriverSta Line 179  void qemu_chr_accept_input(CharDriverSta
         s->chr_accept_input(s);          s->chr_accept_input(s);
 }  }
   
 void qemu_chr_printf(CharDriverState *s, const char *fmt, ...)  void qemu_chr_fe_printf(CharDriverState *s, const char *fmt, ...)
 {  {
     char buf[READ_BUF_LEN];      char buf[READ_BUF_LEN];
     va_list ap;      va_list ap;
     va_start(ap, fmt);      va_start(ap, fmt);
     vsnprintf(buf, sizeof(buf), fmt, ap);      vsnprintf(buf, sizeof(buf), fmt, ap);
     qemu_chr_write(s, (uint8_t *)buf, strlen(buf));      qemu_chr_fe_write(s, (uint8_t *)buf, strlen(buf));
     va_end(ap);      va_end(ap);
 }  }
   
 void qemu_chr_send_event(CharDriverState *s, int event)  
 {  
     if (s->chr_send_event)  
         s->chr_send_event(s, event);  
 }  
   
 void qemu_chr_add_handlers(CharDriverState *s,  void qemu_chr_add_handlers(CharDriverState *s,
                            IOCanReadHandler *fd_can_read,                             IOCanReadHandler *fd_can_read,
                            IOReadHandler *fd_read,                             IOReadHandler *fd_read,
Line 228  static int qemu_chr_open_null(QemuOpts * Line 222  static int qemu_chr_open_null(QemuOpts *
 {  {
     CharDriverState *chr;      CharDriverState *chr;
   
     chr = qemu_mallocz(sizeof(CharDriverState));      chr = g_malloc0(sizeof(CharDriverState));
     chr->chr_write = null_chr_write;      chr->chr_write = null_chr_write;
   
     *_chr= chr;      *_chr= chr;
Line 365  static int mux_proc_byte(CharDriverState Line 359  static int mux_proc_byte(CharDriverState
             bdrv_commit_all();              bdrv_commit_all();
             break;              break;
         case 'b':          case 'b':
             qemu_chr_event(chr, CHR_EVENT_BREAK);              qemu_chr_be_event(chr, CHR_EVENT_BREAK);
             break;              break;
         case 'c':          case 'c':
             /* Switch to the next registered device */              /* Switch to the next registered device */
Line 477  static CharDriverState *qemu_chr_open_mu Line 471  static CharDriverState *qemu_chr_open_mu
     CharDriverState *chr;      CharDriverState *chr;
     MuxDriver *d;      MuxDriver *d;
   
     chr = qemu_mallocz(sizeof(CharDriverState));      chr = g_malloc0(sizeof(CharDriverState));
     d = qemu_mallocz(sizeof(MuxDriver));      d = g_malloc0(sizeof(MuxDriver));
   
     chr->opaque = d;      chr->opaque = d;
     d->drv = drv;      d->drv = drv;
Line 544  int send_all(int fd, const void *_buf, i Line 538  int send_all(int fd, const void *_buf, i
 }  }
 #endif /* !_WIN32 */  #endif /* !_WIN32 */
   
   #define STDIO_MAX_CLIENTS 1
   static int stdio_nb_clients;
   
 #ifndef _WIN32  #ifndef _WIN32
   
 typedef struct {  typedef struct {
Line 551  typedef struct { Line 548  typedef struct {
     int max_size;      int max_size;
 } FDCharDriver;  } FDCharDriver;
   
 #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, int len)
 {  {
Line 565  static int fd_chr_read_poll(void *opaque Line 560  static int fd_chr_read_poll(void *opaque
     CharDriverState *chr = opaque;      CharDriverState *chr = opaque;
     FDCharDriver *s = chr->opaque;      FDCharDriver *s = chr->opaque;
   
     s->max_size = qemu_chr_can_read(chr);      s->max_size = qemu_chr_be_can_write(chr);
     return s->max_size;      return s->max_size;
 }  }
   
Line 585  static void fd_chr_read(void *opaque) Line 580  static void fd_chr_read(void *opaque)
     if (size == 0) {      if (size == 0) {
         /* FD has been closed. Remove it from the active list.  */          /* FD has been closed. Remove it from the active list.  */
         qemu_set_fd_handler2(s->fd_in, NULL, NULL, NULL, NULL);          qemu_set_fd_handler2(s->fd_in, NULL, NULL, NULL, NULL);
         qemu_chr_event(chr, CHR_EVENT_CLOSED);          qemu_chr_be_event(chr, CHR_EVENT_CLOSED);
         return;          return;
     }      }
     if (size > 0) {      if (size > 0) {
         qemu_chr_read(chr, buf, size);          qemu_chr_be_write(chr, buf, size);
     }      }
 }  }
   
Line 617  static void fd_chr_close(struct CharDriv Line 612  static void fd_chr_close(struct CharDriv
         }          }
     }      }
   
     qemu_free(s);      g_free(s);
     qemu_chr_event(chr, CHR_EVENT_CLOSED);      qemu_chr_be_event(chr, CHR_EVENT_CLOSED);
 }  }
   
 /* open a character device to a unix fd */  /* open a character device to a unix fd */
Line 627  static CharDriverState *qemu_chr_open_fd Line 622  static CharDriverState *qemu_chr_open_fd
     CharDriverState *chr;      CharDriverState *chr;
     FDCharDriver *s;      FDCharDriver *s;
   
     chr = qemu_mallocz(sizeof(CharDriverState));      chr = g_malloc0(sizeof(CharDriverState));
     s = qemu_mallocz(sizeof(FDCharDriver));      s = g_malloc0(sizeof(FDCharDriver));
     s->fd_in = fd_in;      s->fd_in = fd_in;
     s->fd_out = fd_out;      s->fd_out = fd_out;
     chr->opaque = s;      chr->opaque = s;
Line 699  static int stdio_read_poll(void *opaque) Line 694  static int stdio_read_poll(void *opaque)
     CharDriverState *chr = opaque;      CharDriverState *chr = opaque;
   
     /* try to flush the queue if needed */      /* try to flush the queue if needed */
     if (term_fifo_size != 0 && qemu_chr_can_read(chr) > 0) {      if (term_fifo_size != 0 && qemu_chr_be_can_write(chr) > 0) {
         qemu_chr_read(chr, term_fifo, 1);          qemu_chr_be_write(chr, term_fifo, 1);
         term_fifo_size = 0;          term_fifo_size = 0;
     }      }
     /* see if we can absorb more chars */      /* see if we can absorb more chars */
Line 720  static void stdio_read(void *opaque) Line 715  static void stdio_read(void *opaque)
     if (size == 0) {      if (size == 0) {
         /* stdin has been closed. Remove it from the active list.  */          /* stdin has been closed. Remove it from the active list.  */
         qemu_set_fd_handler2(0, NULL, NULL, NULL, NULL);          qemu_set_fd_handler2(0, NULL, NULL, NULL, NULL);
         qemu_chr_event(chr, CHR_EVENT_CLOSED);          qemu_chr_be_event(chr, CHR_EVENT_CLOSED);
         return;          return;
     }      }
     if (size > 0) {      if (size > 0) {
         if (qemu_chr_can_read(chr) > 0) {          if (qemu_chr_be_can_write(chr) > 0) {
             qemu_chr_read(chr, buf, 1);              qemu_chr_be_write(chr, buf, 1);
         } else if (term_fifo_size == 0) {          } else if (term_fifo_size == 0) {
             term_fifo[term_fifo_size++] = buf[0];              term_fifo[term_fifo_size++] = buf[0];
         }          }
Line 795  static int qemu_chr_open_stdio(QemuOpts  Line 790  static int qemu_chr_open_stdio(QemuOpts 
     stdio_nb_clients++;      stdio_nb_clients++;
     stdio_allow_signal = qemu_opt_get_bool(opts, "signal",      stdio_allow_signal = qemu_opt_get_bool(opts, "signal",
                                            display_type != DT_NOGRAPHIC);                                             display_type != DT_NOGRAPHIC);
     qemu_chr_set_echo(chr, false);      qemu_chr_fe_set_echo(chr, false);
   
     *_chr = chr;      *_chr = chr;
     return 0;      return 0;
Line 890  static int pty_chr_read_poll(void *opaqu Line 885  static int pty_chr_read_poll(void *opaqu
     CharDriverState *chr = opaque;      CharDriverState *chr = opaque;
     PtyCharDriver *s = chr->opaque;      PtyCharDriver *s = chr->opaque;
   
     s->read_bytes = qemu_chr_can_read(chr);      s->read_bytes = qemu_chr_be_can_write(chr);
     return s->read_bytes;      return s->read_bytes;
 }  }
   
Line 914  static void pty_chr_read(void *opaque) Line 909  static void pty_chr_read(void *opaque)
     }      }
     if (size > 0) {      if (size > 0) {
         pty_chr_state(chr, 1);          pty_chr_state(chr, 1);
         qemu_chr_read(chr, buf, size);          qemu_chr_be_write(chr, buf, size);
     }      }
 }  }
   
Line 981  static void pty_chr_close(struct CharDri Line 976  static void pty_chr_close(struct CharDri
     close(s->fd);      close(s->fd);
     qemu_del_timer(s->timer);      qemu_del_timer(s->timer);
     qemu_free_timer(s->timer);      qemu_free_timer(s->timer);
     qemu_free(s);      g_free(s);
     qemu_chr_event(chr, CHR_EVENT_CLOSED);      qemu_chr_be_event(chr, CHR_EVENT_CLOSED);
 }  }
   
 static int qemu_chr_open_pty(QemuOpts *opts, CharDriverState **_chr)  static int qemu_chr_open_pty(QemuOpts *opts, CharDriverState **_chr)
Line 990  static int qemu_chr_open_pty(QemuOpts *o Line 985  static int qemu_chr_open_pty(QemuOpts *o
     CharDriverState *chr;      CharDriverState *chr;
     PtyCharDriver *s;      PtyCharDriver *s;
     struct termios tty;      struct termios tty;
     int slave_fd, len;      int master_fd, slave_fd, len;
 #if defined(__OpenBSD__) || defined(__DragonFly__)  #if defined(__OpenBSD__) || defined(__DragonFly__)
     char pty_name[PATH_MAX];      char pty_name[PATH_MAX];
 #define q_ptsname(x) pty_name  #define q_ptsname(x) pty_name
Line 999  static int qemu_chr_open_pty(QemuOpts *o Line 994  static int qemu_chr_open_pty(QemuOpts *o
 #define q_ptsname(x) ptsname(x)  #define q_ptsname(x) ptsname(x)
 #endif  #endif
   
     chr = qemu_mallocz(sizeof(CharDriverState));      if (openpty(&master_fd, &slave_fd, pty_name, NULL, NULL) < 0) {
     s = qemu_mallocz(sizeof(PtyCharDriver));  
   
     if (openpty(&s->fd, &slave_fd, pty_name, NULL, NULL) < 0) {  
         return -errno;          return -errno;
     }      }
   
Line 1012  static int qemu_chr_open_pty(QemuOpts *o Line 1004  static int qemu_chr_open_pty(QemuOpts *o
     tcsetattr(slave_fd, TCSAFLUSH, &tty);      tcsetattr(slave_fd, TCSAFLUSH, &tty);
     close(slave_fd);      close(slave_fd);
   
     len = strlen(q_ptsname(s->fd)) + 5;      chr = g_malloc0(sizeof(CharDriverState));
     chr->filename = qemu_malloc(len);  
     snprintf(chr->filename, len, "pty:%s", q_ptsname(s->fd));      len = strlen(q_ptsname(master_fd)) + 5;
     qemu_opt_set(opts, "path", q_ptsname(s->fd));      chr->filename = g_malloc(len);
     fprintf(stderr, "char device redirected to %s\n", q_ptsname(s->fd));      snprintf(chr->filename, len, "pty:%s", q_ptsname(master_fd));
       qemu_opt_set(opts, "path", q_ptsname(master_fd));
       fprintf(stderr, "char device redirected to %s\n", q_ptsname(master_fd));
   
       s = g_malloc0(sizeof(PtyCharDriver));
     chr->opaque = s;      chr->opaque = s;
     chr->chr_write = pty_chr_write;      chr->chr_write = pty_chr_write;
     chr->chr_update_read_handler = pty_chr_update_read_handler;      chr->chr_update_read_handler = pty_chr_update_read_handler;
     chr->chr_close = pty_chr_close;      chr->chr_close = pty_chr_close;
   
       s->fd = master_fd;
     s->timer = qemu_new_timer_ms(rt_clock, pty_chr_timer, chr);      s->timer = qemu_new_timer_ms(rt_clock, pty_chr_timer, chr);
   
     *_chr = chr;      *_chr = chr;
Line 1358  static void pp_close(CharDriverState *ch Line 1354  static void pp_close(CharDriverState *ch
     pp_hw_mode(drv, IEEE1284_MODE_COMPAT);      pp_hw_mode(drv, IEEE1284_MODE_COMPAT);
     ioctl(fd, PPRELEASE);      ioctl(fd, PPRELEASE);
     close(fd);      close(fd);
     qemu_free(drv);      g_free(drv);
     qemu_chr_event(chr, CHR_EVENT_CLOSED);      qemu_chr_be_event(chr, CHR_EVENT_CLOSED);
 }  }
   
 static int qemu_chr_open_pp(QemuOpts *opts, CharDriverState **_chr)  static int qemu_chr_open_pp(QemuOpts *opts, CharDriverState **_chr)
Line 1379  static int qemu_chr_open_pp(QemuOpts *op Line 1375  static int qemu_chr_open_pp(QemuOpts *op
         return -errno;          return -errno;
     }      }
   
     drv = qemu_mallocz(sizeof(ParallelCharDriver));      drv = g_malloc0(sizeof(ParallelCharDriver));
     drv->fd = fd;      drv->fd = fd;
     drv->mode = IEEE1284_MODE_COMPAT;      drv->mode = IEEE1284_MODE_COMPAT;
   
     chr = qemu_mallocz(sizeof(CharDriverState));      chr = g_malloc0(sizeof(CharDriverState));
     chr->chr_write = null_chr_write;      chr->chr_write = null_chr_write;
     chr->chr_ioctl = pp_ioctl;      chr->chr_ioctl = pp_ioctl;
     chr->chr_close = pp_close;      chr->chr_close = pp_close;
Line 1445  static int qemu_chr_open_pp(QemuOpts *op Line 1441  static int qemu_chr_open_pp(QemuOpts *op
         return -errno;          return -errno;
     }      }
   
     chr = qemu_mallocz(sizeof(CharDriverState));      chr = g_malloc0(sizeof(CharDriverState));
     chr->opaque = (void *)(intptr_t)fd;      chr->opaque = (void *)(intptr_t)fd;
     chr->chr_write = null_chr_write;      chr->chr_write = null_chr_write;
     chr->chr_ioctl = pp_ioctl;      chr->chr_ioctl = pp_ioctl;
Line 1457  static int qemu_chr_open_pp(QemuOpts *op Line 1453  static int qemu_chr_open_pp(QemuOpts *op
   
 #else /* _WIN32 */  #else /* _WIN32 */
   
   static CharDriverState *stdio_clients[STDIO_MAX_CLIENTS];
   
 typedef struct {  typedef struct {
     int max_size;      int max_size;
     HANDLE hcom, hrecv, hsend;      HANDLE hcom, hrecv, hsend;
Line 1465  typedef struct { Line 1463  typedef struct {
     DWORD len;      DWORD len;
 } WinCharState;  } WinCharState;
   
   typedef struct {
       HANDLE  hStdIn;
       HANDLE  hInputReadyEvent;
       HANDLE  hInputDoneEvent;
       HANDLE  hInputThread;
       uint8_t win_stdio_buf;
   } WinStdioCharState;
   
 #define NSENDBUF 2048  #define NSENDBUF 2048
 #define NRECVBUF 2048  #define NRECVBUF 2048
 #define MAXCONNECT 1  #define MAXCONNECT 1
Line 1494  static void win_chr_close(CharDriverStat Line 1500  static void win_chr_close(CharDriverStat
     else      else
         qemu_del_polling_cb(win_chr_poll, chr);          qemu_del_polling_cb(win_chr_poll, chr);
   
     qemu_chr_event(chr, CHR_EVENT_CLOSED);      qemu_chr_be_event(chr, CHR_EVENT_CLOSED);
 }  }
   
 static int win_chr_init(CharDriverState *chr, const char *filename)  static int win_chr_init(CharDriverState *chr, const char *filename)
Line 1602  static int win_chr_read_poll(CharDriverS Line 1608  static int win_chr_read_poll(CharDriverS
 {  {
     WinCharState *s = chr->opaque;      WinCharState *s = chr->opaque;
   
     s->max_size = qemu_chr_can_read(chr);      s->max_size = qemu_chr_be_can_write(chr);
     return s->max_size;      return s->max_size;
 }  }
   
Line 1624  static void win_chr_readfile(CharDriverS Line 1630  static void win_chr_readfile(CharDriverS
     }      }
   
     if (size > 0) {      if (size > 0) {
         qemu_chr_read(chr, buf, size);          qemu_chr_be_write(chr, buf, size);
     }      }
 }  }
   
Line 1663  static int qemu_chr_open_win(QemuOpts *o Line 1669  static int qemu_chr_open_win(QemuOpts *o
     CharDriverState *chr;      CharDriverState *chr;
     WinCharState *s;      WinCharState *s;
   
     chr = qemu_mallocz(sizeof(CharDriverState));      chr = g_malloc0(sizeof(CharDriverState));
     s = qemu_mallocz(sizeof(WinCharState));      s = g_malloc0(sizeof(WinCharState));
     chr->opaque = s;      chr->opaque = s;
     chr->chr_write = win_chr_write;      chr->chr_write = win_chr_write;
     chr->chr_close = win_chr_close;      chr->chr_close = win_chr_close;
   
     if (win_chr_init(chr, filename) < 0) {      if (win_chr_init(chr, filename) < 0) {
         free(s);          g_free(s);
         free(chr);          g_free(chr);
         return -EIO;          return -EIO;
     }      }
     qemu_chr_generic_open(chr);      qemu_chr_generic_open(chr);
Line 1765  static int qemu_chr_open_win_pipe(QemuOp Line 1771  static int qemu_chr_open_win_pipe(QemuOp
     CharDriverState *chr;      CharDriverState *chr;
     WinCharState *s;      WinCharState *s;
   
     chr = qemu_mallocz(sizeof(CharDriverState));      chr = g_malloc0(sizeof(CharDriverState));
     s = qemu_mallocz(sizeof(WinCharState));      s = g_malloc0(sizeof(WinCharState));
     chr->opaque = s;      chr->opaque = s;
     chr->chr_write = win_chr_write;      chr->chr_write = win_chr_write;
     chr->chr_close = win_chr_close;      chr->chr_close = win_chr_close;
   
     if (win_chr_pipe_init(chr, filename) < 0) {      if (win_chr_pipe_init(chr, filename) < 0) {
         free(s);          g_free(s);
         free(chr);          g_free(chr);
         return -EIO;          return -EIO;
     }      }
     qemu_chr_generic_open(chr);      qemu_chr_generic_open(chr);
Line 1787  static int qemu_chr_open_win_file(HANDLE Line 1793  static int qemu_chr_open_win_file(HANDLE
     CharDriverState *chr;      CharDriverState *chr;
     WinCharState *s;      WinCharState *s;
   
     chr = qemu_mallocz(sizeof(CharDriverState));      chr = g_malloc0(sizeof(CharDriverState));
     s = qemu_mallocz(sizeof(WinCharState));      s = g_malloc0(sizeof(WinCharState));
     s->hcom = fd_out;      s->hcom = fd_out;
     chr->opaque = s;      chr->opaque = s;
     chr->chr_write = win_chr_write;      chr->chr_write = win_chr_write;
Line 1815  static int qemu_chr_open_win_file_out(Qe Line 1821  static int qemu_chr_open_win_file_out(Qe
   
     return qemu_chr_open_win_file(fd_out, _chr);      return qemu_chr_open_win_file(fd_out, _chr);
 }  }
   
   static int win_stdio_write(CharDriverState *chr, const uint8_t *buf, int len)
   {
       HANDLE  hStdOut = GetStdHandle(STD_OUTPUT_HANDLE);
       DWORD   dwSize;
       int     len1;
   
       len1 = len;
   
       while (len1 > 0) {
           if (!WriteFile(hStdOut, buf, len1, &dwSize, NULL)) {
               break;
           }
           buf  += dwSize;
           len1 -= dwSize;
       }
   
       return len - len1;
   }
   
   static void win_stdio_wait_func(void *opaque)
   {
       CharDriverState   *chr   = opaque;
       WinStdioCharState *stdio = chr->opaque;
       INPUT_RECORD       buf[4];
       int                ret;
       DWORD              dwSize;
       int                i;
   
       ret = ReadConsoleInput(stdio->hStdIn, buf, sizeof(buf) / sizeof(*buf),
                              &dwSize);
   
       if (!ret) {
           /* Avoid error storm */
           qemu_del_wait_object(stdio->hStdIn, NULL, NULL);
           return;
       }
   
       for (i = 0; i < dwSize; i++) {
           KEY_EVENT_RECORD *kev = &buf[i].Event.KeyEvent;
   
           if (buf[i].EventType == KEY_EVENT && kev->bKeyDown) {
               int j;
               if (kev->uChar.AsciiChar != 0) {
                   for (j = 0; j < kev->wRepeatCount; j++) {
                       if (qemu_chr_be_can_write(chr)) {
                           uint8_t c = kev->uChar.AsciiChar;
                           qemu_chr_be_write(chr, &c, 1);
                       }
                   }
               }
           }
       }
   }
   
   static DWORD WINAPI win_stdio_thread(LPVOID param)
   {
       CharDriverState   *chr   = param;
       WinStdioCharState *stdio = chr->opaque;
       int                ret;
       DWORD              dwSize;
   
       while (1) {
   
           /* Wait for one byte */
           ret = ReadFile(stdio->hStdIn, &stdio->win_stdio_buf, 1, &dwSize, NULL);
   
           /* Exit in case of error, continue if nothing read */
           if (!ret) {
               break;
           }
           if (!dwSize) {
               continue;
           }
   
           /* Some terminal emulator returns \r\n for Enter, just pass \n */
           if (stdio->win_stdio_buf == '\r') {
               continue;
           }
   
           /* Signal the main thread and wait until the byte was eaten */
           if (!SetEvent(stdio->hInputReadyEvent)) {
               break;
           }
           if (WaitForSingleObject(stdio->hInputDoneEvent, INFINITE)
               != WAIT_OBJECT_0) {
               break;
           }
       }
   
       qemu_del_wait_object(stdio->hInputReadyEvent, NULL, NULL);
       return 0;
   }
   
   static void win_stdio_thread_wait_func(void *opaque)
   {
       CharDriverState   *chr   = opaque;
       WinStdioCharState *stdio = chr->opaque;
   
       if (qemu_chr_be_can_write(chr)) {
           qemu_chr_be_write(chr, &stdio->win_stdio_buf, 1);
       }
   
       SetEvent(stdio->hInputDoneEvent);
   }
   
   static void qemu_chr_set_echo_win_stdio(CharDriverState *chr, bool echo)
   {
       WinStdioCharState *stdio  = chr->opaque;
       DWORD              dwMode = 0;
   
       GetConsoleMode(stdio->hStdIn, &dwMode);
   
       if (echo) {
           SetConsoleMode(stdio->hStdIn, dwMode | ENABLE_ECHO_INPUT);
       } else {
           SetConsoleMode(stdio->hStdIn, dwMode & ~ENABLE_ECHO_INPUT);
       }
   }
   
   static void win_stdio_close(CharDriverState *chr)
   {
       WinStdioCharState *stdio = chr->opaque;
   
       if (stdio->hInputReadyEvent != INVALID_HANDLE_VALUE) {
           CloseHandle(stdio->hInputReadyEvent);
       }
       if (stdio->hInputDoneEvent != INVALID_HANDLE_VALUE) {
           CloseHandle(stdio->hInputDoneEvent);
       }
       if (stdio->hInputThread != INVALID_HANDLE_VALUE) {
           TerminateThread(stdio->hInputThread, 0);
       }
   
       g_free(chr->opaque);
       g_free(chr);
       stdio_nb_clients--;
   }
   
   static int qemu_chr_open_win_stdio(QemuOpts *opts, CharDriverState **_chr)
   {
       CharDriverState   *chr;
       WinStdioCharState *stdio;
       DWORD              dwMode;
       int                is_console = 0;
   
       if (stdio_nb_clients >= STDIO_MAX_CLIENTS
           || ((display_type != DT_NOGRAPHIC) && (stdio_nb_clients != 0))) {
           return -EIO;
       }
   
       chr   = g_malloc0(sizeof(CharDriverState));
       stdio = g_malloc0(sizeof(WinStdioCharState));
   
       stdio->hStdIn = GetStdHandle(STD_INPUT_HANDLE);
       if (stdio->hStdIn == INVALID_HANDLE_VALUE) {
           fprintf(stderr, "cannot open stdio: invalid handle\n");
           exit(1);
       }
   
       is_console = GetConsoleMode(stdio->hStdIn, &dwMode) != 0;
   
       chr->opaque    = stdio;
       chr->chr_write = win_stdio_write;
       chr->chr_close = win_stdio_close;
   
       if (stdio_nb_clients == 0) {
           if (is_console) {
               if (qemu_add_wait_object(stdio->hStdIn,
                                        win_stdio_wait_func, chr)) {
                   fprintf(stderr, "qemu_add_wait_object: failed\n");
               }
           } else {
               DWORD   dwId;
   
               stdio->hInputReadyEvent = CreateEvent(NULL, FALSE, FALSE, NULL);
               stdio->hInputDoneEvent  = CreateEvent(NULL, FALSE, FALSE, NULL);
               stdio->hInputThread     = CreateThread(NULL, 0, win_stdio_thread,
                                               chr, 0, &dwId);
   
               if (stdio->hInputThread == INVALID_HANDLE_VALUE
                   || stdio->hInputReadyEvent == INVALID_HANDLE_VALUE
                   || stdio->hInputDoneEvent == INVALID_HANDLE_VALUE) {
                   fprintf(stderr, "cannot create stdio thread or event\n");
                   exit(1);
               }
               if (qemu_add_wait_object(stdio->hInputReadyEvent,
                                        win_stdio_thread_wait_func, chr)) {
                   fprintf(stderr, "qemu_add_wait_object: failed\n");
               }
           }
       }
   
       dwMode |= ENABLE_LINE_INPUT;
   
       stdio_clients[stdio_nb_clients++] = chr;
       if (stdio_nb_clients == 1 && is_console) {
           /* set the terminal in raw mode */
           /* ENABLE_QUICK_EDIT_MODE | ENABLE_EXTENDED_FLAGS */
           dwMode |= ENABLE_PROCESSED_INPUT;
       }
   
       SetConsoleMode(stdio->hStdIn, dwMode);
   
       chr->chr_set_echo = qemu_chr_set_echo_win_stdio;
       qemu_chr_fe_set_echo(chr, false);
   
       *_chr = chr;
   
       return 0;
   }
 #endif /* !_WIN32 */  #endif /* !_WIN32 */
   
 /***********************************************************/  /***********************************************************/
Line 1840  static int udp_chr_read_poll(void *opaqu Line 2057  static int udp_chr_read_poll(void *opaqu
     CharDriverState *chr = opaque;      CharDriverState *chr = opaque;
     NetCharDriver *s = chr->opaque;      NetCharDriver *s = chr->opaque;
   
     s->max_size = qemu_chr_can_read(chr);      s->max_size = qemu_chr_be_can_write(chr);
   
     /* If there were any stray characters in the queue process them      /* If there were any stray characters in the queue process them
      * first       * first
      */       */
     while (s->max_size > 0 && s->bufptr < s->bufcnt) {      while (s->max_size > 0 && s->bufptr < s->bufcnt) {
         qemu_chr_read(chr, &s->buf[s->bufptr], 1);          qemu_chr_be_write(chr, &s->buf[s->bufptr], 1);
         s->bufptr++;          s->bufptr++;
         s->max_size = qemu_chr_can_read(chr);          s->max_size = qemu_chr_be_can_write(chr);
     }      }
     return s->max_size;      return s->max_size;
 }  }
Line 1867  static void udp_chr_read(void *opaque) Line 2084  static void udp_chr_read(void *opaque)
   
     s->bufptr = 0;      s->bufptr = 0;
     while (s->max_size > 0 && s->bufptr < s->bufcnt) {      while (s->max_size > 0 && s->bufptr < s->bufcnt) {
         qemu_chr_read(chr, &s->buf[s->bufptr], 1);          qemu_chr_be_write(chr, &s->buf[s->bufptr], 1);
         s->bufptr++;          s->bufptr++;
         s->max_size = qemu_chr_can_read(chr);          s->max_size = qemu_chr_be_can_write(chr);
     }      }
 }  }
   
Line 1887  static void udp_chr_close(CharDriverStat Line 2104  static void udp_chr_close(CharDriverStat
 {  {
     NetCharDriver *s = chr->opaque;      NetCharDriver *s = chr->opaque;
     if (s->fd >= 0) {      if (s->fd >= 0) {
         qemu_set_fd_handler(s->fd, NULL, NULL, NULL);          qemu_set_fd_handler2(s->fd, NULL, NULL, NULL, NULL);
         closesocket(s->fd);          closesocket(s->fd);
     }      }
     qemu_free(s);      g_free(s);
     qemu_chr_event(chr, CHR_EVENT_CLOSED);      qemu_chr_be_event(chr, CHR_EVENT_CLOSED);
 }  }
   
 static int qemu_chr_open_udp(QemuOpts *opts, CharDriverState **_chr)  static int qemu_chr_open_udp(QemuOpts *opts, CharDriverState **_chr)
Line 1901  static int qemu_chr_open_udp(QemuOpts *o Line 2118  static int qemu_chr_open_udp(QemuOpts *o
     int fd = -1;      int fd = -1;
     int ret;      int ret;
   
     chr = qemu_mallocz(sizeof(CharDriverState));      chr = g_malloc0(sizeof(CharDriverState));
     s = qemu_mallocz(sizeof(NetCharDriver));      s = g_malloc0(sizeof(NetCharDriver));
   
     fd = inet_dgram_opts(opts);      fd = inet_dgram_opts(opts);
     if (fd < 0) {      if (fd < 0) {
Line 1923  static int qemu_chr_open_udp(QemuOpts *o Line 2140  static int qemu_chr_open_udp(QemuOpts *o
     return 0;      return 0;
   
 return_err:  return_err:
     qemu_free(chr);      g_free(chr);
     qemu_free(s);      g_free(s);
     if (fd >= 0) {      if (fd >= 0) {
         closesocket(fd);          closesocket(fd);
     }      }
Line 1963  static int tcp_chr_read_poll(void *opaqu Line 2180  static int tcp_chr_read_poll(void *opaqu
     TCPCharDriver *s = chr->opaque;      TCPCharDriver *s = chr->opaque;
     if (!s->connected)      if (!s->connected)
         return 0;          return 0;
     s->max_size = qemu_chr_can_read(chr);      s->max_size = qemu_chr_be_can_write(chr);
     return s->max_size;      return s->max_size;
 }  }
   
Line 1996  static void tcp_chr_process_IAC_bytes(Ch Line 2213  static void tcp_chr_process_IAC_bytes(Ch
             } else {              } else {
                 if ((unsigned char)buf[i] == IAC_BREAK && s->do_telnetopt == 2) {                  if ((unsigned char)buf[i] == IAC_BREAK && s->do_telnetopt == 2) {
                     /* Handle IAC break commands by sending a serial break */                      /* Handle IAC break commands by sending a serial break */
                     qemu_chr_event(chr, CHR_EVENT_BREAK);                      qemu_chr_be_event(chr, CHR_EVENT_BREAK);
                     s->do_telnetopt++;                      s->do_telnetopt++;
                 }                  }
                 s->do_telnetopt++;                  s->do_telnetopt++;
Line 2099  static void tcp_chr_read(void *opaque) Line 2316  static void tcp_chr_read(void *opaque)
         /* connection closed */          /* connection closed */
         s->connected = 0;          s->connected = 0;
         if (s->listen_fd >= 0) {          if (s->listen_fd >= 0) {
             qemu_set_fd_handler(s->listen_fd, tcp_chr_accept, NULL, chr);              qemu_set_fd_handler2(s->listen_fd, NULL, tcp_chr_accept, NULL, chr);
         }          }
         qemu_set_fd_handler(s->fd, NULL, NULL, NULL);          qemu_set_fd_handler2(s->fd, NULL, NULL, NULL, NULL);
         closesocket(s->fd);          closesocket(s->fd);
         s->fd = -1;          s->fd = -1;
         qemu_chr_event(chr, CHR_EVENT_CLOSED);          qemu_chr_be_event(chr, CHR_EVENT_CLOSED);
     } else if (size > 0) {      } else if (size > 0) {
         if (s->do_telnetopt)          if (s->do_telnetopt)
             tcp_chr_process_IAC_bytes(chr, s, buf, &size);              tcp_chr_process_IAC_bytes(chr, s, buf, &size);
         if (size > 0)          if (size > 0)
             qemu_chr_read(chr, buf, size);              qemu_chr_be_write(chr, buf, size);
     }      }
 }  }
   
Line 2162  static int tcp_chr_add_client(CharDriver Line 2379  static int tcp_chr_add_client(CharDriver
     if (s->do_nodelay)      if (s->do_nodelay)
         socket_set_nodelay(fd);          socket_set_nodelay(fd);
     s->fd = fd;      s->fd = fd;
     qemu_set_fd_handler(s->listen_fd, NULL, NULL, NULL);      qemu_set_fd_handler2(s->listen_fd, NULL, NULL, NULL, NULL);
     tcp_chr_connect(chr);      tcp_chr_connect(chr);
   
     return 0;      return 0;
Line 2208  static void tcp_chr_close(CharDriverStat Line 2425  static void tcp_chr_close(CharDriverStat
 {  {
     TCPCharDriver *s = chr->opaque;      TCPCharDriver *s = chr->opaque;
     if (s->fd >= 0) {      if (s->fd >= 0) {
         qemu_set_fd_handler(s->fd, NULL, NULL, NULL);          qemu_set_fd_handler2(s->fd, NULL, NULL, NULL, NULL);
         closesocket(s->fd);          closesocket(s->fd);
     }      }
     if (s->listen_fd >= 0) {      if (s->listen_fd >= 0) {
         qemu_set_fd_handler(s->listen_fd, NULL, NULL, NULL);          qemu_set_fd_handler2(s->listen_fd, NULL, NULL, NULL, NULL);
         closesocket(s->listen_fd);          closesocket(s->listen_fd);
     }      }
     qemu_free(s);      g_free(s);
     qemu_chr_event(chr, CHR_EVENT_CLOSED);      qemu_chr_be_event(chr, CHR_EVENT_CLOSED);
 }  }
   
 static int qemu_chr_open_socket(QemuOpts *opts, CharDriverState **_chr)  static int qemu_chr_open_socket(QemuOpts *opts, CharDriverState **_chr)
Line 2239  static int qemu_chr_open_socket(QemuOpts Line 2456  static int qemu_chr_open_socket(QemuOpts
     if (!is_listen)      if (!is_listen)
         is_waitconnect = 0;          is_waitconnect = 0;
   
     chr = qemu_mallocz(sizeof(CharDriverState));      chr = g_malloc0(sizeof(CharDriverState));
     s = qemu_mallocz(sizeof(TCPCharDriver));      s = g_malloc0(sizeof(TCPCharDriver));
   
     if (is_unix) {      if (is_unix) {
         if (is_listen) {          if (is_listen) {
Line 2278  static int qemu_chr_open_socket(QemuOpts Line 2495  static int qemu_chr_open_socket(QemuOpts
   
     if (is_listen) {      if (is_listen) {
         s->listen_fd = fd;          s->listen_fd = fd;
         qemu_set_fd_handler(s->listen_fd, tcp_chr_accept, NULL, chr);          qemu_set_fd_handler2(s->listen_fd, NULL, tcp_chr_accept, NULL, chr);
         if (is_telnet)          if (is_telnet)
             s->do_telnetopt = 1;              s->do_telnetopt = 1;
   
Line 2290  static int qemu_chr_open_socket(QemuOpts Line 2507  static int qemu_chr_open_socket(QemuOpts
     }      }
   
     /* for "info chardev" monitor command */      /* for "info chardev" monitor command */
     chr->filename = qemu_malloc(256);      chr->filename = g_malloc(256);
     if (is_unix) {      if (is_unix) {
         snprintf(chr->filename, 256, "unix:%s%s",          snprintf(chr->filename, 256, "unix:%s%s",
                  qemu_opt_get(opts, "path"),                   qemu_opt_get(opts, "path"),
Line 2318  static int qemu_chr_open_socket(QemuOpts Line 2535  static int qemu_chr_open_socket(QemuOpts
  fail:   fail:
     if (fd >= 0)      if (fd >= 0)
         closesocket(fd);          closesocket(fd);
     qemu_free(s);      g_free(s);
     qemu_free(chr);      g_free(chr);
     return ret;      return ret;
 }  }
   
Line 2341  static int mem_chr_write(CharDriverState Line 2558  static int mem_chr_write(CharDriverState
         /* grow outbuf */          /* grow outbuf */
         d->outbuf_capacity += len;          d->outbuf_capacity += len;
         d->outbuf_capacity *= 2;          d->outbuf_capacity *= 2;
         d->outbuf = qemu_realloc(d->outbuf, d->outbuf_capacity);          d->outbuf = g_realloc(d->outbuf, d->outbuf_capacity);
     }      }
   
     memcpy(d->outbuf + d->outbuf_size, buf, len);      memcpy(d->outbuf + d->outbuf_size, buf, len);
Line 2354  void qemu_chr_init_mem(CharDriverState * Line 2571  void qemu_chr_init_mem(CharDriverState *
 {  {
     MemoryDriver *d;      MemoryDriver *d;
   
     d = qemu_malloc(sizeof(*d));      d = g_malloc(sizeof(*d));
     d->outbuf_size = 0;      d->outbuf_size = 0;
     d->outbuf_capacity = 4096;      d->outbuf_capacity = 4096;
     d->outbuf = qemu_mallocz(d->outbuf_capacity);      d->outbuf = g_malloc0(d->outbuf_capacity);
   
     memset(chr, 0, sizeof(*chr));      memset(chr, 0, sizeof(*chr));
     chr->opaque = d;      chr->opaque = d;
Line 2370  QString *qemu_chr_mem_to_qs(CharDriverSt Line 2587  QString *qemu_chr_mem_to_qs(CharDriverSt
     return qstring_from_substr((char *) d->outbuf, 0, d->outbuf_size - 1);      return qstring_from_substr((char *) d->outbuf, 0, d->outbuf_size - 1);
 }  }
   
 /* NOTE: this driver can not be closed with qemu_chr_close()! */  /* NOTE: this driver can not be closed with qemu_chr_delete()! */
 void qemu_chr_close_mem(CharDriverState *chr)  void qemu_chr_close_mem(CharDriverState *chr)
 {  {
     MemoryDriver *d = chr->opaque;      MemoryDriver *d = chr->opaque;
   
     qemu_free(d->outbuf);      g_free(d->outbuf);
     qemu_free(chr->opaque);      g_free(chr->opaque);
     chr->opaque = NULL;      chr->opaque = NULL;
     chr->chr_write = NULL;      chr->chr_write = NULL;
 }  }
Line 2525  static const struct { Line 2742  static const struct {
     { .name = "pipe",      .open = qemu_chr_open_win_pipe },      { .name = "pipe",      .open = qemu_chr_open_win_pipe },
     { .name = "console",   .open = qemu_chr_open_win_con },      { .name = "console",   .open = qemu_chr_open_win_con },
     { .name = "serial",    .open = qemu_chr_open_win },      { .name = "serial",    .open = qemu_chr_open_win },
       { .name = "stdio",     .open = qemu_chr_open_win_stdio },
 #else  #else
     { .name = "file",      .open = qemu_chr_open_file_out },      { .name = "file",      .open = qemu_chr_open_file_out },
     { .name = "pipe",      .open = qemu_chr_open_pipe },      { .name = "pipe",      .open = qemu_chr_open_pipe },
Line 2548  static const struct { Line 2766  static const struct {
 #endif  #endif
 };  };
   
 CharDriverState *qemu_chr_open_opts(QemuOpts *opts,  CharDriverState *qemu_chr_new_from_opts(QemuOpts *opts,
                                     void (*init)(struct CharDriverState *s))                                      void (*init)(struct CharDriverState *s))
 {  {
     CharDriverState *chr;      CharDriverState *chr;
Line 2583  CharDriverState *qemu_chr_open_opts(Qemu Line 2801  CharDriverState *qemu_chr_open_opts(Qemu
     }      }
   
     if (!chr->filename)      if (!chr->filename)
         chr->filename = qemu_strdup(qemu_opt_get(opts, "backend"));          chr->filename = g_strdup(qemu_opt_get(opts, "backend"));
     chr->init = init;      chr->init = init;
     QTAILQ_INSERT_TAIL(&chardevs, chr, next);      QTAILQ_INSERT_TAIL(&chardevs, chr, next);
   
     if (qemu_opt_get_bool(opts, "mux", 0)) {      if (qemu_opt_get_bool(opts, "mux", 0)) {
         CharDriverState *base = chr;          CharDriverState *base = chr;
         int len = strlen(qemu_opts_id(opts)) + 6;          int len = strlen(qemu_opts_id(opts)) + 6;
         base->label = qemu_malloc(len);          base->label = g_malloc(len);
         snprintf(base->label, len, "%s-base", qemu_opts_id(opts));          snprintf(base->label, len, "%s-base", qemu_opts_id(opts));
         chr = qemu_chr_open_mux(base);          chr = qemu_chr_open_mux(base);
         chr->filename = base->filename;          chr->filename = base->filename;
Line 2599  CharDriverState *qemu_chr_open_opts(Qemu Line 2817  CharDriverState *qemu_chr_open_opts(Qemu
     } else {      } else {
         chr->avail_connections = 1;          chr->avail_connections = 1;
     }      }
     chr->label = qemu_strdup(qemu_opts_id(opts));      chr->label = g_strdup(qemu_opts_id(opts));
     return chr;      return chr;
 }  }
   
 CharDriverState *qemu_chr_open(const char *label, const char *filename, void (*init)(struct CharDriverState *s))  CharDriverState *qemu_chr_new(const char *label, const char *filename, void (*init)(struct CharDriverState *s))
 {  {
     const char *p;      const char *p;
     CharDriverState *chr;      CharDriverState *chr;
Line 2617  CharDriverState *qemu_chr_open(const cha Line 2835  CharDriverState *qemu_chr_open(const cha
     if (!opts)      if (!opts)
         return NULL;          return NULL;
   
     chr = qemu_chr_open_opts(opts, init);      chr = qemu_chr_new_from_opts(opts, init);
     if (chr && qemu_opt_get_bool(opts, "mux", 0)) {      if (chr && qemu_opt_get_bool(opts, "mux", 0)) {
         monitor_init(chr, MONITOR_USE_READLINE);          monitor_init(chr, MONITOR_USE_READLINE);
     }      }
Line 2625  CharDriverState *qemu_chr_open(const cha Line 2843  CharDriverState *qemu_chr_open(const cha
     return chr;      return chr;
 }  }
   
 void qemu_chr_set_echo(struct CharDriverState *chr, bool echo)  void qemu_chr_fe_set_echo(struct CharDriverState *chr, bool echo)
 {  {
     if (chr->chr_set_echo) {      if (chr->chr_set_echo) {
         chr->chr_set_echo(chr, echo);          chr->chr_set_echo(chr, echo);
     }      }
 }  }
   
 void qemu_chr_guest_open(struct CharDriverState *chr)  void qemu_chr_fe_open(struct CharDriverState *chr)
 {  {
     if (chr->chr_guest_open) {      if (chr->chr_guest_open) {
         chr->chr_guest_open(chr);          chr->chr_guest_open(chr);
     }      }
 }  }
   
 void qemu_chr_guest_close(struct CharDriverState *chr)  void qemu_chr_fe_close(struct CharDriverState *chr)
 {  {
     if (chr->chr_guest_close) {      if (chr->chr_guest_close) {
         chr->chr_guest_close(chr);          chr->chr_guest_close(chr);
     }      }
 }  }
   
 void qemu_chr_close(CharDriverState *chr)  void qemu_chr_delete(CharDriverState *chr)
 {  {
     QTAILQ_REMOVE(&chardevs, chr, next);      QTAILQ_REMOVE(&chardevs, chr, next);
     if (chr->chr_close)      if (chr->chr_close)
         chr->chr_close(chr);          chr->chr_close(chr);
     qemu_free(chr->filename);      g_free(chr->filename);
     qemu_free(chr->label);      g_free(chr->label);
     qemu_free(chr);      g_free(chr);
 }  
   
 static void qemu_chr_qlist_iter(QObject *obj, void *opaque)  
 {  
     QDict *chr_dict;  
     Monitor *mon = opaque;  
   
     chr_dict = qobject_to_qdict(obj);  
     monitor_printf(mon, "%s: filename=%s\n", qdict_get_str(chr_dict, "label"),  
                                          qdict_get_str(chr_dict, "filename"));  
 }  }
   
 void qemu_chr_info_print(Monitor *mon, const QObject *ret_data)  ChardevInfoList *qmp_query_chardev(Error **errp)
 {  {
     qlist_iter(qobject_to_qlist(ret_data), qemu_chr_qlist_iter, mon);      ChardevInfoList *chr_list = NULL;
 }  
   
 void qemu_chr_info(Monitor *mon, QObject **ret_data)  
 {  
     QList *chr_list;  
     CharDriverState *chr;      CharDriverState *chr;
   
     chr_list = qlist_new();  
   
     QTAILQ_FOREACH(chr, &chardevs, next) {      QTAILQ_FOREACH(chr, &chardevs, next) {
         QObject *obj = qobject_from_jsonf("{ 'label': %s, 'filename': %s }",          ChardevInfoList *info = g_malloc0(sizeof(*info));
                                           chr->label, chr->filename);          info->value = g_malloc0(sizeof(*info->value));
         qlist_append_obj(chr_list, obj);          info->value->label = g_strdup(chr->label);
           info->value->filename = g_strdup(chr->filename);
   
           info->next = chr_list;
           chr_list = info;
     }      }
   
     *ret_data = QOBJECT(chr_list);      return chr_list;
 }  }
   
 CharDriverState *qemu_chr_find(const char *name)  CharDriverState *qemu_chr_find(const char *name)

Removed from v.1.1.1.11  
changed lines
  Added in v.1.1.1.12


unix.superglobalmegacorp.com