Diff for /qemu/qemu-char.c between versions 1.1.1.3 and 1.1.1.4

version 1.1.1.3, 2018/04/24 17:01:42 version 1.1.1.4, 2018/04/24 17:20:39
Line 23 Line 23
  */   */
 #include "qemu-common.h"  #include "qemu-common.h"
 #include "net.h"  #include "net.h"
   #include "monitor.h"
 #include "console.h"  #include "console.h"
 #include "sysemu.h"  #include "sysemu.h"
 #include "qemu-timer.h"  #include "qemu-timer.h"
Line 60 Line 61
 #include <dirent.h>  #include <dirent.h>
 #include <netdb.h>  #include <netdb.h>
 #include <sys/select.h>  #include <sys/select.h>
 #ifdef _BSD  #ifdef HOST_BSD
 #include <sys/stat.h>  #include <sys/stat.h>
 #ifdef __FreeBSD__  #ifdef __FreeBSD__
 #include <libutil.h>  #include <libutil.h>
 #include <dev/ppbus/ppi.h>  #include <dev/ppbus/ppi.h>
 #include <dev/ppbus/ppbconf.h>  #include <dev/ppbus/ppbconf.h>
   #elif defined(__DragonFly__)
   #include <libutil.h>
   #include <dev/misc/ppi/ppi.h>
   #include <bus/ppbus/ppbconf.h>
 #else  #else
 #include <util.h>  #include <util.h>
 #endif  #endif
Line 163  void qemu_chr_read(CharDriverState *s, u Line 168  void qemu_chr_read(CharDriverState *s, u
     s->chr_read(s->handler_opaque, buf, len);      s->chr_read(s->handler_opaque, buf, len);
 }  }
   
   int qemu_chr_get_msgfd(CharDriverState *s)
   {
       return s->get_msgfd ? s->get_msgfd(s) : -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 214  static CharDriverState *qemu_chr_open_nu Line 224  static CharDriverState *qemu_chr_open_nu
 }  }
   
 /* MUX driver for serial I/O splitting */  /* MUX driver for serial I/O splitting */
 static int term_timestamps;  
 static int64_t term_timestamps_start;  
 #define MAX_MUX 4  #define MAX_MUX 4
 #define MUX_BUFFER_SIZE 32      /* Must be a power of 2.  */  #define MUX_BUFFER_SIZE 32      /* Must be a power of 2.  */
 #define MUX_BUFFER_MASK (MUX_BUFFER_SIZE - 1)  #define MUX_BUFFER_MASK (MUX_BUFFER_SIZE - 1)
Line 234  typedef struct { Line 242  typedef struct {
     unsigned char buffer[MAX_MUX][MUX_BUFFER_SIZE];      unsigned char buffer[MAX_MUX][MUX_BUFFER_SIZE];
     int prod[MAX_MUX];      int prod[MAX_MUX];
     int cons[MAX_MUX];      int cons[MAX_MUX];
       int timestamps;
       int linestart;
       int64_t timestamps_start;
 } MuxDriver;  } MuxDriver;
   
   
