1 /* 2 * Process Ping Pong 3 * Martin Klöckner - mklockner@fi.uba.ar 4 * 5 * Based on examples given in wait(2) man page 6 */ 7 8 #include <stdio.h> 9 #include <stdlib.h> 10 #include <string.h> 11 #include <sys/wait.h> 12 #include <stdint.h> 13 #include <time.h> 14 #include <unistd.h> 15 16 #define LOG_ENABLE true 17 #define PIPE_READ_END 0 18 #define PIPE_WRITE_END 1 19 #define DELAY_MS 100 20 21 #if true == LOG_ENABLE 22 #define LOG(fmt, ...) do { \ 23 printf("[LOG] "fmt"\n", ##__VA_ARGS__); \ 24 } while (0) 25 #define LOG_ID(fmt, ...) do { \ 26 printf("[LOG][%ld] "fmt"\n", proc_count, ##__VA_ARGS__); \ 27 } while (0) 28 #else 29 #define LOG(fmt, ...) 30 #define PROC_LOG(fmt, ...) 31 #endif 32 33 void sleep_ms(long ms) 34 { 35 struct timespec ts = { 36 .tv_sec = ms / 1000, 37 .tv_nsec = (ms % 1000) * 1000000L 38 }; 39 40 nanosleep(&ts, NULL); 41 } 42 43 /* 44 * Parent ===pipefd_1===> Child 45 * Parent <==pipefd_2==== Child 46 */ 47 48 int main (void) 49 { 50 int wstatus, cpid, proc_count; 51 int pipefd_1[2], pipefd_2[2]; 52 uint32_t ball; 53 54 proc_count = 0; 55 ball = 0; 56 57 if ((pipe(pipefd_1) == -1) || (pipe(pipefd_2) == -1)) 58 { 59 perror("pipe"); 60 exit(EXIT_FAILURE); 61 } 62 63 cpid = fork(); 64 65 if (cpid == -1) 66 { 67 perror("fork"); 68 exit(EXIT_FAILURE); 69 } 70 71 if (cpid == 0) 72 { 73 // Child 74 proc_count++; 75 LOG_ID("PID is %jd", (intmax_t) getpid()); 76 sleep_ms(DELAY_MS); 77 78 if (close(pipefd_1[PIPE_WRITE_END]) == -1) 79 { 80 // Close unused pipefd_1 write end 81 perror("close"); 82 exit(EXIT_FAILURE); 83 } 84 85 if (close(pipefd_2[PIPE_READ_END]) == -1) 86 { 87 // Close unused pipefd_2 read end 88 perror("close"); 89 exit(EXIT_FAILURE); 90 } 91 92 while (true) 93 { 94 // Wait for response from the other end 95 while (read(pipefd_1[PIPE_READ_END], &ball, sizeof(ball)) <= 0) 96 { 97 ; 98 } 99 sleep_ms(DELAY_MS); 100 101 ball++; 102 LOG_ID("%d", ball); 103 write(pipefd_2[PIPE_WRITE_END], &ball, sizeof(ball)); 104 } 105 106 exit(EXIT_SUCCESS); 107 } 108 else 109 { 110 // Parent 111 LOG_ID("PID is %jd", (intmax_t) getpid()); 112 sleep_ms(DELAY_MS); 113 114 if (close(pipefd_1[PIPE_READ_END]) == -1) 115 { 116 // Close unused pipefd_1 read end 117 perror("close"); 118 exit(EXIT_FAILURE); 119 } 120 121 if (close(pipefd_2[PIPE_WRITE_END]) == -1) 122 { 123 // Close unused pipefd_2 write end 124 perror("close"); 125 exit(EXIT_FAILURE); 126 } 127 128 while (true) 129 { 130 ball++; 131 LOG_ID("%d", ball); 132 write(pipefd_1[PIPE_WRITE_END], &ball, sizeof(ball)); 133 134 // Wait for response from the other end 135 while (read(pipefd_2[PIPE_READ_END], &ball, sizeof(ball)) <= 0) 136 { 137 ; 138 } 139 140 sleep_ms(DELAY_MS); 141 } 142 143 exit(EXIT_SUCCESS); 144 } 145 146 exit(EXIT_SUCCESS); 147 }
