1 /* 2 * Process Unidirectional Pipe 3 * Martin Klöckner - mklockner@fi.uba.ar 4 * 5 * Based on example given in wait(2) man page 6 */ 7 8 #include <stdio.h> 9 #include <stdlib.h> 10 #include <string.h> 11 #include <unistd.h> 12 #include <sys/wait.h> 13 #include <stdint.h> 14 15 #define LOG_ENABLE true 16 #define PIPE_READ_END 0 17 #define PIPE_WRITE_END 1 18 19 #if true == LOG_ENABLE 20 #define LOG(fmt, ...) do { \ 21 printf("[LOG] "fmt, ##__VA_ARGS__); \ 22 } while (0) 23 #define LOG_ID(fmt, ...) do { \ 24 printf("[LOG][%ld] "fmt, proc_count, ##__VA_ARGS__); \ 25 } while (0) 26 #else 27 #define LOG(fmt, ...) 28 #define PROC_LOG(fmt, ...) 29 #endif 30 31 int main (void) 32 { 33 int wstatus, cpid, proc_count; 34 int pipefd[2]; 35 char buf; 36 37 proc_count = 0; 38 39 if (pipe(pipefd) == -1) 40 { 41 perror("pipe"); 42 exit(EXIT_FAILURE); 43 } 44 45 cpid = fork(); 46 47 if (cpid == -1) 48 { 49 perror("fork"); 50 exit(EXIT_FAILURE); 51 } 52 else if (cpid == 0) 53 { 54 // Child 55 56 proc_count++; 57 LOG_ID("PID is %jd\n", (intmax_t) getpid()); 58 59 if (close(pipefd[1]) == -1) { 60 // Close unused write end 61 perror("close"); 62 exit(EXIT_FAILURE); 63 } 64 65 while (read(pipefd[0], &buf, 1) > 0) { 66 if (write(STDOUT_FILENO, &buf, 1) != 1) 67 { 68 perror("write"); 69 exit(EXIT_FAILURE); 70 } 71 72 if(buf == '\n') 73 { 74 break; 75 } 76 } 77 78 exit(EXIT_SUCCESS); 79 } 80 else 81 { 82 // Parent 83 84 if (close(pipefd[0]) == -1) { 85 // Close unused read end 86 perror("close"); 87 exit(EXIT_FAILURE); 88 } 89 90 LOG_ID("PID is %jd\n", (intmax_t) getpid()); 91 const char *str = "Hello, World!\n\0"; 92 write(pipefd[PIPE_WRITE_END], str, strlen(str)); 93 94 do 95 { 96 if(waitpid(cpid, &wstatus, WUNTRACED | WCONTINUED) == -1) 97 { 98 perror("waitpid"); 99 exit(EXIT_FAILURE); 100 } 101 102 if (WIFEXITED(wstatus)) 103 { 104 LOG_ID("Child exited with status %d\n", WEXITSTATUS(wstatus)); 105 } 106 else if (WIFSIGNALED(wstatus)) 107 { 108 LOG_ID("Child killed by signal %d\n", WTERMSIG(wstatus)); 109 } 110 else if (WIFSTOPPED(wstatus)) 111 { 112 LOG_ID("Child stopped by signal %d\n", WSTOPSIG(wstatus)); 113 } 114 else if (WIFCONTINUED(wstatus)) 115 { 116 LOG_ID("Child continued\n"); 117 } 118 119 } while (!WIFEXITED(wstatus) && !WIFSIGNALED(wstatus)); 120 exit(EXIT_SUCCESS); 121 } 122 123 exit(EXIT_SUCCESS); 124 }
