Advertisement
djk77

git

Apr 1st, 2020
118
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
text 10.76 KB | None | 0 0
  1. #include <stdlib.h>
  2. #include <unistd.h>
  3. #include <stdio.h>
  4. #include <sys/types.h>
  5. #include <sys/wait.h>
  6. #include <getopt.h>
  7. #include <string.h>
  8. #include <time.h>
  9. #include <errno.h>
  10. #include "ipc.h"
  11. #include "pa1.h"
  12. #include "common.h"
  13.  
  14. #define MAX_NUM_OF_PROCESSES 10
  15.  
  16. static const char * const log_opened_fmt =
  17. "Pipe (input %5d, output %5d) was opened\n";
  18.  
  19. static const char * const log_closed_fmt =
  20. "Pipe %5d in process %5d was closed\n";
  21.  
  22. static const char * const log_read_fmt =
  23. "Pipe (input %5d, output %5d) in process %5d read %5d bytes\n";
  24.  
  25. static const char * const log_write_fmt =
  26. "Pipe (input %5d, output %5d) in process %5d write %5d bytes\n";
  27.  
  28. typedef struct{
  29. int in;
  30. int out;
  31. } Pipe;
  32.  
  33. typedef struct{
  34. int numOfChildren;
  35. local_id id;
  36. Pipe *pipes[MAX_NUM_OF_PROCESSES + 1][MAX_NUM_OF_PROCESSES + 1];
  37. } IO;
  38.  
  39. int send(void * self, local_id dst, const Message * msg){
  40. IO *inout = (IO*)self;
  41. int fd = inout -> pipes[inout -> id][dst] -> out;
  42. if (write(fd, msg, msg->s_header.s_payload_len + sizeof(MessageHeader)) == -1)
  43. return errno;
  44. else return 0;
  45. }
  46.  
  47. int send_multicast(void * self, const Message * msg){
  48. IO *inout = (IO*)self;
  49. for (int i = 0; i < inout -> numOfChildren + 1; i++){
  50. if (i != inout -> id){
  51. int fd = inout -> pipes[inout -> id][i] -> out;
  52. int sum;
  53. switch(sum = write(fd, msg, msg -> s_header.s_payload_len + sizeof(MessageHeader))){
  54. case -1: return errno;
  55. default:
  56. printf(log_write_fmt, inout -> pipes[inout -> id][i] -> in, inout -> pipes[inout -> id][i] -> out, inout -> id, sum);
  57. break;
  58. }
  59. }
  60. }
  61. return 0;
  62. }
  63.  
  64. int receive(void * self, local_id from, Message * msg){
  65. IO *inout = (IO*)self;
  66. int fd = inout -> pipes[from][inout -> id] -> in;
  67. int sum, sum1;
  68. if ((sum = read(fd, &msg -> s_header, sizeof(MessageHeader))) == -1) return errno;
  69. printf(log_read_fmt, inout -> pipes[from][inout -> id] -> in, inout -> pipes[from][inout -> id] -> out, inout -> id, sum);
  70. if (msg -> s_header.s_payload_len > 0) {
  71. sum1 = read(fd, msg->s_payload, msg->s_header.s_payload_len);
  72. printf(log_read_fmt, inout -> pipes[from][inout -> id] -> in, inout -> pipes[from][inout -> id] -> out, inout -> id, sum1);
  73. }
  74. return 0;
  75. }
  76.  
  77. //wrong, must be released with fcntl(2)
  78. int receive_any(void * self, Message * msg){
  79. IO *inout = (IO*)self;
  80. while(1){
  81. for (int i = 0; i < inout -> numOfChildren + 1; i++){
  82. if (i != inout -> id - 1){
  83. int fd = inout -> pipes[i][inout -> id] -> in;
  84. int cur = lseek(fd, 0, SEEK_CUR);
  85. int end = lseek(fd, 0, SEEK_END);
  86. lseek(fd, cur, SEEK_SET);
  87. if (end > cur) {
  88. if (read(fd, msg, msg->s_header.s_payload_len) == -1)
  89. return errno;
  90. else return 0;
  91. }
  92. }
  93. }
  94. }
  95. }
  96.  
  97. int main(int argc, char *argv[]){
  98.  
  99. // create an IO structure
  100. IO *inout = (IO*)malloc(sizeof(IO));
  101.  
  102. // number of child processes from command line to numOfChildren variable
  103. int opt;
  104. while ( (opt = getopt(argc,argv,"p:")) != -1){
  105. switch (opt){
  106. case 'p': inout -> numOfChildren = atoi(optarg); break;
  107. default:
  108. free(inout);
  109. return -1;
  110. }
  111. }
  112.  
  113. inout -> id = PARENT_ID;
  114.  
  115. // create or open logs for writing
  116. FILE *pipesLog = fopen(pipes_log, "w+");
  117. FILE *eventsLog = fopen(events_log, "w+");
  118.  
  119. // create pipes and fill the inout.pipes
  120. for (int i = 0; i < inout -> numOfChildren + 1; i++){
  121. for (int j = 0; j < inout -> numOfChildren + 1; j++){
  122. if (i != j){
  123. Pipe *pipeMem = (Pipe*)malloc(sizeof(Pipe));
  124. int pipefd[2];
  125. pipe(pipefd);
  126. pipeMem -> in = pipefd[0];
  127. pipeMem -> out = pipefd[1];
  128. inout -> pipes[i][j] = pipeMem;
  129. fprintf(pipesLog, log_opened_fmt, pipefd[0], pipefd[1]);
  130. fflush(pipesLog);
  131. printf(log_opened_fmt, pipefd[0], pipefd[1]);
  132. }
  133. }
  134. }
  135.  
  136. Message *msgReceive = (Message*)malloc(sizeof(Message));
  137.  
  138. // create children
  139. for (int id = 1; id < inout -> numOfChildren + 1; id++){
  140. switch(fork()){
  141. case -1:
  142. perror("fork");
  143. exit(1);
  144. case 0:
  145. fprintf(eventsLog, log_started_fmt, id, getpid(), getppid());
  146. fflush(eventsLog);
  147. printf(log_started_fmt, id, getpid(), getppid());
  148.  
  149. inout -> id = id;
  150.  
  151. // close unused pipes
  152. for (int i = 0; i < inout -> numOfChildren + 1; i++){
  153. for (int j = 0; j < inout -> numOfChildren + 1; j++){
  154. if (i != j){
  155. if (i != inout -> id && j != inout -> id){
  156. close(inout -> pipes[i][j] -> in);
  157. fprintf(pipesLog, log_closed_fmt, inout -> pipes[i][j] -> in, inout -> id);
  158. fflush(pipesLog);
  159. printf(log_closed_fmt, inout -> pipes[i][j] -> in, inout -> id);
  160. close(inout -> pipes[i][j] -> out);
  161. fprintf(pipesLog, log_closed_fmt, inout -> pipes[i][j] -> out, inout -> id);
  162. fflush(pipesLog);
  163. printf(log_closed_fmt, inout -> pipes[i][j] -> out, inout -> id);
  164. }
  165. if (i == inout -> id){
  166. close(inout -> pipes[i][j] -> in);
  167. fprintf(pipesLog, log_closed_fmt, inout -> pipes[i][j] -> in, inout -> id);
  168. fflush(pipesLog);
  169. printf(log_closed_fmt, inout -> pipes[i][j] -> in, inout -> id);
  170. }
  171. if (j == inout -> id){
  172. close(inout -> pipes[i][j] -> out);
  173. fprintf(pipesLog, log_closed_fmt, inout -> pipes[i][j] -> out, inout -> id);
  174. fflush(pipesLog);
  175. printf(log_closed_fmt, inout -> pipes[i][j] -> out, inout -> id);
  176. }
  177.  
  178. }
  179.  
  180. }
  181. }
  182.  
  183. // fill the STARTED message
  184. Message *msg = (Message*)malloc(sizeof(Message));
  185. sprintf(msg -> s_payload, log_started_fmt, id, getpid(), getppid());
  186. msg -> s_header.s_magic = MESSAGE_MAGIC;
  187. msg -> s_header.s_payload_len = strlen(msg -> s_payload)+1;
  188. msg -> s_header.s_type = STARTED;
  189. msg -> s_header.s_local_time = time(NULL);
  190.  
  191. // send STARTED message to other processes
  192. send_multicast(inout, msg);
  193.  
  194. // receive STARTED message from other processes
  195. for (int i = 1; i < inout -> numOfChildren + 1; i++){
  196. if (i != inout -> id){
  197. do{
  198. receive(inout, i, msgReceive);
  199. } while (msgReceive -> s_header.s_type != STARTED);
  200. }
  201. }
  202.  
  203. // logs
  204. fprintf(eventsLog, log_received_all_started_fmt, inout -> id);
  205. fflush(eventsLog);
  206. printf(log_received_all_started_fmt, inout -> id);
  207.  
  208. // fill the DONE message
  209. sprintf(msg -> s_payload, log_done_fmt, inout -> id);
  210. msg -> s_header.s_magic = MESSAGE_MAGIC;
  211. msg -> s_header.s_payload_len = strlen(msg -> s_payload)+1;
  212. msg -> s_header.s_type = DONE;
  213. msg -> s_header.s_local_time = time(NULL);
  214. //msg -> s_header = *head;
  215.  
  216. // send STARTED message to other processes
  217. send_multicast(inout, msg);
  218.  
  219. // receive STARTED message from other processes
  220. for (int i = 1; i < inout -> numOfChildren + 1; i++){
  221. if (i != inout -> id){
  222. do{
  223. receive(inout, i, msgReceive);
  224. } while (msgReceive -> s_header.s_type != DONE);
  225. }
  226. }
  227.  
  228. // logs
  229. fprintf(eventsLog, log_received_all_done_fmt, inout -> id);
  230. fflush(eventsLog);
  231. printf(log_received_all_done_fmt, inout -> id);
  232.  
  233. // close all other pipes
  234. for (int i = 0; i < inout -> numOfChildren + 1; i++){
  235. for (int j = 0; j < inout -> numOfChildren + 1; j++){
  236. if (i != j){
  237. if (i == inout -> id){
  238. close(inout -> pipes[i][j] -> out);
  239. fprintf(pipesLog, log_closed_fmt, inout -> pipes[i][j] -> out, inout -> id);
  240. fflush(pipesLog);
  241. printf(log_closed_fmt, inout -> pipes[i][j] -> out, inout -> id);
  242. }
  243. if (j == inout -> id){
  244. close(inout -> pipes[i][j] -> in);
  245. fprintf(pipesLog, log_closed_fmt, inout -> pipes[i][j] -> in, inout -> id);
  246. fflush(pipesLog);
  247. printf(log_closed_fmt, inout -> pipes[i][j] -> in, inout -> id);
  248.  
  249. }
  250. }
  251. }
  252. }
  253.  
  254. for (int i = 0; i < inout -> numOfChildren + 1; i++){
  255. for (int j = 0; j < inout -> numOfChildren + 1; j++){
  256. if (i != j) free(inout -> pipes[i][j]);
  257. }
  258. }
  259. free(msg);
  260. fprintf(eventsLog, log_done_fmt, inout -> id);
  261. fflush(eventsLog);
  262. printf(log_done_fmt, inout -> id);
  263. return 0;
  264. default:
  265. break;
  266. }
  267. }
  268.  
  269. for (int i = 0; i < inout -> numOfChildren + 1; i++){
  270. for (int j = 0; j < inout -> numOfChildren + 1; j++){
  271. if (i != j){
  272. if (i != PARENT_ID && j != PARENT_ID){
  273. close(inout -> pipes[i][j] -> in);
  274. fprintf(pipesLog, log_closed_fmt, inout -> pipes[i][j] -> in, inout -> id);
  275. fflush(pipesLog);
  276. printf(log_closed_fmt, inout -> pipes[i][j] -> in, inout -> id);
  277. close(inout -> pipes[i][j] -> out);
  278. fprintf(pipesLog, log_closed_fmt, inout -> pipes[i][j] -> out, inout -> id);
  279. fflush(pipesLog);
  280. printf(log_closed_fmt, inout -> pipes[i][j] -> out, inout -> id);
  281. }
  282. if (i == PARENT_ID){
  283. close(inout -> pipes[i][j] -> in);
  284. fprintf(pipesLog, log_closed_fmt, inout -> pipes[i][j] -> in, inout -> id);
  285. fflush(pipesLog);
  286. printf(log_closed_fmt, inout -> pipes[i][j] -> in, inout -> id);
  287. }
  288. if (j == PARENT_ID){
  289. close(inout -> pipes[i][j] -> out);
  290. fprintf(pipesLog, log_closed_fmt, inout -> pipes[i][j] -> out, inout -> id);
  291. fflush(pipesLog);
  292. printf(log_closed_fmt, inout -> pipes[i][j] -> out, inout -> id);
  293. }
  294. }
  295. }
  296. }
  297.  
  298. for (int i = 1; i < inout -> numOfChildren + 1; i++){
  299. if (i != inout -> id){
  300. do{
  301. receive(inout, i, msgReceive);
  302. } while (msgReceive -> s_header.s_type != STARTED);
  303. }
  304. }
  305. fprintf(eventsLog, log_received_all_started_fmt, inout -> id);
  306. fflush(eventsLog);
  307. printf(log_received_all_started_fmt, inout -> id);
  308. for (int i = 1; i < inout -> numOfChildren + 1; i++){
  309. if (i != inout -> id){
  310. do{
  311. receive(inout, i, msgReceive);
  312. } while (msgReceive -> s_header.s_type != DONE);
  313. }
  314. }
  315. fprintf(eventsLog, log_received_all_done_fmt, inout -> id);
  316. fflush(eventsLog);
  317. printf(log_received_all_done_fmt, inout -> id);
  318. for (int i = 0; i < inout -> numOfChildren + 1; i++){
  319. for (int j = 0; j < inout -> numOfChildren + 1; j++){
  320. if (i != j){
  321. if (i == PARENT_ID){
  322. close(inout -> pipes[i][j] -> out);
  323. fprintf(pipesLog, log_closed_fmt, inout -> pipes[i][j] -> out, inout -> id);
  324. fflush(pipesLog);
  325. printf(log_closed_fmt, inout -> pipes[i][j] -> out, inout -> id);
  326. }
  327. if (j == PARENT_ID){
  328. close(inout -> pipes[i][j] -> in);
  329. fprintf(pipesLog, log_closed_fmt, inout -> pipes[i][j] -> in, inout -> id);
  330. fflush(pipesLog);
  331. printf(log_closed_fmt, inout -> pipes[i][j] -> in, inout -> id);
  332. }
  333. }
  334. }
  335. }
  336. for (int i = 0; i < inout -> numOfChildren; i++)
  337. wait(NULL);
  338. free(inout);
  339. free(msgReceive);
  340. fclose(pipesLog);
  341. fclose(eventsLog);
  342. return 0;
  343. }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement