SmallChess
SmallChess

Reputation: 8156

Non-blocking call for reading descriptor

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?

Upvotes: 56

Views: 108747

Answers (6)

Judge Maygarden
Judge Maygarden

Reputation: 27613

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 fcntl 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.

Upvotes: 80

Ankur Soni
Ankur Soni

Reputation: 21

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;
}

Upvotes: 2

Novin Shahroudi
Novin Shahroudi

Reputation: 680

Check out the API or system/tool you are using for your specific programming purpose. (descriptors/file descriptors have many uses in Linux programming such as socket programming, file manipulation, shared_memory, etc.)

For example one time I used inotify (for monitoring file system events). This API gives you ability to create non-blocking file from the first point and there's no need to use fcntl or such APIs to modify the created file descriptor.

Probably other tools or API's that you're going to use have such functionality and you can set such option in their initiation or such steps (check this first).

But generally yes using fcntl is the answer and it might be interesting to know that inotify itself uses fcntl itself too. (refer to the manual pages of Linux)

select() can give you a same functionality as it operates on file descriptors for monitoring events with a specified limited time but keep in mind that the main usage of select is for monitoring multiple file descriptors.

Upvotes: 1

R.. GitHub STOP HELPING ICE
R.. GitHub STOP HELPING ICE

Reputation: 215617

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 */

Upvotes: 18

mu is too short
mu is too short

Reputation: 434965

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.

Upvotes: 3

Elalfer
Elalfer

Reputation: 5358

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

Upvotes: 1

Related Questions