Guest User

Untitled

a guest
Nov 11th, 2017
169
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
text 2.78 KB | None | 0 0
  1. The setup:
  2. exerciser - A program that prints some stuff, and launches a child process that also prints some stuff. Their prints are setup so that both processes could have the "A" buffered unless stdout is flushed before the fork.
  3. reader - Launches a child process and sets up a pipe to read it's output. Prints immediately everything it reads from the child. The child runs the exerciser program.
  4.  
  5. The problem:
  6. The terminal somehow deals with the exerciser in a smart way that prevents "A: 10" from showing up twice, the poor reader on the other hand gets "A: 10". What does *reader* have to do differently so that it gets the exact same result as what the terminal shows?
  7.  
  8. NOTE: I know how to fix this by adding flushes to exerciser but a part of the problem is that I must solve this by only altering reader.
  9.  
  10. ----terminal output----
  11. <...>/pipe-testing$ ./exerciser
  12. A: 10
  13. B: 42
  14. C: 42
  15. C: 10
  16. <...>/pipe-testing$ ./reader
  17. READER...
  18. A: 10
  19. B: 42
  20. C: 42
  21. A: 10
  22. C: 10
  23.  
  24. ----exerciser.cpp----
  25. #include <stdio.h>
  26. #include <unistd.h>
  27. #include <sys/types.h>
  28. #include <sys/wait.h>
  29.  
  30. int main(){
  31. int n = 10, status = 0;
  32. fprintf(stdout, "A: %d\n", n);
  33. if (fork() == 0){
  34. n = 42;
  35. fprintf(stdout, "B: %d\n", n);
  36. }
  37. else{
  38. wait(&status);
  39. }
  40. fprintf(stdout, "C: %d\n", n);
  41. return(0);
  42. }
  43.  
  44. ----reader.cpp----
  45. #include <stdio.h>
  46. #include <unistd.h>
  47.  
  48. int main(){
  49. fprintf(stdout, "READER...\n");
  50. fflush(stdout);
  51.  
  52. int pipe_fds[2];
  53. if (pipe(pipe_fds) == -1){
  54. fprintf(stdout, "failed to make pipe\n");
  55. return(0);
  56. }
  57.  
  58. pid_t child_pid = fork();
  59. if (child_pid == -1){
  60. fprintf(stdout, "failed to fork\n");
  61. return(0);
  62. }
  63.  
  64. #define PIPE_READ 0
  65. #define PIPE_WRITE 1
  66.  
  67. if (child_pid == 0){
  68. close(pipe_fds[PIPE_READ]);
  69. dup2(pipe_fds[PIPE_WRITE], STDOUT_FILENO);
  70. dup2(pipe_fds[PIPE_WRITE], STDERR_FILENO);
  71.  
  72. char *argv[] = {
  73. "sh",
  74. "-c",
  75. "./exerciser",
  76. 0
  77. };
  78.  
  79. if (execv("/bin/sh", argv) == -1){
  80. fprintf(stdout, "failed to execv\n");
  81. return(0);
  82. }
  83. }
  84. else{
  85. close(pipe_fds[PIPE_WRITE]);
  86.  
  87. char buffer[1024];
  88. int capacity = sizeof(buffer);
  89. for (;;){
  90. ssize_t num = read(pipe_fds[PIPE_READ], buffer, capacity);
  91. if (num == -1){
  92. fprintf(stdout, "read error\n");
  93. return(0);
  94. }
  95. else if (num == 0){
  96. break;
  97. }
  98. else{
  99. fprintf(stdout, "%.*s", (int)num, buffer);
  100. fflush(stdout);
  101. }
  102. }
  103. }
  104.  
  105. return(0);
  106. }
RAW Paste Data Copied
Add Comment
Please, Sign In to add comment