#include #include #include #include #include #include int main (void) { int fd[2]; pid_t pid; if (0 != pipe(fd)) { fprintf (stderr, "Cannot open pipe; %s\n", strerror(errno)); exit(1); } /* fd[0] is now for reading, fd[1] for writing. */ pid = fork(); if (pid > 0) { /* Parent because pid non-zero */ FILE *input; char buf[100]; int status; printf("Parent speaking child pid is %d\n", (int)pid); close(fd[1]); /* We don't need that anymore */ /* For sanity craft a FILE* for fd[0] which is where we read from */ if (NULL == (input = fdopen(fd[0], "r"))) { fprintf (stderr, "fdopen failed?\n"); exit(1); } for(;;) { if (NULL == fgets (buf, sizeof buf, input)) { if (feof(input)) { fprintf(stderr, "Got EOF from child\n"); break; } else { fprintf(stderr, "Huh? Reading failed?\n"); exit(1); } } fprintf (stderr, "Child said: \"%s\"\n", buf); } if (waitpid(pid, &status, 0) < 0) { fprintf(stderr, "waitpid(2): %s\n", strerror(errno)); exit(1); } else if (WIFEXITED(status)) { fprintf (stderr, "Child's exited with status %d\n", WEXITSTATUS(status)); } else { fprintf (stderr, "um, something else happened to child (0x%x)\n", status); } exit(0); } else if (pid == 0) { /* Child */ /* Get rid of fd[0], as we don't need it */ close(fd[0]); /* Close our stdin, stdout, keep stderr though */ close(0); /* stdin */ close(1); /* stdout */ /* FDs will be allocated from the least numbered free fd, that is in order 0, 1 */ /* Craft new fd 0 = stdin */ if (open("/dev/null", O_RDONLY) != 0) { fprintf(stderr, "No /dev/null for us? %s\n", strerror(errno)); exit(1); } /* Make our pipe writing end fd 1 = stdout */ dup(fd[1]); close(fd[1]); /* Exec process */ execlp("/bin/date", "date", NULL); fprintf(stderr, "We survived. exec(2) failed; %s\n", strerror(errno)); exit(1); } else { fprintf(stderr, "fork(2) failed; %s\n", strerror(errno)); } return 0; }