cunixioposix-select

Confusion with select() - stdout never ready for write


Here is a simple select() loop:

#include <unistd.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <fcntl.h>
#include <sys/select.h>

#define BUFSIZE 999

int main()
{
    int            select_result;
    fd_set         read_fds, write_fds;
    struct timeval timeout = {0, 400000}, timeoutcopy;
    const int max_fd = STDIN_FILENO > STDOUT_FILENO ? STDIN_FILENO :
                                                      STDOUT_FILENO;
    char buffer[BUFSIZE];

    fcntl(STDIN_FILENO, F_SETFL, fcntl(STDIN_FILENO, F_GETFL) | O_NONBLOCK);
    fcntl(STDOUT_FILENO, F_SETFL, fcntl(STDOUT_FILENO, F_GETFL) | O_NONBLOCK);
    printf("Enter loop\n");
    while(1) {
        FD_ZERO(&read_fds);
        FD_ZERO(&write_fds);
        printf("Loop\n");
        FD_SET(STDIN_FILENO, &read_fds);
        FD_SET(STDOUT_FILENO, &write_fds);

        timeoutcopy = timeout;
        if ((select_result = select(max_fd, &read_fds, &write_fds, NULL,
                                    &timeoutcopy)) < 0) {
            return select_result;
        }

        if (FD_ISSET(STDIN_FILENO, &read_fds))
            printf("Stdin ready for read\n");
            fgets(buffer, BUFSIZE, stdin);
            if (strlen(buffer))
                printf("Stdin content: %s\n", buffer);
        if (FD_ISSET(STDOUT_FILENO, &write_fds))
            printf("Stdout ready for write\n");
    }
}

It just polls stdin and stdout with select() with timeout of 400000 milliseconds. When stdin is ready it tries to read it's content and print it. When stdout is ready, it just prints, that it it ready.

And for some reason, after select() call stdin is never ready, why?


Solution

  • Your max_fd should be "the highest-numbered file descriptor in any of the three sets, plus 1." according to the select man page. I should rename it so you'll remember to add 1.