/* Demo of O_NONBLOCK O_NONBLOCK is intended only for descriptors that could block forever, such as sockets, not for regular files. */ #include #include #include #include // O_RDONLY #include #include #include // Global so that it can be accessed by signal handler. int pipe_fd[2]; void handler(int signum) { char msg[] = "Handler writing to pipe\n"; write(pipe_fd[1], msg, strlen(msg) + 1); } int main(int argc, char* argv[]) { const int BUF_SIZE = 81; char buffer[BUF_SIZE]; int n; // Number of chars read signal(SIGINT, handler); signal(SIGQUIT, handler); // // Demonstrating use of O_NONBLOCK on a pipe. // pipe(pipe_fd); while ( (n = read(pipe_fd[0], buffer, BUF_SIZE-1)) < 0 ) { perror("read from pipe failed"); } buffer[n] = '\0'; printf("Msg: %s\n", buffer); // Showing that reading from an empty pipe normally blocks // n = read(pipe_fd[0], buffer, BUF_SIZE-1); // Blocks // puts("Passed first pipe read"); // Enable NONBLOCK for pipe int flags = fcntl(pipe_fd[0], F_GETFL); flags |= O_NONBLOCK; fcntl(pipe_fd[0], F_SETFL, flags); // Check NONBLOCK for pipe flags = fcntl(pipe_fd[0], F_GETFL); if ((flags & O_NONBLOCK) == O_NONBLOCK) // Note precedence!!! puts("nonblock for pipe enabled from fcntl"); else puts("nonblock for pipe failed in fcntl"); // Showing that we no longer block on reading from an empty pipe. n = read(pipe_fd[0], buffer, BUF_SIZE-1); // What should a non-blocking read return if there's nothing there? if (n < 0) { // read returns -1 when there's nothing there. // If it returned zero we would not be able to distinguish from a // closed stream. perror("Failed to read pipe after setting O_NONBLOCK and no write."); printf("errno: %d, EAGAIN: %d\n", errno, EAGAIN); } else puts(buffer); // Showing that we can still read from the pipe when it has something. write(pipe_fd[1], "hello", 6); n = read(pipe_fd[0], buffer, BUF_SIZE-1); if (n < 0) perror("Failed to read pipe after writing."); else puts(buffer); }