sandbox/ostep/hw5/hw5_8.c

86 lines
1.6 KiB
C

#include <sys/wait.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <unistd.h>
int pipefd[2];
int
main(void)
{
if (pipe(pipefd) != 0) {
perror("pipe");
return EXIT_FAILURE;
}
int pwrite = pipefd[1];
int pread = pipefd[0];
pid_t pid = fork();
if (pid < 0) {
perror("fork");
return EXIT_FAILURE;
}
/* the first child */
else if (pid == 0) {
/*
* Close standard output and reassign it to the pipe.
* The close is done automagically by dup2.
*/
dup2(pwrite, STDOUT_FILENO);
/* Close unnecessary pipe read file descriptor. */
close(pread);
/* Now we do the thing. */
printf("Hello, world.\n");
/* ¡Adios! */
return EXIT_SUCCESS;
}
/*
* We are now in the parent. We must fork again, and do the
* child dance.
*/
if ((pid = fork()) < 0) {
perror("fork");
return EXIT_FAILURE;
}
/* the second of the children */
else if (pid == 0) {
/* Close standard input and reassign it to the pipe. */
dup2(pread, STDIN_FILENO);
/* Close unnecessary pipe write file descriptor. */
close(pwrite);
/* Read the thing. */
char data[16];
ssize_t rl;
memset(data, 0, 16);
rl = read(STDIN_FILENO, data, 15);
if (rl < 1) {
perror("read");
return EXIT_FAILURE;
}
printf("%s", data);
return EXIT_SUCCESS;
}
/* wait for the children to die so we can reap them */
/* there are two, they should drop dead on their own. */
int status1, status2;
waitpid(-1, &status1, 0);
waitpid(-1, &status2, 0);
if (WIFEXITED(status1) && WIFEXITED(status2)) {
printf("Goodbye.\n");
return EXIT_SUCCESS;
}
fprintf(stderr, "At least one child died abnormally.\n");
return EXIT_FAILURE;
}