2

In the following C program for an embedded device, I am trying to display a dot (".") every time a user, on a remote computer connected by a serial cable to my device, enters some characters on her terminal program and hits the ENTER key.

What I am seeing is that once the first carriage return is detected, the printf displays dots in an infinite loop. I was expecting FD_ZERO et FD_CLR to "reset" the wait condition.

How to?

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

main()
{
    int    fd1;       /* Input sources 1 and 2 */
    fd_set readfs;    /* File descriptor set */
    int    maxfd;     /* Maximum file desciptor used */
    int    loop=1;    /* Loop while TRUE */

    /*
       open_input_source opens a device, sets the port correctly, and
       returns a file descriptor.
    */
    fd1 = open("/dev/ttyS2", O_RDWR | O_NOCTTY | O_NONBLOCK);
    if (fd1<0)
    {
        exit(0);
    }

    maxfd =fd1+1;  /* Maximum bit entry (fd) to test. */

    /* Loop for input */
    while (loop)
    {
        FD_SET(fd1, &readfs);  /* Set testing for source 1. */

        /* Block until input becomes available. */
        select(maxfd, &readfs, NULL, NULL, NULL);

        if (FD_ISSET(fd1, &readfs))
        {
            /* input from source 1 available */
            printf(".");
            FD_CLR(fd1, &readfs);
            FD_ZERO( &readfs);
        }
    }
}
1
  • Have you tried looking at the return value of select()? Commented Feb 4, 2011 at 15:45

2 Answers 2

4

All FD_CLR and FD_ZERO do is reset the fd_set, it doesn't clear the underlying condition. To do that, you need to read() all the data until there isn't any available anymore.

In fact, if you only want to do one fd at a time, you're better off dispensing with the select() altogether and just use a blocking read() to see when data becomes available.

On a side note, FD_ZERO does the same thing as FD_CLR, but for all the fds. If you do one, you don't need the other.

Sign up to request clarification or add additional context in comments.

2 Comments

And the next loop iteration does FD_SET again, undoing the FD_CLR.
And don't forget to fflush(stdout) after each printf, or you will not see the dot for a long tine.
1

First, use proper function headers like int main(void). Second, FD_SET has an upper limit for storing fds, in other words, not all fds can be monitored with select. (poll has no such limit.)

Third and finally, in your loop, you only check whether there is data available on the fd, but you never read it. Thus, it is continuing to be available in the next iteration.

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.