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

version 1.1.1.10, 2018/04/24 18:43:25 version 1.1.1.11, 2018/04/24 18:56:03
Line 35 Line 35
   
 #include <unistd.h>  #include <unistd.h>
 #include <fcntl.h>  #include <fcntl.h>
 #include <signal.h>  
 #include <time.h>  #include <time.h>
 #include <errno.h>  #include <errno.h>
 #include <sys/time.h>  #include <sys/time.h>
Line 169  int qemu_chr_get_msgfd(CharDriverState * Line 168  int qemu_chr_get_msgfd(CharDriverState *
     return s->get_msgfd ? s->get_msgfd(s) : -1;      return s->get_msgfd ? s->get_msgfd(s) : -1;
 }  }
   
   int qemu_chr_add_client(CharDriverState *s, int fd)
   {
       return s->chr_add_client ? s->chr_add_client(s, fd) : -1;
   }
   
 void qemu_chr_accept_input(CharDriverState *s)  void qemu_chr_accept_input(CharDriverState *s)
 {  {
     if (s->chr_accept_input)      if (s->chr_accept_input)
Line 197  void qemu_chr_add_handlers(CharDriverSta Line 201  void qemu_chr_add_handlers(CharDriverSta
                            IOEventHandler *fd_event,                             IOEventHandler *fd_event,
                            void *opaque)                             void *opaque)
 {  {
       if (!opaque && !fd_can_read && !fd_read && !fd_event) {
           /* chr driver being released. */
           ++s->avail_connections;
       }
     s->chr_can_read = fd_can_read;      s->chr_can_read = fd_can_read;
     s->chr_read = fd_read;      s->chr_read = fd_read;
     s->chr_event = fd_event;      s->chr_event = fd_event;
Line 216  static int null_chr_write(CharDriverStat Line 224  static int null_chr_write(CharDriverStat
     return len;      return len;
 }  }
   
 static CharDriverState *qemu_chr_open_null(QemuOpts *opts)  static int qemu_chr_open_null(QemuOpts *opts, CharDriverState **_chr)
 {  {
     CharDriverState *chr;      CharDriverState *chr;
   
     chr = qemu_mallocz(sizeof(CharDriverState));      chr = qemu_mallocz(sizeof(CharDriverState));
     chr->chr_write = null_chr_write;      chr->chr_write = null_chr_write;
     return chr;  
       *_chr= chr;
       return 0;
 }  }
   
 /* MUX driver for serial I/O splitting */  /* MUX driver for serial I/O splitting */
Line 267  static int mux_chr_write(CharDriverState Line 277  static int mux_chr_write(CharDriverState
                 int64_t ti;                  int64_t ti;
                 int secs;                  int secs;
   
                 ti = qemu_get_clock(rt_clock);                  ti = qemu_get_clock_ms(rt_clock);
                 if (d->timestamps_start == -1)                  if (d->timestamps_start == -1)
                     d->timestamps_start = ti;                      d->timestamps_start = ti;
                 ti -= d->timestamps_start;                  ti -= d->timestamps_start;
Line 476  static CharDriverState *qemu_chr_open_mu Line 486  static CharDriverState *qemu_chr_open_mu
     chr->chr_write = mux_chr_write;      chr->chr_write = mux_chr_write;
     chr->chr_update_read_handler = mux_chr_update_read_handler;      chr->chr_update_read_handler = mux_chr_update_read_handler;
     chr->chr_accept_input = mux_chr_accept_input;      chr->chr_accept_input = mux_chr_accept_input;
       /* Frontend guest-open / -close notification is not support with muxes */
       chr->chr_guest_open = NULL;
       chr->chr_guest_close = NULL;
   
     /* Muxes are always open on creation */      /* Muxes are always open on creation */
     qemu_chr_generic_open(chr);      qemu_chr_generic_open(chr);
Line 628  static CharDriverState *qemu_chr_open_fd Line 641  static CharDriverState *qemu_chr_open_fd
     return chr;      return chr;
 }  }
   
 static CharDriverState *qemu_chr_open_file_out(QemuOpts *opts)  static int qemu_chr_open_file_out(QemuOpts *opts, CharDriverState **_chr)
 {  {
     int fd_out;      int fd_out;
   
     TFR(fd_out = qemu_open(qemu_opt_get(opts, "path"),      TFR(fd_out = qemu_open(qemu_opt_get(opts, "path"),
                       O_WRONLY | O_TRUNC | O_CREAT | O_BINARY, 0666));                        O_WRONLY | O_TRUNC | O_CREAT | O_BINARY, 0666));
     if (fd_out < 0)      if (fd_out < 0) {
         return NULL;          return -errno;
     return qemu_chr_open_fd(-1, fd_out);      }
   
       *_chr = qemu_chr_open_fd(-1, fd_out);
       return 0;
 }  }
   
 static CharDriverState *qemu_chr_open_pipe(QemuOpts *opts)  static int qemu_chr_open_pipe(QemuOpts *opts, CharDriverState **_chr)
 {  {
     int fd_in, fd_out;      int fd_in, fd_out;
     char filename_in[256], filename_out[256];      char filename_in[256], filename_out[256];
Line 647  static CharDriverState *qemu_chr_open_pi Line 663  static CharDriverState *qemu_chr_open_pi
   
     if (filename == NULL) {      if (filename == NULL) {
         fprintf(stderr, "chardev: pipe: no filename given\n");          fprintf(stderr, "chardev: pipe: no filename given\n");
         return NULL;          return -EINVAL;
     }      }
   
     snprintf(filename_in, 256, "%s.in", filename);      snprintf(filename_in, 256, "%s.in", filename);
Line 659  static CharDriverState *qemu_chr_open_pi Line 675  static CharDriverState *qemu_chr_open_pi
             close(fd_in);              close(fd_in);
         if (fd_out >= 0)          if (fd_out >= 0)
             close(fd_out);              close(fd_out);
         TFR(fd_in = fd_out = open(filename, O_RDWR | O_BINARY));          TFR(fd_in = fd_out = qemu_open(filename, O_RDWR | O_BINARY));
         if (fd_in < 0)          if (fd_in < 0) {
             return NULL;              return -errno;
           }
     }      }
     return qemu_chr_open_fd(fd_in, fd_out);  
       *_chr = qemu_chr_open_fd(fd_in, fd_out);
       return 0;
 }  }
   
   
Line 754  static void qemu_chr_close_stdio(struct  Line 773  static void qemu_chr_close_stdio(struct 
     fd_chr_close(chr);      fd_chr_close(chr);
 }  }
   
 static CharDriverState *qemu_chr_open_stdio(QemuOpts *opts)  static int qemu_chr_open_stdio(QemuOpts *opts, CharDriverState **_chr)
 {  {
     CharDriverState *chr;      CharDriverState *chr;
   
     if (stdio_nb_clients >= STDIO_MAX_CLIENTS)      if (stdio_nb_clients >= STDIO_MAX_CLIENTS) {
         return NULL;          return -EBUSY;
       }
   
     if (stdio_nb_clients == 0) {      if (stdio_nb_clients == 0) {
         old_fd0_flags = fcntl(0, F_GETFL);          old_fd0_flags = fcntl(0, F_GETFL);
         tcgetattr (0, &oldtty);          tcgetattr (0, &oldtty);
Line 776  static CharDriverState *qemu_chr_open_st Line 797  static CharDriverState *qemu_chr_open_st
                                            display_type != DT_NOGRAPHIC);                                             display_type != DT_NOGRAPHIC);
     qemu_chr_set_echo(chr, false);      qemu_chr_set_echo(chr, false);
   
     return chr;      *_chr = chr;
       return 0;
 }  }
   
 #ifdef __sun__  #ifdef __sun__
Line 911  static void pty_chr_update_read_handler( Line 933  static void pty_chr_update_read_handler(
      * timeout to the normal (much longer) poll interval before the       * timeout to the normal (much longer) poll interval before the
      * timer triggers.       * timer triggers.
      */       */
     qemu_mod_timer(s->timer, qemu_get_clock(rt_clock) + 10);      qemu_mod_timer(s->timer, qemu_get_clock_ms(rt_clock) + 10);
 }  }
   
 static void pty_chr_state(CharDriverState *chr, int connected)  static void pty_chr_state(CharDriverState *chr, int connected)
Line 925  static void pty_chr_state(CharDriverStat Line 947  static void pty_chr_state(CharDriverStat
         /* (re-)connect poll interval for idle guests: once per second.          /* (re-)connect poll interval for idle guests: once per second.
          * We check more frequently in case the guests sends data to           * We check more frequently in case the guests sends data to
          * the virtual device linked to our pty. */           * the virtual device linked to our pty. */
         qemu_mod_timer(s->timer, qemu_get_clock(rt_clock) + 1000);          qemu_mod_timer(s->timer, qemu_get_clock_ms(rt_clock) + 1000);
     } else {      } else {
         if (!s->connected)          if (!s->connected)
             qemu_chr_generic_open(chr);              qemu_chr_generic_open(chr);
Line 963  static void pty_chr_close(struct CharDri Line 985  static void pty_chr_close(struct CharDri
     qemu_chr_event(chr, CHR_EVENT_CLOSED);      qemu_chr_event(chr, CHR_EVENT_CLOSED);
 }  }
   
 static CharDriverState *qemu_chr_open_pty(QemuOpts *opts)  static int qemu_chr_open_pty(QemuOpts *opts, CharDriverState **_chr)
 {  {
     CharDriverState *chr;      CharDriverState *chr;
     PtyCharDriver *s;      PtyCharDriver *s;
Line 981  static CharDriverState *qemu_chr_open_pt Line 1003  static CharDriverState *qemu_chr_open_pt
     s = qemu_mallocz(sizeof(PtyCharDriver));      s = qemu_mallocz(sizeof(PtyCharDriver));
   
     if (openpty(&s->fd, &slave_fd, pty_name, NULL, NULL) < 0) {      if (openpty(&s->fd, &slave_fd, pty_name, NULL, NULL) < 0) {
         return NULL;          return -errno;
     }      }
   
     /* Set raw attributes on the pty. */      /* Set raw attributes on the pty. */
Line 1001  static CharDriverState *qemu_chr_open_pt Line 1023  static CharDriverState *qemu_chr_open_pt
     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->timer = qemu_new_timer(rt_clock, pty_chr_timer, chr);      s->timer = qemu_new_timer_ms(rt_clock, pty_chr_timer, chr);
   
     return chr;      *_chr = chr;
       return 0;
 }  }
   
 static void tty_serial_init(int fd, int speed,  static void tty_serial_init(int fd, int speed,
Line 1204  static void qemu_chr_close_tty(CharDrive Line 1227  static void qemu_chr_close_tty(CharDrive
     }      }
 }  }
   
 static CharDriverState *qemu_chr_open_tty(QemuOpts *opts)  static int qemu_chr_open_tty(QemuOpts *opts, CharDriverState **_chr)
 {  {
     const char *filename = qemu_opt_get(opts, "path");      const char *filename = qemu_opt_get(opts, "path");
     CharDriverState *chr;      CharDriverState *chr;
     int fd;      int fd;
   
     TFR(fd = open(filename, O_RDWR | O_NONBLOCK));      TFR(fd = qemu_open(filename, O_RDWR | O_NONBLOCK));
     if (fd < 0) {      if (fd < 0) {
         return NULL;          return -errno;
     }      }
     tty_serial_init(fd, 115200, 'N', 8, 1);      tty_serial_init(fd, 115200, 'N', 8, 1);
     chr = qemu_chr_open_fd(fd, fd);      chr = qemu_chr_open_fd(fd, fd);
     if (!chr) {  
         close(fd);  
         return NULL;  
     }  
     chr->chr_ioctl = tty_serial_ioctl;      chr->chr_ioctl = tty_serial_ioctl;
     chr->chr_close = qemu_chr_close_tty;      chr->chr_close = qemu_chr_close_tty;
     return chr;  
       *_chr = chr;
       return 0;
 }  }
 #else  /* ! __linux__ && ! __sun__ */  #else  /* ! __linux__ && ! __sun__ */
 static CharDriverState *qemu_chr_open_pty(QemuOpts *opts)  static int qemu_chr_open_pty(QemuOpts *opts, CharDriverState **_chr)
 {  {
     return NULL;      return -ENOTSUP;
 }  }
 #endif /* __linux__ || __sun__ */  #endif /* __linux__ || __sun__ */
   
Line 1341  static void pp_close(CharDriverState *ch Line 1362  static void pp_close(CharDriverState *ch
     qemu_chr_event(chr, CHR_EVENT_CLOSED);      qemu_chr_event(chr, CHR_EVENT_CLOSED);
 }  }
   
 static CharDriverState *qemu_chr_open_pp(QemuOpts *opts)  static int qemu_chr_open_pp(QemuOpts *opts, CharDriverState **_chr)
 {  {
     const char *filename = qemu_opt_get(opts, "path");      const char *filename = qemu_opt_get(opts, "path");
     CharDriverState *chr;      CharDriverState *chr;
Line 1349  static CharDriverState *qemu_chr_open_pp Line 1370  static CharDriverState *qemu_chr_open_pp
     int fd;      int fd;
   
     TFR(fd = open(filename, O_RDWR));      TFR(fd = open(filename, O_RDWR));
     if (fd < 0)      if (fd < 0) {
         return NULL;          return -errno;
       }
   
     if (ioctl(fd, PPCLAIM) < 0) {      if (ioctl(fd, PPCLAIM) < 0) {
         close(fd);          close(fd);
         return NULL;          return -errno;
     }      }
   
     drv = qemu_mallocz(sizeof(ParallelCharDriver));      drv = qemu_mallocz(sizeof(ParallelCharDriver));
Line 1369  static CharDriverState *qemu_chr_open_pp Line 1391  static CharDriverState *qemu_chr_open_pp
   
     qemu_chr_generic_open(chr);      qemu_chr_generic_open(chr);
   
     return chr;      *_chr = chr;
       return 0;
 }  }
 #endif /* __linux__ */  #endif /* __linux__ */
   
 #if defined(__FreeBSD__) || defined(__FreeBSD_kernel__) || defined(__DragonFly__)  #if defined(__FreeBSD__) || defined(__FreeBSD_kernel__) || defined(__DragonFly__)
 static int pp_ioctl(CharDriverState *chr, int cmd, void *arg)  static int pp_ioctl(CharDriverState *chr, int cmd, void *arg)
 {  {
     int fd = (int)(long)chr->opaque;      int fd = (int)(intptr_t)chr->opaque;
     uint8_t b;      uint8_t b;
   
     switch(cmd) {      switch(cmd) {
Line 1411  static int pp_ioctl(CharDriverState *chr Line 1434  static int pp_ioctl(CharDriverState *chr
     return 0;      return 0;
 }  }
   
 static CharDriverState *qemu_chr_open_pp(QemuOpts *opts)  static int qemu_chr_open_pp(QemuOpts *opts, CharDriverState **_chr)
 {  {
     const char *filename = qemu_opt_get(opts, "path");      const char *filename = qemu_opt_get(opts, "path");
     CharDriverState *chr;      CharDriverState *chr;
     int fd;      int fd;
   
     fd = open(filename, O_RDWR);      fd = qemu_open(filename, O_RDWR);
     if (fd < 0)      if (fd < 0) {
         return NULL;          return -errno;
       }
   
     chr = qemu_mallocz(sizeof(CharDriverState));      chr = qemu_mallocz(sizeof(CharDriverState));
     chr->opaque = (void *)(long)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;
     return chr;  
       *_chr = chr;
       return 0;
 }  }
 #endif  #endif
   
Line 1631  static int win_chr_poll(void *opaque) Line 1657  static int win_chr_poll(void *opaque)
     return 0;      return 0;
 }  }
   
 static CharDriverState *qemu_chr_open_win(QemuOpts *opts)  static int qemu_chr_open_win(QemuOpts *opts, CharDriverState **_chr)
 {  {
     const char *filename = qemu_opt_get(opts, "path");      const char *filename = qemu_opt_get(opts, "path");
     CharDriverState *chr;      CharDriverState *chr;
Line 1646  static CharDriverState *qemu_chr_open_wi Line 1672  static CharDriverState *qemu_chr_open_wi
     if (win_chr_init(chr, filename) < 0) {      if (win_chr_init(chr, filename) < 0) {
         free(s);          free(s);
         free(chr);          free(chr);
         return NULL;          return -EIO;
     }      }
     qemu_chr_generic_open(chr);      qemu_chr_generic_open(chr);
     return chr;  
       *_chr = chr;
       return 0;
 }  }
   
 static int win_chr_pipe_poll(void *opaque)  static int win_chr_pipe_poll(void *opaque)
Line 1731  static int win_chr_pipe_init(CharDriverS Line 1759  static int win_chr_pipe_init(CharDriverS
 }  }
   
   
 static CharDriverState *qemu_chr_open_win_pipe(QemuOpts *opts)  static int qemu_chr_open_win_pipe(QemuOpts *opts, CharDriverState **_chr)
 {  {
     const char *filename = qemu_opt_get(opts, "path");      const char *filename = qemu_opt_get(opts, "path");
     CharDriverState *chr;      CharDriverState *chr;
Line 1746  static CharDriverState *qemu_chr_open_wi Line 1774  static CharDriverState *qemu_chr_open_wi
     if (win_chr_pipe_init(chr, filename) < 0) {      if (win_chr_pipe_init(chr, filename) < 0) {
         free(s);          free(s);
         free(chr);          free(chr);
         return NULL;          return -EIO;
     }      }
     qemu_chr_generic_open(chr);      qemu_chr_generic_open(chr);
     return chr;  
       *_chr = chr;
       return 0;
 }  }
   
 static CharDriverState *qemu_chr_open_win_file(HANDLE fd_out)  static int qemu_chr_open_win_file(HANDLE fd_out, CharDriverState **pchr)
 {  {
     CharDriverState *chr;      CharDriverState *chr;
     WinCharState *s;      WinCharState *s;
Line 1763  static CharDriverState *qemu_chr_open_wi Line 1793  static CharDriverState *qemu_chr_open_wi
     chr->opaque = s;      chr->opaque = s;
     chr->chr_write = win_chr_write;      chr->chr_write = win_chr_write;
     qemu_chr_generic_open(chr);      qemu_chr_generic_open(chr);
     return chr;      *pchr = chr;
       return 0;
 }  }
   
 static CharDriverState *qemu_chr_open_win_con(QemuOpts *opts)  static int qemu_chr_open_win_con(QemuOpts *opts, CharDriverState **chr)
 {  {
     return qemu_chr_open_win_file(GetStdHandle(STD_OUTPUT_HANDLE));      return qemu_chr_open_win_file(GetStdHandle(STD_OUTPUT_HANDLE), chr);
 }  }
   
 static CharDriverState *qemu_chr_open_win_file_out(QemuOpts *opts)  static int qemu_chr_open_win_file_out(QemuOpts *opts, CharDriverState **_chr)
 {  {
     const char *file_out = qemu_opt_get(opts, "path");      const char *file_out = qemu_opt_get(opts, "path");
     HANDLE fd_out;      HANDLE fd_out;
   
     fd_out = CreateFile(file_out, GENERIC_WRITE, FILE_SHARE_READ, NULL,      fd_out = CreateFile(file_out, GENERIC_WRITE, FILE_SHARE_READ, NULL,
                         OPEN_ALWAYS, FILE_ATTRIBUTE_NORMAL, NULL);                          OPEN_ALWAYS, FILE_ATTRIBUTE_NORMAL, NULL);
     if (fd_out == INVALID_HANDLE_VALUE)      if (fd_out == INVALID_HANDLE_VALUE) {
         return NULL;          return -EIO;
       }
   
     return qemu_chr_open_win_file(fd_out);      return qemu_chr_open_win_file(fd_out, _chr);
 }  }
 #endif /* !_WIN32 */  #endif /* !_WIN32 */
   
Line 1828  static void udp_chr_read(void *opaque) Line 1860  static void udp_chr_read(void *opaque)
   
     if (s->max_size == 0)      if (s->max_size == 0)
         return;          return;
     s->bufcnt = recv(s->fd, (void *)s->buf, sizeof(s->buf), 0);      s->bufcnt = qemu_recv(s->fd, s->buf, sizeof(s->buf), 0);
     s->bufptr = s->bufcnt;      s->bufptr = s->bufcnt;
     if (s->bufcnt <= 0)      if (s->bufcnt <= 0)
         return;          return;
Line 1862  static void udp_chr_close(CharDriverStat Line 1894  static void udp_chr_close(CharDriverStat
     qemu_chr_event(chr, CHR_EVENT_CLOSED);      qemu_chr_event(chr, CHR_EVENT_CLOSED);
 }  }
   
 static CharDriverState *qemu_chr_open_udp(QemuOpts *opts)  static int qemu_chr_open_udp(QemuOpts *opts, CharDriverState **_chr)
 {  {
     CharDriverState *chr = NULL;      CharDriverState *chr = NULL;
     NetCharDriver *s = NULL;      NetCharDriver *s = NULL;
     int fd = -1;      int fd = -1;
       int ret;
   
     chr = qemu_mallocz(sizeof(CharDriverState));      chr = qemu_mallocz(sizeof(CharDriverState));
     s = qemu_mallocz(sizeof(NetCharDriver));      s = qemu_mallocz(sizeof(NetCharDriver));
Line 1874  static CharDriverState *qemu_chr_open_ud Line 1907  static CharDriverState *qemu_chr_open_ud
     fd = inet_dgram_opts(opts);      fd = inet_dgram_opts(opts);
     if (fd < 0) {      if (fd < 0) {
         fprintf(stderr, "inet_dgram_opts failed\n");          fprintf(stderr, "inet_dgram_opts failed\n");
           ret = -errno;
         goto return_err;          goto return_err;
     }      }
   
Line 1884  static CharDriverState *qemu_chr_open_ud Line 1918  static CharDriverState *qemu_chr_open_ud
     chr->chr_write = udp_chr_write;      chr->chr_write = udp_chr_write;
     chr->chr_update_read_handler = udp_chr_update_read_handler;      chr->chr_update_read_handler = udp_chr_update_read_handler;
     chr->chr_close = udp_chr_close;      chr->chr_close = udp_chr_close;
     return chr;  
       *_chr = chr;
       return 0;
   
 return_err:  return_err:
     if (chr)      qemu_free(chr);
         free(chr);      qemu_free(s);
     if (s)      if (fd >= 0) {
         free(s);  
     if (fd >= 0)  
         closesocket(fd);          closesocket(fd);
     return NULL;      }
       return ret;
 }  }
   
 /***********************************************************/  /***********************************************************/
Line 2043  static ssize_t tcp_chr_recv(CharDriverSt Line 2078  static ssize_t tcp_chr_recv(CharDriverSt
 static ssize_t tcp_chr_recv(CharDriverState *chr, char *buf, size_t len)  static ssize_t tcp_chr_recv(CharDriverState *chr, char *buf, size_t len)
 {  {
     TCPCharDriver *s = chr->opaque;      TCPCharDriver *s = chr->opaque;
     return recv(s->fd, buf, len, 0);      return qemu_recv(s->fd, buf, len, 0);
 }  }
 #endif  #endif
   
Line 2117  static void socket_set_nodelay(int fd) Line 2152  static void socket_set_nodelay(int fd)
     setsockopt(fd, IPPROTO_TCP, TCP_NODELAY, (char *)&val, sizeof(val));      setsockopt(fd, IPPROTO_TCP, TCP_NODELAY, (char *)&val, sizeof(val));
 }  }
   
   static int tcp_chr_add_client(CharDriverState *chr, int fd)
   {
       TCPCharDriver *s = chr->opaque;
       if (s->fd != -1)
           return -1;
   
       socket_set_nonblock(fd);
       if (s->do_nodelay)
           socket_set_nodelay(fd);
       s->fd = fd;
       qemu_set_fd_handler(s->listen_fd, NULL, NULL, NULL);
       tcp_chr_connect(chr);
   
       return 0;
   }
   
 static void tcp_chr_accept(void *opaque)  static void tcp_chr_accept(void *opaque)
 {  {
     CharDriverState *chr = opaque;      CharDriverState *chr = opaque;
Line 2149  static void tcp_chr_accept(void *opaque) Line 2200  static void tcp_chr_accept(void *opaque)
             break;              break;
         }          }
     }      }
     socket_set_nonblock(fd);      if (tcp_chr_add_client(chr, fd) < 0)
     if (s->do_nodelay)          close(fd);
         socket_set_nodelay(fd);  
     s->fd = fd;  
     qemu_set_fd_handler(s->listen_fd, NULL, NULL, NULL);  
     tcp_chr_connect(chr);  
 }  }
   
 static void tcp_chr_close(CharDriverState *chr)  static void tcp_chr_close(CharDriverState *chr)
Line 2172  static void tcp_chr_close(CharDriverStat Line 2219  static void tcp_chr_close(CharDriverStat
     qemu_chr_event(chr, CHR_EVENT_CLOSED);      qemu_chr_event(chr, CHR_EVENT_CLOSED);
 }  }
   
 static CharDriverState *qemu_chr_open_socket(QemuOpts *opts)  static int qemu_chr_open_socket(QemuOpts *opts, CharDriverState **_chr)
 {  {
     CharDriverState *chr = NULL;      CharDriverState *chr = NULL;
     TCPCharDriver *s = NULL;      TCPCharDriver *s = NULL;
Line 2182  static CharDriverState *qemu_chr_open_so Line 2229  static CharDriverState *qemu_chr_open_so
     int do_nodelay;      int do_nodelay;
     int is_unix;      int is_unix;
     int is_telnet;      int is_telnet;
       int ret;
   
     is_listen      = qemu_opt_get_bool(opts, "server", 0);      is_listen      = qemu_opt_get_bool(opts, "server", 0);
     is_waitconnect = qemu_opt_get_bool(opts, "wait", 1);      is_waitconnect = qemu_opt_get_bool(opts, "wait", 1);
Line 2207  static CharDriverState *qemu_chr_open_so Line 2255  static CharDriverState *qemu_chr_open_so
             fd = inet_connect_opts(opts);              fd = inet_connect_opts(opts);
         }          }
     }      }
     if (fd < 0)      if (fd < 0) {
           ret = -errno;
         goto fail;          goto fail;
       }
   
     if (!is_waitconnect)      if (!is_waitconnect)
         socket_set_nonblock(fd);          socket_set_nonblock(fd);
