Search code examples
cloopspoolposix-select

How to loop select() to poll for data ad infinitum


#include <stdio.h>
#include <unistd.h>
#include <sys/time.h>
#include <sys/types.h>

int main ()
{
    char            name[20];
    fd_set          input_set;
    struct timeval  timeout;
    int             ready_for_reading = 0;
    int             read_bytes = 0;

    /* Empty the FD Set */
    FD_ZERO(&input_set );
    /* Listen to the input descriptor */
    FD_SET(0, &input_set);

    /* Waiting for some seconds */
    timeout.tv_sec = 10;    // 10 seconds
    timeout.tv_usec = 0;    // 0 milliseconds

    /* Invitation for the user to write something */
    printf("Enter Username: (in 15 seconds)\n");
    printf("Time start now!!!\n");

    /* Listening for input stream for any activity */
    ready_for_reading = select(1, &input_set, NULL, NULL, &timeout);
    /* Here, first parameter is value of the socket descriptor + 1 (STDIN descriptor is 0, so  
     * 0 +1 = 1)  
     * in the set, second is our FD set for reading,
     * third is the FD set in which any write activity needs to updated, which is not required
     * in this case. Fourth is timeout
     */

    if (ready_for_reading == -1) {
        /* Some error has occured in input */
        printf("Unable to read your input\n");
        return -1;
    } else {
        if (ready_for_reading) {
            read_bytes = read(0, name, 19);
            printf("Read, %d bytes from input : %s \n", read_bytes, name);
        } else {
            printf(" 10 Seconds are over - no data input \n");
        }
    }

    return 0;
}

How to do the same, but not just once, but in an infinite loop which breaks after encountering the 'quit' string (for example). Every way I tried - failed. So if no data has been inputed after 10 seconds, the program just prints "10 secs are over - no data input" and then starts waiting again. Same after input - just begins again and behave the same every time in infinite loop.


Solution

  • I don't really see the problem here. Basically just put everything you want in the loop, and let it run. Did you try this?

    int main ()
    {
       /* Declarations and stuff */
       /* ... */
    
       /* The loop */
       int break_condition = 0;
       while (!break_condition)
       {
           /* Selection */
           FD_ZERO(&input_set );   /* Empty the FD Set */
           FD_SET(0, &input_set);  /* Listen to the input descriptor */
           ready_for_reading = select(1, &input_set, NULL, NULL, &timeout);
    
           /* Selection handling */
           if (ready_for_reading)
           {
              /* Do something clever with the input */
           }
           else
           {
              /* Handle the error */
           }
    
           /* Test the breaking condition */
           break_condition = some_calculation();
       }
       return 0;
    }
    

    Note that you have to have keep resetting the selection inside the loop so that it will respond again in the next iteration.