From mboxrd@z Thu Jan 1 00:00:00 1970 Received: from mailman by lists.gnu.org with tmda-scanned (Exim 4.43) id 1EklWt-0003BI-41 for qemu-devel@nongnu.org; Fri, 09 Dec 2005 11:55:31 -0500 Received: from exim by lists.gnu.org with spam-scanned (Exim 4.43) id 1EklWp-0003AP-W5 for qemu-devel@nongnu.org; Fri, 09 Dec 2005 11:55:30 -0500 Received: from [199.232.76.173] (helo=monty-python.gnu.org) by lists.gnu.org with esmtp (Exim 4.43) id 1EklWp-0003AI-Hb for qemu-devel@nongnu.org; Fri, 09 Dec 2005 11:55:27 -0500 Received: from [80.91.229.2] (helo=ciao.gmane.org) by monty-python.gnu.org with esmtp (TLS-1.0:RSA_AES_128_CBC_SHA:16) (Exim 4.34) id 1EklY3-00071K-Ak for qemu-devel@nongnu.org; Fri, 09 Dec 2005 11:56:43 -0500 Received: from root by ciao.gmane.org with local (Exim 4.43) id 1EklRx-0007Wd-Ia for qemu-devel@nongnu.org; Fri, 09 Dec 2005 17:50:26 +0100 Received: from pollindd.in2p3.fr ([134.158.128.15]) by main.gmane.org with esmtp (Gmexim 0.1 (Debian)) id 1AlnuQ-0007hv-00 for ; Fri, 09 Dec 2005 17:50:25 +0100 Received: from david.decotigny by pollindd.in2p3.fr with local (Gmexim 0.1 (Debian)) id 1AlnuQ-0007hv-00 for ; Fri, 09 Dec 2005 17:50:25 +0100 From: David Decotigny Date: Fri, 09 Dec 2005 16:32:17 +0100 Message-ID: Mime-Version: 1.0 Content-Type: multipart/mixed; boundary="------------090306060301090802040309" Sender: news Subject: [Qemu-devel] [PATCH] fix for pty device output Reply-To: qemu-devel@nongnu.org List-Id: qemu-devel.nongnu.org List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , To: qemu-devel@nongnu.org This is a multi-part message in MIME format. --------------090306060301090802040309 Content-Type: text/plain; charset=ISO-8859-1 Content-Transfer-Encoding: 7bit Hi, By default, with -monitor pty or -serial pty, local echo is enabled for the qemu side of the pty. This can result in infinite write/read loops and/or slowness of the simulation. Attached is a very small patch (against today's cvs) solving the problem. The 3 lines adjusting the tty fields could be replaced by "cfmakeraw(&tty)" if available on the host platform. BTW, I was also looking for a simple program to dial with these pty, a kind of telnet for ptys... I couldn't find one. Yet, I am pretty sure it does exist ! Anyway, attached is the homemade and very basic version of this program (usage: "./termslave /dev/pts/4" for example once qemu is running). If someone could tell me the name of THE unix-ish program to do the job, I would be glad to throw mine away. Enjoy ! ... And many many many thanks for qemu ! -- David Decotigny -- http://david.decotigny.free.fr --------------090306060301090802040309 Content-Type: text/x-patch; name="patch-qemu-pty.diff" Content-Transfer-Encoding: 7bit Content-Disposition: inline; filename="patch-qemu-pty.diff" Index: vl.c =================================================================== RCS file: /cvsroot/qemu/qemu/vl.c,v retrieving revision 1.152 diff -u -r1.152 vl.c --- vl.c 5 Dec 2005 20:31:52 -0000 1.152 +++ vl.c 9 Dec 2005 15:07:46 -0000 @@ -1396,6 +1396,7 @@ #if defined(__linux__) CharDriverState *qemu_chr_open_pty(void) { + struct termios tty; char slave_name[1024]; int master_fd, slave_fd; @@ -1403,6 +1404,14 @@ if (openpty(&master_fd, &slave_fd, slave_name, NULL, NULL) < 0) { return NULL; } + + /* Disabling local echo and line-buffered output */ + tcgetattr (master_fd, &tty); + tty.c_lflag &= ~(ECHO|ICANON|ISIG); + tty.c_cc[VMIN] = 1; + tty.c_cc[VTIME] = 0; + tcsetattr (master_fd, TCSAFLUSH, &tty); + fprintf(stderr, "char device redirected to %s\n", slave_name); return qemu_chr_open_fd(master_fd, master_fd); } --------------090306060301090802040309 Content-Type: text/x-csrc; name="termslave.c" Content-Transfer-Encoding: 7bit Content-Disposition: inline; filename="termslave.c" /* Unix pty slave program License: GNU GPL version 2 Most of it taken from the GNU C library doc examples */ #include #include #include #include #include #include #include #include /* Use this variable to remember original terminal attributes. */ struct termios saved_attributes; static void reset_input_mode (void) { tcsetattr (STDIN_FILENO, TCSANOW, &saved_attributes); } static void set_input_mode (void) { struct termios tattr; /* Make sure stdin is a terminal. */ if (!isatty (STDIN_FILENO)) { fprintf (stderr, "Not a terminal.\n"); exit (EXIT_FAILURE); } /* Save the terminal attributes so we can restore them later. */ tcgetattr (STDIN_FILENO, &saved_attributes); atexit (reset_input_mode); /* Set the funny terminal modes. */ tcgetattr (STDIN_FILENO, &tattr); tattr.c_iflag &= ~(IGNBRK|BRKINT|PARMRK|ISTRIP |INLCR|IGNCR|ICRNL|IXON); tattr.c_lflag &= ~(ICANON|ECHO); tattr.c_cflag |= CLOCAL; tattr.c_cc[VMIN] = 1; tattr.c_cc[VTIME] = 0; tcsetattr (STDIN_FILENO, TCSAFLUSH, &tattr); } int main (int argc, char *argv[]) { int term; if (argc < 2) { fprintf(stderr, "Usage: %s /dev/pts/number\n", argv[0]); return -1; } term = open(argv[1], O_RDWR); if (term < 0) { perror("open"); return -1; } if (! isatty(term)) { fprintf(stderr, "%s is not a valid terminal\n", argv[1]); return -1; } set_input_mode(); while (1) { fd_set cur_set; FD_ZERO(& cur_set); FD_SET(STDIN_FILENO, & cur_set); FD_SET(term, & cur_set); if (select(FD_SETSIZE, & cur_set, NULL, NULL, NULL) < 1) continue; if (FD_ISSET(term, & cur_set)) { char buf[1024]; int len = read(term, buf, sizeof(buf)); if (len >= 1) write(STDOUT_FILENO, buf, len); else { fprintf(stderr, "Master exitted\n"); break; } } if (FD_ISSET(STDIN_FILENO, & cur_set)) { char c; if (read(STDIN_FILENO, &c, 1) == 1) { if (c == 0x4) /* ctrl-D */ break; write(term, &c, 1); } else break; } } return 0; } --------------090306060301090802040309--