Date: Sat, 24 Mar 2001 22:28:50 +0200 From: "Eli Zaretskii" Sender: halo1 AT zahav DOT net DOT il To: djgpp-workers AT delorie DOT com Message-Id: <7458-Sat24Mar2001222849+0200-eliz@is.elta.co.il> X-Mailer: Emacs 20.6 (via feedmail 8.3.emacs20_6 I) and Blat ver 1.8.6 Subject: select and termios Reply-To: djgpp-workers AT delorie DOT com `select' does not pay attention to the characters buffered by termios. Under ``cooked'' terminal input, termios reads characters until it sees a newline, buffers the entire line in its internal queue, then delivers the buffered characters one by one to the application. However, since reading the whole line drains the keyboard queue, function 4406h of Int 21h called by `select' reports that stdin is not ready for input. You can see the consequence of this in GDB 5.0: start it on a large executable, such as GDB itself, and quickly type a few characters while it is busy reading the debug info. Then see how GDB's input is totally messed up, being out of sync with the characters you type. The patches below fix this problem. Comments? (Mark, does Bash use `select'? I guess not, otherwise this problem would have been reported by someone long ago.) Index: include/libc/ttyprvt.h =================================================================== RCS file: /cvs/djgpp/djgpp/include/libc/ttyprvt.h,v retrieving revision 1.2 diff -u -r1.2 ttyprvt.h --- ttyprvt.h 1998/06/28 22:11:38 1.2 +++ ttyprvt.h 2001/03/24 20:19:29 @@ -128,6 +128,7 @@ /* functions */ void __libc_termios_init (void); +extern int __libc_termios_exist_queue (void); #endif /* !_POSIX_SOURCE */ #endif /* !__STRICT_ANSI__ */ Index: src/libc/compat/time/select.c =================================================================== RCS file: /cvs/djgpp/djgpp/src/libc/compat/time/select.c,v retrieving revision 1.4 diff -u -p -r1.4 select.c --- select.c 1999/04/02 07:49:47 1.4 +++ select.c 2001/03/24 20:20:09 @@ -1,3 +1,4 @@ +/* Copyright (C) 2001 DJ Delorie, see COPYING.DJ for details */ /* Copyright (C) 1996 DJ Delorie, see COPYING.DJ for details */ /* Copyright (C) 1995 DJ Delorie, see COPYING.DJ for details */ /* An implementation of select() @@ -21,6 +22,8 @@ #include #include #include +#include +#include #include inline static int @@ -94,6 +97,11 @@ fd_input_ready(int fd) return -1; } if ((regs.x.dx & 0x80) == 0) /* if not a character device */ + return 1; + /* If it's a STDIN device, and termios buffers some characters, say + it's ready for input. */ + else if ((regs.x.dx & _DEV_STDIN) == 1 + && __libc_read_termios_hook && __libc_termios_exist_queue ()) return 1; regs.x.ax = 0x4406; Index: src/libc/posix/termios/tminit.c =================================================================== RCS file: /cvs/djgpp/djgpp/src/libc/posix/termios/tminit.c,v retrieving revision 1.8 diff -u -p -r1.8 tminit.c --- tminit.c 2001/01/05 20:10:19 1.8 +++ tminit.c 2001/03/24 20:20:47 @@ -52,7 +52,6 @@ static void __libc_termios_maybe_erase1 static void __libc_termios_erase_editline (void); static void __libc_termios_kill_editline (void); static void __libc_termios_insert_editline (unsigned char ch); -static int __libc_termios_exist_queue (void); static void __libc_termios_clear_queue (void); static int __libc_termios_get_queue (void); static int __libc_termios_put_queue (unsigned char ch); @@ -815,7 +814,7 @@ __libc_termios_insert_editline (unsigned /******************************************************************************/ /* queued input routines ******************************************************/ -static int +int __libc_termios_exist_queue (void) { return __libc_tty_p->t_count;