2
votes

I'm having a hard time finding an answer for this online.

What should be expected when calling select for reading file and the socket is set to non-blocking on Linux ?

I don't find it trivial as select man page states:

Those listed in readfds will be watched to see if characters become available for reading (more precisely, to see if a read will not block; in particular, a file descriptor is also ready on end-of-file)

If the socket is set non-blocking, it should never block, should select return immediately? This sounds wrong... Is Hyde documentation wrong or just ignore this case?

Also, if select will indeed block, what should be it's return value? Reading the socket will not block but the socket has no data available for reading..

When I get home I'll write some code examples and edit this question, this could help a lot to anyone else googling this subject.

3

3 Answers

2
votes

If you select() to read on a socket which has no data waiting to be read (nor any errors), it will block (until the select() timeout expires).

0
votes

Here is a little C program that shows that calling select(2) on a non-blocking file descriptor still blocks until there is something to read:

#include <stddef.h>
#include <stdio.h>
#include <sys/time.h>
#include <sys/select.h>
#include <unistd.h>
#include <fcntl.h>

int main(int argc, char **argv) {
    int ready;
    struct timeval *pto;
    fd_set readfds, writefds;
    char buf[1024];
    int bytes;
    int fd = 0; // stdin

    pto = NULL;
    FD_ZERO(&readfds);
    FD_ZERO(&writefds);
    FD_SET(fd, &readfds);

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

    while (1) { 
        ready = select(1, &readfds, &writefds, NULL, pto);

        if (ready == -1) {
            printf("got -1\n");
            return 1;
        }

        printf("ready = %d\n", ready);

        bytes = read(fd, buf, 1024);
        if (bytes == 0) {
            printf("all done\n");
            return 0;
        } else if (bytes > 0) {
            buf[bytes] = '\0';
            printf("read: %s\n", buf);
        } else {
            printf("got an error\n");
        }
    }
}
-1
votes

if you use read() without non-block, the program will block hence blocking the flow of your code. But if you use non-block mode, the select() will return immediately without blocking code flow returning a value greater then zero only if there is some data to read.