On Linux the included program returns from select and exits:$ gcc -Wall -Wextra select_test.c -o select_test$ ./select_testreading from read endclosing write endfirst read returned 0second read returned 0selecting with read fd in fdsetselect returnedOn OS X, the select blocks forever and the program does not exit.  The Linux behavior matches my expectation and appears to conform to the following bit of the POSIX manual page for select:A descriptor shall be considered ready for reading when a call to an input function with O_NONBLOCK clear would not block, whether or not the function would transfer data successfully. (The function might return data, an end-of-file indication, or an error other than one indicating that it is blocked, and in each of these cases the descriptor shall be considered ready for reading.)Since read(2) on the read end of the fifo will always return EOF, my reading says that it should always be considered ready by select.Is macOS's behavior here well-known or expected?  Is there something else in this example that leads to the behavior difference?A further note is that if I remove the read calls then macOS's select returns. This and some other experiments seem to indicate that once an EOF has been read from the file, it will no longer be marked as ready if select is called on it later.Example Program#include <sys/types.h>#include <sys/stat.h>#include <sys/select.h>#include <fcntl.h>#include <unistd.h>#include <stdio.h>#include <stdlib.h>#define FILENAME select_test_tmp.fifoint main() {    pid_t pid;    int r_fd, w_fd;    unsigned char buffer[10];    fd_set readfds;    mkfifo(FILENAME, S_IRWXU);    pid = fork();    if (pid == -1)     {        perror(fork);        exit(1);    }    if (pid == 0)     {        w_fd = open(FILENAME, O_WRONLY);        if (w_fd == -1)         {            perror(open);            exit(1);        }        printf(closing write end\n);        close(w_fd);        exit(0);    }    r_fd = open(FILENAME, O_RDONLY);    if (r_fd == -1)     {        perror(open);        exit(1);    }    printf(reading from read end\n);    if (read(r_fd, &buffer, 10) == 0)     {        printf(first read returned 0\n);    }     else     {        printf(first read returned non-zero\n);    }    if (read(r_fd, &buffer, 10) == 0)     {        printf(second read returned 0\n);    }     else     {        printf(second read returned non-zero\n);    }    FD_ZERO(&readfds);    FD_SET(r_fd, &readfds);    printf(selecting with read fd in fdset\n);    if (select(r_fd + 1, &readfds, NULL, NULL, NULL) == -1)     {        perror(select);        exit(1);    }    printf(select returned\n);    unlink(FILENAME);    exit(0);}
select(2) on FIFO on macOS
c;system calls;portability