Line 241  static int mux_chr_write(CharDriverState Line 252  static int mux_chr_write(CharDriverState
 {  {
     MuxDriver *d = chr->opaque;      MuxDriver *d = chr->opaque;
     int ret;      int ret;
     if (!term_timestamps) {      if (!d->timestamps) {
         ret = d->drv->chr_write(d->drv, buf, len);          ret = d->drv->chr_write(d->drv, buf, len);
     } else {      } else {
         int i;          int i;
   
         ret = 0;          ret = 0;
         for(i = 0; i < len; i++) {          for (i = 0; i < len; i++) {
             ret += d->drv->chr_write(d->drv, buf+i, 1);              if (d->linestart) {
             if (buf[i] == '\n') {  
                 char buf1[64];                  char buf1[64];
                 int64_t ti;                  int64_t ti;
                 int secs;                  int secs;
   
                 ti = qemu_get_clock(rt_clock);                  ti = qemu_get_clock(rt_clock);
                 if (term_timestamps_start == -1)                  if (d->timestamps_start == -1)
                     term_timestamps_start = ti;                      d->timestamps_start = ti;
                 ti -= term_timestamps_start;                  ti -= d->timestamps_start;
                 secs = ti / 1000;                  secs = ti / 1000;
                 snprintf(buf1, sizeof(buf1),                  snprintf(buf1, sizeof(buf1),
                          "[%02d:%02d:%02d.%03d] ",                           "[%02d:%02d:%02d.%03d] ",
Line 266  static int mux_chr_write(CharDriverState Line 276  static int mux_chr_write(CharDriverState
                          secs % 60,                           secs % 60,
                          (int)(ti % 1000));                           (int)(ti % 1000));
                 d->drv->chr_write(d->drv, (uint8_t *)buf1, strlen(buf1));                  d->drv->chr_write(d->drv, (uint8_t *)buf1, strlen(buf1));
                   d->linestart = 0;
               }
               ret += d->drv->chr_write(d->drv, buf+i, 1);
               if (buf[i] == '\n') {
                   d->linestart = 1;
             }              }
         }          }
     }      }
Line 309  static void mux_print_help(CharDriverSta Line 324  static void mux_print_help(CharDriverSta
     }      }
 }  }
   
   static void mux_chr_send_event(MuxDriver *d, int mux_nr, int event)
   {
       if (d->chr_event[mux_nr])
           d->chr_event[mux_nr](d->ext_opaque[mux_nr], event);
   }
   
 static int mux_proc_byte(CharDriverState *chr, MuxDriver *d, int ch)  static int mux_proc_byte(CharDriverState *chr, MuxDriver *d, int ch)
 {  {
     if (d->term_got_escape) {      if (d->term_got_escape) {
Line 340  static int mux_proc_byte(CharDriverState Line 361  static int mux_proc_byte(CharDriverState
             break;              break;
         case 'c':          case 'c':
             /* Switch to the next registered device */              /* Switch to the next registered device */
               mux_chr_send_event(d, chr->focus, CHR_EVENT_MUX_OUT);
             chr->focus++;              chr->focus++;
             if (chr->focus >= d->mux_cnt)              if (chr->focus >= d->mux_cnt)
                 chr->focus = 0;                  chr->focus = 0;
               mux_chr_send_event(d, chr->focus, CHR_EVENT_MUX_IN);
               break;
           case 't':
               d->timestamps = !d->timestamps;
               d->timestamps_start = -1;
               d->linestart = 0;
             break;              break;
        case 't':  
            term_timestamps = !term_timestamps;  
            term_timestamps_start = -1;  
            break;  
         }          }
     } else if (ch == term_escape_char) {      } else if (ch == term_escape_char) {
         d->term_got_escape = 1;          d->term_got_escape = 1;
Line 412  static void mux_chr_event(void *opaque,  Line 436  static void mux_chr_event(void *opaque, 
   
     /* Send the event to all registered listeners */      /* Send the event to all registered listeners */
     for (i = 0; i < d->mux_cnt; i++)      for (i = 0; i < d->mux_cnt; i++)
         if (d->chr_event[i])          mux_chr_send_event(d, i, event);
             d->chr_event[i](d->ext_opaque[i], event);  
 }  }
   
 static void mux_chr_update_read_handler(CharDriverState *chr)  static void mux_chr_update_read_handler(CharDriverState *chr)
Line 559  static void fd_chr_update_read_handler(C Line 582  static void fd_chr_update_read_handler(C
     FDCharDriver *s = chr->opaque;      FDCharDriver *s = chr->opaque;
   
     if (s->fd_in >= 0) {      if (s->fd_in >= 0) {
         if (nographic && s->fd_in == 0) {          if (display_type == DT_NOGRAPHIC && s->fd_in == 0) {
         } else {          } else {
             qemu_set_fd_handler2(s->fd_in, fd_chr_read_poll,              qemu_set_fd_handler2(s->fd_in, fd_chr_read_poll,
                                  fd_chr_read, NULL, chr);                                   fd_chr_read, NULL, chr);
Line 572  static void fd_chr_close(struct CharDriv Line 595  static void fd_chr_close(struct CharDriv
     FDCharDriver *s = chr->opaque;      FDCharDriver *s = chr->opaque;
   
     if (s->fd_in >= 0) {      if (s->fd_in >= 0) {
         if (nographic && s->fd_in == 0) {          if (display_type == DT_NOGRAPHIC && s->fd_in == 0) {
         } else {          } else {
             qemu_set_fd_handler2(s->fd_in, NULL, NULL, NULL, NULL);              qemu_set_fd_handler2(s->fd_in, NULL, NULL, NULL, NULL);
         }          }
Line 702  static void term_init(void) Line 725  static void term_init(void)
     tty.c_oflag |= OPOST;      tty.c_oflag |= OPOST;
     tty.c_lflag &= ~(ECHO|ECHONL|ICANON|IEXTEN);      tty.c_lflag &= ~(ECHO|ECHONL|ICANON|IEXTEN);
     /* if graphical mode, we allow Ctrl-C handling */      /* if graphical mode, we allow Ctrl-C handling */
     if (nographic)      if (display_type == DT_NOGRAPHIC)
         tty.c_lflag &= ~ISIG;          tty.c_lflag &= ~ISIG;
     tty.c_cflag &= ~(CSIZE|PARENB);      tty.c_cflag &= ~(CSIZE|PARENB);
     tty.c_cflag |= CS8;      tty.c_cflag |= CS8;
Line 742  static CharDriverState *qemu_chr_open_st Line 765  static CharDriverState *qemu_chr_open_st
   
 #ifdef __sun__  #ifdef __sun__
 /* Once Solaris has openpty(), this is going to be removed. */  /* Once Solaris has openpty(), this is going to be removed. */
 int openpty(int *amaster, int *aslave, char *name,  static int openpty(int *amaster, int *aslave, char *name,
             struct termios *termp, struct winsize *winp)                     struct termios *termp, struct winsize *winp)
 {  {
         const char *slave;          const char *slave;
         int mfd = -1, sfd = -1;          int mfd = -1, sfd = -1;
Line 783  err: Line 806  err:
         return -1;          return -1;
 }  }
   
 void cfmakeraw (struct termios *termios_p)  static void cfmakeraw (struct termios *termios_p)
 {  {
         termios_p->c_iflag &=          termios_p->c_iflag &=
                 ~(IGNBRK|BRKINT|PARMRK|ISTRIP|INLCR|IGNCR|ICRNL|IXON);                  ~(IGNBRK|BRKINT|PARMRK|ISTRIP|INLCR|IGNCR|ICRNL|IXON);
Line 798  void cfmakeraw (struct termios *termios_ Line 821  void cfmakeraw (struct termios *termios_
 #endif  #endif
   
 #if defined(__linux__) || defined(__sun__) || defined(__FreeBSD__) \  #if defined(__linux__) || defined(__sun__) || defined(__FreeBSD__) \
     || defined(__NetBSD__) || defined(__OpenBSD__)      || defined(__NetBSD__) || defined(__OpenBSD__) || defined(__DragonFly__)
   
 typedef struct {  typedef struct {
     int fd;      int fd;
Line 928  static CharDriverState *qemu_chr_open_pt Line 951  static CharDriverState *qemu_chr_open_pt
     PtyCharDriver *s;      PtyCharDriver *s;
     struct termios tty;      struct termios tty;
     int slave_fd, len;      int slave_fd, len;
 #if defined(__OpenBSD__)  #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
 #else  #else
Line 1274  static CharDriverState *qemu_chr_open_pp Line 1297  static CharDriverState *qemu_chr_open_pp
 }  }
 #endif /* __linux__ */  #endif /* __linux__ */
   
 #if defined(__FreeBSD__)  #if defined(__FreeBSD__) || 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)chr->opaque;      int fd = (int)chr->opaque;
Line 1696  static int udp_chr_write(CharDriverState Line 1719  static int udp_chr_write(CharDriverState
 {  {
     NetCharDriver *s = chr->opaque;      NetCharDriver *s = chr->opaque;
   
     return sendto(s->fd, buf, len, 0,      return sendto(s->fd, (const void *)buf, len, 0,
                   (struct sockaddr *)&s->daddr, sizeof(struct sockaddr_in));                    (struct sockaddr *)&s->daddr, sizeof(struct sockaddr_in));
 }  }
   
Line 1725  static void udp_chr_read(void *opaque) Line 1748  static void udp_chr_read(void *opaque)
   
     if (s->max_size == 0)      if (s->max_size == 0)
         return;          return;
     s->bufcnt = recv(s->fd, s->buf, sizeof(s->buf), 0);      s->bufcnt = recv(s->fd, (void *)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 1814  typedef struct { Line 1837  typedef struct {
     int do_telnetopt;      int do_telnetopt;
     int do_nodelay;      int do_nodelay;
     int is_unix;      int is_unix;
       int msgfd;
 } TCPCharDriver;  } TCPCharDriver;
   
 static void tcp_chr_accept(void *opaque);  static void tcp_chr_accept(void *opaque);
Line 1889  static void tcp_chr_process_IAC_bytes(Ch Line 1913  static void tcp_chr_process_IAC_bytes(Ch
     *size = j;      *size = j;
 }  }
   
   static int tcp_get_msgfd(CharDriverState *chr)
   {
       TCPCharDriver *s = chr->opaque;
   
       return s->msgfd;
   }
   
   #ifndef WIN32
   static void unix_process_msgfd(CharDriverState *chr, struct msghdr *msg)
   {
       TCPCharDriver *s = chr->opaque;
       struct cmsghdr *cmsg;
   
       for (cmsg = CMSG_FIRSTHDR(msg); cmsg; cmsg = CMSG_NXTHDR(msg, cmsg)) {
           int fd;
   
           if (cmsg->cmsg_len != CMSG_LEN(sizeof(int)) ||
               cmsg->cmsg_level != SOL_SOCKET ||
               cmsg->cmsg_type != SCM_RIGHTS)
               continue;
   
           fd = *((int *)CMSG_DATA(cmsg));
           if (fd < 0)
               continue;
   
           if (s->msgfd != -1)
               close(s->msgfd);
           s->msgfd = fd;
       }
   }
   
   static ssize_t tcp_chr_recv(CharDriverState *chr, char *buf, size_t len)
   {
       TCPCharDriver *s = chr->opaque;
       struct msghdr msg = { NULL, };
       struct iovec iov[1];
       union {
           struct cmsghdr cmsg;
           char control[CMSG_SPACE(sizeof(int))];
       } msg_control;
       ssize_t ret;
   
       iov[0].iov_base = buf;
       iov[0].iov_len = len;
   
       msg.msg_iov = iov;
       msg.msg_iovlen = 1;
       msg.msg_control = &msg_control;
       msg.msg_controllen = sizeof(msg_control);
   
       ret = recvmsg(s->fd, &msg, 0);
       if (ret > 0 && s->is_unix)
           unix_process_msgfd(chr, &msg);
   
       return ret;
   }
   #else
   static ssize_t tcp_chr_recv(CharDriverState *chr, char *buf, size_t len)
   {
       TCPCharDriver *s = chr->opaque;
       return recv(s->fd, buf, len, 0);
   }
   #endif
   
 static void tcp_chr_read(void *opaque)  static void tcp_chr_read(void *opaque)
 {  {
     CharDriverState *chr = opaque;      CharDriverState *chr = opaque;
Line 1901  static void tcp_chr_read(void *opaque) Line 1989  static void tcp_chr_read(void *opaque)
     len = sizeof(buf);      len = sizeof(buf);
     if (len > s->max_size)      if (len > s->max_size)
         len = s->max_size;          len = s->max_size;
     size = recv(s->fd, buf, len, 0);      size = tcp_chr_recv(chr, (void *)buf, len);
     if (size == 0) {      if (size == 0) {
         /* connection closed */          /* connection closed */
         s->connected = 0;          s->connected = 0;
Line 1916  static void tcp_chr_read(void *opaque) Line 2004  static void tcp_chr_read(void *opaque)
             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_read(chr, buf, size);
           if (s->msgfd != -1) {
               close(s->msgfd);
               s->msgfd = -1;
           }
     }      }
 }  }
   
Line 2077  static CharDriverState *qemu_chr_open_tc Line 2169  static CharDriverState *qemu_chr_open_tc
     s->connected = 0;      s->connected = 0;
     s->fd = -1;      s->fd = -1;
     s->listen_fd = -1;      s->listen_fd = -1;
       s->msgfd = -1;
     s->is_unix = is_unix;      s->is_unix = is_unix;
     s->do_nodelay = do_nodelay && !is_unix;      s->do_nodelay = do_nodelay && !is_unix;
   
     chr->opaque = s;      chr->opaque = s;
     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;
   
     if (is_listen) {      if (is_listen) {
         s->listen_fd = fd;          s->listen_fd = fd;
Line 2118  CharDriverState *qemu_chr_open(const cha Line 2212  CharDriverState *qemu_chr_open(const cha
     CharDriverState *chr;      CharDriverState *chr;
   
     if (!strcmp(filename, "vc")) {      if (!strcmp(filename, "vc")) {
         chr = text_console_init(0);          chr = text_console_init(NULL);
     } else      } else
     if (strstart(filename, "vc:", &p)) {      if (strstart(filename, "vc:", &p)) {
         chr = text_console_init(p);          chr = text_console_init(p);
Line 2139  CharDriverState *qemu_chr_open(const cha Line 2233  CharDriverState *qemu_chr_open(const cha
         chr = qemu_chr_open(label, p, NULL);          chr = qemu_chr_open(label, p, NULL);
         if (chr) {          if (chr) {
             chr = qemu_chr_open_mux(chr);              chr = qemu_chr_open_mux(chr);
             monitor_init(chr, !nographic);              monitor_init(chr, MONITOR_USE_READLINE);
         } else {          } else {
             printf("Unable to open driver: %s\n", p);              printf("Unable to open driver: %s\n", p);
         }          }
Line 2162  CharDriverState *qemu_chr_open(const cha Line 2256  CharDriverState *qemu_chr_open(const cha
     if (strstart(filename, "/dev/parport", NULL)) {      if (strstart(filename, "/dev/parport", NULL)) {
         chr = qemu_chr_open_pp(filename);          chr = qemu_chr_open_pp(filename);
     } else      } else
 #elif defined(__FreeBSD__)  #elif defined(__FreeBSD__) || defined(__DragonFly__)
     if (strstart(filename, "/dev/ppi", NULL)) {      if (strstart(filename, "/dev/ppi", NULL)) {
         chr = qemu_chr_open_pp(filename);          chr = qemu_chr_open_pp(filename);
     } else      } else
 #endif  #endif
 #if defined(__linux__) || defined(__sun__) || defined(__FreeBSD__) \  #if defined(__linux__) || defined(__sun__) || defined(__FreeBSD__) \
     || defined(__NetBSD__) || defined(__OpenBSD__)      || defined(__NetBSD__) || defined(__OpenBSD__) || defined(__DragonFly__)
     if (strstart(filename, "/dev/", NULL)) {      if (strstart(filename, "/dev/", NULL)) {
         chr = qemu_chr_open_tty(filename);          chr = qemu_chr_open_tty(filename);
     } else      } else
Line 2216  void qemu_chr_close(CharDriverState *chr Line 2310  void qemu_chr_close(CharDriverState *chr
     qemu_free(chr);      qemu_free(chr);
 }  }
   
 void qemu_chr_info(void)  void qemu_chr_info(Monitor *mon)
 {  {
     CharDriverState *chr;      CharDriverState *chr;
   
     TAILQ_FOREACH(chr, &chardevs, next) {      TAILQ_FOREACH(chr, &chardevs, next) {
         term_printf("%s: filename=%s\n", chr->label, chr->filename);          monitor_printf(mon, "%s: filename=%s\n", chr->label, chr->filename);
     }      }
 }  }

Removed from v.1.1.1.3  
changed lines
  Added in v.1.1.1.4


unix.superglobalmegacorp.com