select question
William Roberts
liam at cs.qmw.ac.uk
Tue Dec 4 04:59:41 AEST 1990
In <AUXPOST%90120217553536 at PUCC.BITNET> MATLEVAN at EKU (Jerry LeVan) writes:
>It appears that when I strike a key that sends an escape sequence
>that only the <esc> character is initially sent and the other characters
>are buffered until another keypress.
>The terminal settings are set as:
> tty = o_tty; /* the old settings */
> tty.c_iflag &= ~(INLCR|ICRNL|ISTRIP|BRKINT);
> tty.c_oflag &= ~OPOST;
> tty.c_lflag &= ~(ICANON|ISIG|ECHO)
> tty.c_cc[4]=0;
> tty.c_cc[5]=0;
>Question:
> Wait: select(...)
> if (rflag) read one character; process character
> goto wait
>If I am at Wait: and place <esc>Or into the system,(down arrow).
>the select fires once the <esc> is processed. When the code returns
>to the Wait: select(...) the read flag is *not* set again even though
>the "O and "r" are available.
This is a bug - it doesn't happen with psuedo terminals (i.e through a telnet
or rlogin connection), on the A/UX console, or under SunOS 4.1. You can work
round the problem by reading more than 1 character at a time (try 3 character
reads).
A little demo program follows: I will send a more detailed bug report to Apple
through the proper channels.
-------------------------------------
#include <sys/time.h>
#include <termio.h>
struct termio tty, o_tty;
main(argc, argv)
int argc;
char *argv[];
{
int n, ttyfd, nbits, nchars;
unsigned long rmask, maskmaster;
unsigned char buffer[20];
unsigned char *cp;
struct timeval timeout, now;
if (argc > 1) {
nchars = atoi(argv[1]);
} else {
nchars = 1;
}
if (nchars >= 20) {
nchars = 20;
}
ttyfd = 2; /* stderr */
n = ioctl(ttyfd, TCGETA, &o_tty);
if (n < 0) {
perror("ioctl TCGETA failed");
exit(1);
}
tty = o_tty; /* the old settings */
tty.c_iflag &= ~(INLCR|ICRNL|ISTRIP|BRKINT);
tty.c_oflag &= ~OPOST;
tty.c_lflag &= ~(ICANON|ISIG|ECHO);
tty.c_cc[4]=0;
tty.c_cc[5]=0;
n = ioctl(ttyfd, TCSETA, &tty);
if (n < 0) {
perror("ioctl TCSETA failed");
exit(1);
}
maskmaster = (1<<ttyfd);
timeout.tv_sec = 4;
timeout.tv_usec = 0;
nbits = 32;
Wait:
rmask = maskmaster;
n = select(nbits, &rmask, 0, 0, &timeout);
gettimeofday(&now, 0);
if (n == 0) {
printf("%d,%d: timeout\n\r", now.tv_sec, now.tv_usec);
goto Wait;
}
if (rmask) {
n = read(ttyfd, buffer, nchars); /* read one character */
printf("%d,%d: got %d chars: ", now.tv_sec, now.tv_usec, n);
for (cp=buffer; n>0; n--,cp++) {
printf(" 0x%x", *cp);
}
printf("\r\n");
if (buffer[0] == 'q') {
ioctl(ttyfd, TCSETA, &o_tty);
exit(0);
}
goto Wait;
}
perror("select failed");
}
-------------------------------------
--
William Roberts ARPA: liam at cs.qmw.ac.uk
Queen Mary & Westfield College UUCP: liam at qmw-cs.UUCP
Mile End Road AppleLink: UK0087
LONDON, E1 4NS, UK Tel: 071-975 5250 (Fax: 081-980 6533)
More information about the Comp.unix.aux
mailing list