Non-blocking call for reading descriptor

87,573

Solution 1

int flags = fcntl(fd, F_GETFL, 0);
fcntl(fd, F_SETFL, flags | O_NONBLOCK);

The code snippet above will configure such a descriptor for non-blocking access. If data is not available when you call read, then the system call will fail with a return value of -1 and errno is set to EAGAIN. See the fnctl man pages for more information.

Alternatively, you can use select with a configurable timeout to check and/or wait a specified time interval for more data. This method is probably what you want and can be much more efficient.

Solution 2

Use select or poll to query whether the file descriptor has data available for read:

fd_set fds;
FD_ZERO(&fds);
FD_SET(&fds, fd);
if (select(fd+1, &fds, 0, 0)==1) /* there is data available */

Solution 3

Depending on what you're doing you might be able to turn the problem inside out and use select to tell you when your file descriptor has something to read.

Solution 4

use poll for timeout:

struct pollfd p;
            int n;
            while ((n = poll(&p, 1, iTo)) < 0) 
              {
               if (errno == EAGAIN || errno == EINTR)
                   continue;
            }

            if (!n) {
                 errno = ETIMEDOUT;
                   }

        while ((len = read(Fd, anyBuff, sizeof(anyenter code hereBuff))) < 0) {
            if (errno == EAGAIN || errno == EINTR)
                continue;

        }

Solution 5

I think you should use select or poll functions to check if there are something to read from the descriptor.

Share:
87,573

Related videos on Youtube

SmallChess
Author by

SmallChess

SmallChess: http://www.smallchess.com. Please follow me at https://twitter.com/scchess or https://www.facebook.com/scchess.

Updated on September 20, 2020

Comments

  • SmallChess
    SmallChess about 3 years

    I have a fd descriptor, which I can use to read from by calling read(fd, buffer,...). Now, I want to check if there is anything to read before actually making the call, because the call is blocking. How do I do this?

    • kqnr
      kqnr over 12 years
      The behavior of read with respect to blocking varies depending on the descriptor type. To what type of device does fd refer?
    • SmallChess
      SmallChess over 12 years
      standard inputs, right now, it's blocking
    • Bionix1441
      Bionix1441 over 7 years
      @KenRockot so if I have a regular file it is different than for example fd which is a socketDescriptor ?
  • mu is too short
    mu is too short over 12 years
    And then check for -1 returns from read and that errno is EAGAIN.
  • malat
    malat almost 9 years
    Isn't is FD_SET(fd, &fds); instead ?
  • R.. GitHub STOP HELPING ICE
    R.. GitHub STOP HELPING ICE almost 9 years
    Probably, but select is a horrible idea anyway because FD_SET invokes UB if fd>=FD_SETSIZE. Just use poll.
  • qrtLs
    qrtLs over 7 years
    good doc about file with non-blocking support setting errno at opengroup
  • Giampaolo Rodolà
    Giampaolo Rodolà almost 7 years
    This is NOT the correct answer. O_NONBLOCK against a regular fs has no effect (read() will keep blocking) and select() will always erroneously report the fd as "ready". Reliable non-blocking IO for regular files on Linux is basically (and unfortunately) not supported.
  • Paul A Jungwirth
    Paul A Jungwirth over 6 years
    Some good sources on regular files and non-blocking I/O. However, if fd is stdin, then it seems harmless to let O_NONBLOCK speed things up when reading from a terminal/pipe and do nothing when reading from a file.
  • Lassi
    Lassi over 5 years
    poll() is now standardized in POSIX so it can always be used in place of select(). pubs.opengroup.org/onlinepubs/009695399/functions/poll.html
  • R.. GitHub STOP HELPING ICE
    R.. GitHub STOP HELPING ICE over 5 years
    Yes, poll should be used instead.
  • Nathan F.
    Nathan F. about 4 years
    Can you add some more details? An example would be nice.
  • nyholku
    nyholku over 3 years
    IIRC poll on macOS AND serial port does not work. I could not locate the reference now but I have distinct recollection that this is or was the case. So as this was old question was not Linux specific I think the recommendation to use poll() might be bad.