Help: with select(2) to detect pending stdin

Help: with select(2) to detect pending stdin

Post by Rodney Haywo » Tue, 20 Jun 1995 04:00:00



I am trying to write a routine that returns a function key wihtout
the user having to press return. I am doing this by putting the terminal
into raw mode and ten reading the characters. This bit is working fine. However
I need to know how many characters to read, as PF-1 returns a different number
of keys to up arrow or the letter A. To detect how many more keys or chars there
are to read I am using the select(2) but it does not seam to work.

Following is a run of my program :

Quote:>CC lee.c -olee -DHP_UX
>lee

Thechar was 27
There is 0 bytes left

Quote:>[A

As you can see I pressed an arrow key that returns 3 characters ESC followed by
[A however after reading the esc select says there are 0 bytes left to read
whereas I expect it to say 2.

Following is a short test program if anyone has any idea what is wrong or has
any better code I would apprecaite the help.

Rodney Haywood

#include <unistd.h>     // read()
#include <fcntl.h>      // setting keyboard flags
#include <sys/ioctl.h>
#include <termio.h>     // used to set terminal modes
#include <termios.h>
#include <stdio.h>
#include <time.h>
#include <string.h>

//
// two global variables for tty and keybrd control
//
static struct termio term_orig;
static int kbdflgs;

//
// function :   system_mode
// purpose  :   reset the system to what it was before input_mode was
//              called
//
void system_mode(void)
{
    if (ioctl(0, TCSETA, &term_orig) == -1) {
        return;
    }
    fcntl(0, F_SETFL, kbdflgs);

Quote:}

//
// function :   input_mode
// purpose  :   set the system into raw mode for keyboard i/o
// returns  :   0 - error
//              1 - no error
//
int input_mode(void)
{
    struct termio term;    // to avoid ^S ^Q processing
    int flags;
    //
    // get rid of XON/XOFF handling, echo, and other input processing
    //
    if (ioctl(0, TCGETA, &term) == -1) {
        return (0);
    }
    (void) ioctl(0, TCGETA, &term_orig);
    term.c_iflag = 0;
    term.c_oflag = 0;
    term.c_lflag = 0;
    term.c_cc[VMIN] = 1;
    term.c_cc[VTIME] = 0;
    if (ioctl(0, TCSETA, &term) == -1) {
        return (0);
    }
    kbdflgs = fcntl(0, F_GETFL, 0);
    //
    // no delay on reading stdin
    //
    flags = fcntl(0, F_GETFL);
    flags &= ~O_NDELAY;
    fcntl(0, F_SETFL, flags);
    return (1);

Quote:}

//
// function :   getch
// purpose  :   read a single character from the keyboard without echo
// returns  :   the keybress character
//
int getch(void)
{
    unsigned char ch;
    //
    // no delays on reading stdin
    //
    input_mode();
    //
    // do a simple loop and get the response
    //
    while (read(0, &ch, 1) != 1) ;

    system_mode();
    return (ch);

Quote:}

int data_ready()
{
    timeval tv;
    tv.tv_sec  = 0;     // no waiting
    tv.tv_usec = 0;
#ifdef HP_UX
    // HP_UX implementation of select in non-standard
    int rset   = 1;     // we are only interested in stdin (bit 1 set)
    return (select(1, &rset, NULL, NULL, &tv));
#else
    // standard implementation
    fd_set rset;
    FD_ZERO(&rset);
    FD_SET(1, &rset);
    return (select(2, &rset, NULL, NULL, &tv));
#endif
Quote:}

int main()
{
    printf("The char was %d\n",getch());
    printf("There is %d bytes left\n",data_ready());
    while (data_ready()) {
        printf("More char of %d\n",getch());
    }
    return 0;
Quote:}

 
 
 

Help: with select(2) to detect pending stdin

Post by Jeff Dicks » Wed, 21 Jun 1995 04:00:00



>I am trying to write a routine that returns a function key wihtout
>the user having to press return. I am doing this by putting the terminal
>into raw mode and ten reading the characters. This bit is working fine. However
>I need to know how many characters to read, as PF-1 returns a different number
>of keys to up arrow or the letter A. To detect how many more keys or chars there
>are to read I am using the select(2) but it does not seam to work.

>Following is a run of my program :

>>CC lee.c -olee -DHP_UX
>>lee
>Thechar was 27
>There is 0 bytes left
>>[A

>As you can see I pressed an arrow key that returns 3 characters ESC followed by
>[A however after reading the esc select says there are 0 bytes left to read
>whereas I expect it to say 2.
>    return (select(2, &rset, NULL, NULL, &tv));

select() returns the number of file descriptors in the set that are ready for
IO and not the number of characters that are available. Use something like
the FIONREAD ioctl to determine the number of characters that are readily
available or set the file descriptor non blocking.

Jeff S.*son


 
 
 

1. Select/Poll says data pending but subsequent read blocks.

Hi,

        I am using TCP socket links for communication in a client/server
        application.  The client sends the server a query, the server
        processes it and returns either an OK or Error packet.

        On both sides of the link, I use select to determine whether or
        not there is data waiting to be read from the socket.  Initially
        this works without problem, however when the server transmits a
        result packet to the client, and then loops waiting for the next
        request, select says that there is data to read even though the
        client has not sent anything - of course, when I subsequently
        call read on the socket, read blocks.

        I have rewritten using poll instead of select, but the results
        are the same.

        So is there a fix for this ? - select does not behave as described
        in the man page (or indeed as on any other system I have developed
        on) this smells like a bug.

        Is there any way to work around the bug ?

        Or is there simply no way of knowing whether or not data is ready
        to read without actually reading it ?

        As always, any help / advice much appreciated.

                Cheers,
                                Paul

Paul Henshaw, EWSE Software Development Team, Centre for Earth Observation
TP270,  JRC Ispra,  21020 Ispra (VA),  Italy
Tel:    ++39 332 789549         Fax: ++39 332 789185
WWW:    http://ewse.ceo.org/construct/build.pl/2694

2. Loadable Modules?

3. select() and Exceptional Conditions Pending: What to do?

4. Density setting for 8mm drive?

5. Q: Using select() to wait for pending input.

6. test

7. Q: select() returns upon socket connection, or STDIN, but not both

8. Retaining file attributes (date, etc.) using FTP

9. select() from sockets & STDIN with ncurses

10. problem with using select() to check stdin

11. Select with device and stdin not working

12. select() on stdin and socket

13. select()ing the STDIN