Mail Archives: cygwin/1997/04/12/15:16:30
In gnu-win32/cygwin32 b17.1 for Win95, termios noncannonical mode blocks
when it shouldn't, doesn't block when it should, and gets confused by
shift, ctrl, and capslock. (only ~ICANON seemed to cause the problem; the
other flags in the example program are only there because those are what I
use in the real program I was trying to port).
The example program below takes 4 command line parameters:
1. the maximum number of characters to read()
2. a flag to enable or disable select() before reading
3. termios VMIN
4. termios VTIME
With max>=1 and selectflag==0, the read() always blocked until max chars
were typed, completely ignoring VMIN and VTIME. Since termios ECHO is on,
it appears likely that the cygwin code is blocked in a windows call, since
not even it echoes until max chars are typed.
With max>=1 and selectflag==1, it got even weirder: for single-keystroke
characters, the read() immediately returned 1 character (even if VMIN>1);
but if SHIFT or CTRL was held, or CAPS LOCK was on, when a key was pressed,
the read() would then block until max chars were typed.
--- cut here ---
#include <unistd.h>
#include <errno.h>
#include <termios.h>
#include <sys/types.h>
struct termios tty, old_tty;
void set_tty(int vmin, int vtime);
void reset_tty(void);
int main(int argc, char *argv[])
{
char buf[1024];
int max, selectflag, vmin, vtime;
int len, count;
fd_set readers;
if (argc != 5) exit(1);
max = atoi(argv[1]);
selectflag = atoi(argv[2]);
vmin = atoi(argv[3]);
vtime = atoi(argv[4]);
FD_ZERO(&readers);
set_tty(vmin, vtime);
while (1) {
if (selectflag) {
FD_SET(STDIN_FILENO, &readers);
count = select(STDIN_FILENO+1, &readers, NULL, NULL, NULL);
if (count < 0) {
perror("select");
break;
}
}
len = read(STDIN_FILENO, buf, max);
if (len < 0) {
perror("read");
break;
}
write(STDOUT_FILENO, buf, len);
if (buf[0] == 'x')
break;
}
reset_tty();
}
void set_tty(int vmin, int vtime)
{
if (tcgetattr(STDIN_FILENO, &tty) < 0) {
perror("getattr");
exit(1);
}
old_tty = tty;
tty.c_lflag &= ~ICANON;
tty.c_lflag |= ISIG;
tty.c_iflag |= IGNBRK | IGNPAR;
tty.c_iflag &= ~(ICRNL | INLCR | ISTRIP | IGNCR);
tty.c_cc[VMIN] = vmin;
tty.c_cc[VTIME] = vtime;
if (tcsetattr(STDIN_FILENO, TCSAFLUSH, &tty) < 0) {
perror("setattr");
exit(1);
}
}
void reset_tty(void)
{
if (tcsetattr(STDIN_FILENO, TCSAFLUSH, &old_tty) < 0)
perror("reset");
}
--- end cut ---
===========================================================================
Ken Keys hawkeye AT tcp DOT com http://tf.tcp.com/~hawkeye/
---------------------------------------------------------------------------
TinyFugue info: http://tf.tcp.com/~hawkeye/tf/
TF version 3.5 beta 4 for UNIX and OS/2 is available at:
ftp://tf.tcp.com/pub/tinyfugue/ and ftp://ftp.tcp.com/pub/mud/Clients/tf/
TF mailing list: mail to majordomo AT tcp DOT com, with body "subscribe tinyfugue"
===========================================================================
-
For help on using this list (especially unsubscribing), send a message to
"gnu-win32-request AT cygnus DOT com" with one line of text: "help".
- Raw text -