Line 2224  static CharDriverState *qemu_chr_open_so Line 2274  static CharDriverState *qemu_chr_open_so
     chr->chr_write = tcp_chr_write;      chr->chr_write = tcp_chr_write;
     chr->chr_close = tcp_chr_close;      chr->chr_close = tcp_chr_close;
     chr->get_msgfd = tcp_get_msgfd;      chr->get_msgfd = tcp_get_msgfd;
       chr->chr_add_client = tcp_chr_add_client;
   
     if (is_listen) {      if (is_listen) {
         s->listen_fd = fd;          s->listen_fd = fd;
Line 2260  static CharDriverState *qemu_chr_open_so Line 2311  static CharDriverState *qemu_chr_open_so
         tcp_chr_accept(chr);          tcp_chr_accept(chr);
         socket_set_nonblock(s->listen_fd);          socket_set_nonblock(s->listen_fd);
     }      }
     return chr;  
       *_chr = chr;
       return 0;
   
  fail:   fail:
     if (fd >= 0)      if (fd >= 0)
         closesocket(fd);          closesocket(fd);
     qemu_free(s);      qemu_free(s);
     qemu_free(chr);      qemu_free(chr);
     return NULL;      return ret;
 }  }
   
 /***********************************************************/  /***********************************************************/
Line 2460  fail: Line 2513  fail:
   
 static const struct {  static const struct {
     const char *name;      const char *name;
     CharDriverState *(*open)(QemuOpts *opts);      int (*open)(QemuOpts *opts, CharDriverState **chr);
 } backend_table[] = {  } backend_table[] = {
     { .name = "null",      .open = qemu_chr_open_null },      { .name = "null",      .open = qemu_chr_open_null },
     { .name = "socket",    .open = qemu_chr_open_socket },      { .name = "socket",    .open = qemu_chr_open_socket },
Line 2500  CharDriverState *qemu_chr_open_opts(Qemu Line 2553  CharDriverState *qemu_chr_open_opts(Qemu
 {  {
     CharDriverState *chr;      CharDriverState *chr;
     int i;      int i;
       int ret;
   
     if (qemu_opts_id(opts) == NULL) {      if (qemu_opts_id(opts) == NULL) {
         fprintf(stderr, "chardev: no id specified\n");          fprintf(stderr, "chardev: no id specified\n");
Line 2521  CharDriverState *qemu_chr_open_opts(Qemu Line 2575  CharDriverState *qemu_chr_open_opts(Qemu
         return NULL;          return NULL;
     }      }
   
     chr = backend_table[i].open(opts);      ret = backend_table[i].open(opts, &chr);
     if (!chr) {      if (ret < 0) {
         fprintf(stderr, "chardev: opening backend \"%s\" failed\n",          fprintf(stderr, "chardev: opening backend \"%s\" failed: %s\n",
                 qemu_opt_get(opts, "backend"));                  qemu_opt_get(opts, "backend"), strerror(-ret));
         return NULL;          return NULL;
     }      }
   
Line 2540  CharDriverState *qemu_chr_open_opts(Qemu Line 2594  CharDriverState *qemu_chr_open_opts(Qemu
         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;
           chr->avail_connections = MAX_MUX;
         QTAILQ_INSERT_TAIL(&chardevs, chr, next);          QTAILQ_INSERT_TAIL(&chardevs, chr, next);
       } else {
           chr->avail_connections = 1;
     }      }
     chr->label = qemu_strdup(qemu_opts_id(opts));      chr->label = qemu_strdup(qemu_opts_id(opts));
     return chr;      return chr;
Line 2575  void qemu_chr_set_echo(struct CharDriver Line 2632  void qemu_chr_set_echo(struct CharDriver
     }      }
 }  }
   
   void qemu_chr_guest_open(struct CharDriverState *chr)
   {
       if (chr->chr_guest_open) {
           chr->chr_guest_open(chr);
       }
   }
   
   void qemu_chr_guest_close(struct CharDriverState *chr)
   {
       if (chr->chr_guest_close) {
           chr->chr_guest_close(chr);
       }
   }
   
 void qemu_chr_close(CharDriverState *chr)  void qemu_chr_close(CharDriverState *chr)
 {  {
     QTAILQ_REMOVE(&chardevs, chr, next);      QTAILQ_REMOVE(&chardevs, chr, next);

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


unix.superglobalmegacorp.com