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