#include #include #include #include #include #define MAXSIZE 4096 void handle_child1(int *fd); void handle_child2(int *fd); /* A program to illustrate the basic use of select. * * The parent forks two children with a pipe to read from each of them and then * reads first from child 1 followed by a read from child 2. */ int main() { char line[MAXSIZE]; int pipe_child1[2], pipe_child2[2]; // Before we fork, create a pipe for child 1 if (pipe(pipe_child1) == -1) { perror("pipe"); } int r = fork(); if (r < 0) { perror("fork"); exit(1); } else if (r == 0) { handle_child1(pipe_child1); exit(0); } else { // This is the parent. Fork another child, // but first close the write file descriptor to child 1 close(pipe_child1[1]); // and make a pipe for the second child if (pipe(pipe_child2) == -1) { perror("pipe"); } // Now fork the second child r = fork(); if (r < 0) { perror("fork"); exit(1); } else if (r == 0) { close(pipe_child1[0]); // still open in parent and inherited handle_child2(pipe_child2); exit(0); } else { close(pipe_child2[1]); // This is now the parent with 2 children -- each with a pipe // from which the parent can read. fd_set read_fds; FD_ZERO(&read_fds); FD_SET(pipe_child1[0], &read_fds); FD_SET(pipe_child2[0], &read_fds); int numfd; if (pipe_child1[0] > pipe_child2[0]) { numfd = pipe_child1[0] + 1; } else { numfd = pipe_child2[0] + 1; } if (select(numfd, &read_fds, NULL, NULL, NULL) == -1) { perror("select"); exit(1); } // Read first from child 1 if (FD_ISSET(pipe_child1[0], &read_fds)) { if ((r = read(pipe_child1[0], line, MAXSIZE)) < 0) { perror("read"); } else if (r == 0) { printf("pipe from child 1 is closed\n"); } else { printf("Read %s from child 1\n", line); } } // Now read from child 2 if (FD_ISSET(pipe_child2[0], &read_fds)) { if ((r = read(pipe_child2[0], line, MAXSIZE)) < 0) { perror("read"); } else if (r == 0) { printf("pipe from child 2 is closed\n"); } else { printf("Read %s from child 2\n", line); } } } // could close all the pipes but since program is ending we will just let // them be closed automatically } return 0; } void handle_child1(int *fd) { close(fd[0]); // we are only writing from child to parent printf("[%d] child\n", getpid()); // Child will write to parent char message[10] = "HELLO DAD"; write(fd[1], message, 10); close(fd[1]); } void handle_child2(int *fd) { close(fd[0]); // we are only writing from child to parent printf("[%d] child\n", getpid()); // Child will write to parent char message[10] = "Hi mom"; write(fd[1], message, 10); close(fd[1]); }