From 7002c6b2327251432b8392098f1afa60c0968cb6 Mon Sep 17 00:00:00 2001
From: Santiago Lo Coco <slococo@itba.edu.ar>
Date: Sun, 5 Sep 2021 10:53:39 -0300
Subject: [PATCH] Add semi-functional master with 2N pipes

Co-authored-by: Juan Barmasch <jbarmasch@itba.edu.ar>
Co-authored-by: Ezequiel Bellver <ebellver@itba.edu.ar>
---
 masterV2.c | 267 +++++++++++++++++++++++++++++++++++++++++++++++++++++
 1 file changed, 267 insertions(+)
 create mode 100644 masterV2.c

diff --git a/masterV2.c b/masterV2.c
new file mode 100644
index 0000000..f6c0476
--- /dev/null
+++ b/masterV2.c
@@ -0,0 +1,267 @@
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+#include <unistd.h>
+#include <math.h>
+#include <sys/stat.h>
+#include <sys/time.h>
+#include <sys/types.h>
+#include <sys/select.h>
+#include <fcntl.h>
+#include "error.h"
+
+#define SLAVE_NUM 5
+#define MAX_SIZE 200
+
+void create(int pipesOutput[SLAVE_NUM][2], int pipesInput[SLAVE_NUM][2]);
+
+int main(int argc, char *argv[]) {
+    setvbuf(stdout, NULL, _IONBF, 0);
+
+    if (argc == 1)
+        printError("Error: no arguments provided");
+
+    int pipesOutput[SLAVE_NUM][2];
+    int pipesInput[SLAVE_NUM][2];
+    create(pipesOutput, pipesInput);
+    //sleep(1);
+
+    struct stat statBuf;
+
+    int tasks = 1, j = 0;
+
+    //for (j = 0; j < argc; j++)
+        //printf("MBOEANAS PUAN. %s\n", argv[j]);
+
+    for (; tasks < SLAVE_NUM && tasks < argc; tasks++) {
+        //printf("%s\n", argv[tasks]);
+        if (stat(argv[tasks], &statBuf) == -1) {
+            printf("%s\n", argv[tasks]);
+            printSystemError("Error, one of the specified paths is incorrect");
+        }
+
+        if (!S_ISREG(statBuf.st_mode))
+            continue;
+
+        if (write(pipesInput[j++][1], argv[tasks], strlen(argv[tasks]) + 1) < 0) {
+            printSystemError("write() -- ERROR oli");
+        }
+    }
+
+
+//    for (; arg < argc; arg++) {
+//        if (stat(argv[arg], &statBuf) == -1)
+//            printSystemError("Error, one of the specified paths is incorrect");
+//
+//        if (!S_ISREG(statBuf.st_mode))
+//            continue;
+//
+//        if (write(pipesInput[j++][1], argv[arg], strlen(argv[arg]) + 1) < 0) {
+//            printSystemError("write() -- ERROR");
+//        }
+//    }
+
+    char buf[MAX_SIZE];
+
+    fd_set pipesOutputSet;
+    FD_ZERO(&pipesOutputSet);
+    // int n = 0;
+    // if (tasks >= SLAVE_NUM)
+    //     for (; n < SLAVE_NUM; n++)
+    //         FD_SET(pipesOutput[n][0], &pipesOutputSet);
+    // else
+    //     for (; n < tasks; n++)
+    //         FD_SET(pipesOutput[n][0], &pipesOutputSet);
+
+    // int count;
+    // if ((count = select(pipesOutput[SLAVE_NUM - 1][0] + 1, &pipesOutputSet, NULL, NULL, NULL)) <= 0)
+    //     printSystemError("select() -- ERROR");
+
+    int r, readBytes, flag, count;
+    if (tasks == SLAVE_NUM) {
+        do {
+            int n;
+            flag = 0;
+            FD_ZERO(&pipesOutputSet);
+            for (n = 0; n < SLAVE_NUM; n++) {
+                if (pipesOutput[n][0] != -1) {
+                    FD_SET(pipesOutput[n][0], &pipesOutputSet);
+                    flag = 1;
+                }
+            }
+            if ((count = select(pipesOutput[SLAVE_NUM - 1][1] + 1, &pipesOutputSet, NULL, NULL, NULL)) <= 0)
+                printSystemError("select() -- ERROR");
+
+            for (r = 0; r < SLAVE_NUM && count > 0; r++) {
+                if (FD_ISSET(pipesOutput[r][0], &pipesOutputSet)) {
+                    readBytes = 0;
+                    do {
+                        if ((readBytes += read(pipesOutput[r][0], buf + readBytes, MAX_SIZE)) < 0)
+                            printSystemError("read() -- ERROR");
+                    } while (buf[readBytes - 1] != '\n');
+                    buf[readBytes] = 0;
+
+                    printf("\n%s\n", buf);
+                    count--;
+
+                    if (tasks < argc) {
+                        if (stat(argv[tasks], &statBuf) == -1)
+                            printSystemError("Error, one of the specified paths is incorrect");
+
+                        if (!S_ISREG(statBuf.st_mode))
+                            continue;
+
+                        if ((write(pipesInput[r][1], argv[tasks], strlen(argv[tasks]) + 1)) < 0)
+                            printSystemError("write() -- ERROR");
+
+                        tasks++;
+
+                    } else {
+                        close(pipesOutput[r][0]);
+                        close(pipesInput[r][1]);
+                        pipesOutput[r][0] = -1;
+                        pipesInput[r][0] = -1;
+                    }
+                }
+            }
+        } while(flag);
+    }
+    else {
+        int k;
+        for (k = tasks - 1; k < SLAVE_NUM; k++) {
+            close(pipesOutput[k][0]);
+            close(pipesInput[k][1]);
+            pipesOutput[k][0] = -1;
+            pipesInput[k][0] = -1;
+        }
+        do {
+            int n;
+            flag = 0;
+            FD_ZERO(&pipesOutputSet);
+            for (n = 0; n < tasks; n++) {
+                if (pipesOutput[n][0] != -1) {
+                    FD_SET(pipesOutput[n][0], &pipesOutputSet);
+                    flag = 1;
+                }
+            }
+
+            if (flag) {
+                if ((count = select(pipesOutput[tasks - 1][1] + 1, &pipesOutputSet, NULL, NULL, NULL)) <= 0)
+                    printSystemError("select() -- ERROR");
+
+                for (r = 0; r < SLAVE_NUM && count > 0; r++) {
+                    if (FD_ISSET(pipesOutput[r][0], &pipesOutputSet)) {
+                        readBytes = 0;
+                        do {
+                            if ((readBytes += read(pipesOutput[r][0], buf + readBytes, MAX_SIZE)) < 0)
+                                printSystemError("read() -- ERROR");
+                        } while (buf[readBytes - 1] != '\n');
+                        buf[readBytes] = 0;
+
+                        close(pipesOutput[r][0]);
+                        close(pipesInput[r][1]);
+                        pipesOutput[r][0] = -1;
+                        pipesInput[r][0] = -1;
+
+                        printf("\n%s\n", buf);
+                        count--;
+                    }
+                }
+            }
+        } while (flag);
+    }
+
+//    if (tasks >= SLAVE_NUM) {
+//        for (r = 0; r < SLAVE_NUM && count > 0; r++) {
+//            if (FD_ISSET(pipesOutput[r][0], &pipesOutputSet)) {
+//                readBytes = 0;
+//                do {
+//                    if ((readBytes += read(pipesOutput[r][0], buf + readBytes, MAX_SIZE)) < 0)
+//                        printSystemError("read() -- ERROR");
+//                } while (buf[readBytes - 1] != '\n');
+//                buf[readBytes] = 0;
+//                if (tasks < argc)
+//                    write(pipesInput[r][1], argv[tasks++], MAX_SIZE);
+//                else {
+//
+//                }
+//                printf("%s", buf);
+//                count--;
+//            }
+//        }
+//    }
+//    else {
+//        for (r = 0; r < tasks && count > 0; r++) {
+//            if (FD_ISSET(pipesOutput[r][0], &pipesOutputSet)) {
+//                readBytes = 0;
+//                do {
+//                    if ((readBytes += read(pipesOutput[r][0], buf + readBytes, MAX_SIZE)) < 0)
+//                        printSystemError("read() -- ERROR");
+//                } while (buf[readBytes - 1] != '\n');
+//                buf[readBytes] = 0;
+//                printf("%s", buf);
+//                count--;
+//            }
+//        }
+//    }
+
+
+//    int fd;
+//    char buf[MAX_SIZE];
+//    if ((fd = select(pipesOutput[SLAVE_NUM - 1][0] + 1, &pipesOutputSet, NULL, NULL, NULL)) < 0)
+//        printSystemError("select() -- ERROR");
+//
+//    int r = 0, readBytes;
+//    for (; r < SLAVE_NUM && fd > 0; r++) {
+//        if (FD_ISSET(pipesOutput[r][0], &pipesOutputSet)) {
+//            readBytes = 0;
+//            do {
+//                if ((readBytes += read(pipesOutput[r][0], buf + readBytes, MAX_SIZE)) < 0)
+//                    printSystemError("read() -- ERROR");
+//            } while (buf[readBytes - 1] != '\n');
+//            buf[readBytes] = 0;
+//            printf("%s", buf);
+//            fd--;
+//        }
+//    }
+    return 0;
+}
+
+//void (int pipesOutput[SLAVE_NUM][2], int pipesInput[SLAVE_NUM][2]) {
+
+void create(int pipesOutput[SLAVE_NUM][2], int pipesInput[SLAVE_NUM][2]) {
+    pid_t pid[SLAVE_NUM];
+
+    int i = 0;
+    for (; i < SLAVE_NUM; i++) {
+        if (pipe(pipesOutput[i]) < 0)
+            printSystemError("pipe() -- ERROR");
+        if (pipe(pipesInput[i]) < 0)
+            printSystemError("pipe() -- ERROR");
+        if ((pid[i] = fork()) == 0) {
+            if (close(pipesOutput[i][0]) < 0)
+                printSystemError("close() -- ERROR");
+            if (dup2(pipesOutput[i][1], STDOUT_FILENO) < 0)
+                printSystemError("dup2() -- ERROR 1");
+            if (close(pipesOutput[i][1]) < 0)
+                printSystemError("close() -- ERROR");
+
+            if (close(pipesInput[i][1]) < 0)
+                printSystemError("close() -- ERROR");
+            if (dup2(pipesInput[i][0], STDIN_FILENO) < 0)
+                printSystemError("dup2() -- ERROR 2");
+            if (close(pipesInput[i][0]) < 0)
+                printSystemError("close() -- ERROR");
+
+            if (execv("slave.o", NULL) < 0)
+                printSystemError("execv() -- ERROR");
+        }
+        else if (pid[i] < 0)
+            printSystemError("fork() -- ERROR");
+
+        if (close(pipesInput[i][0]) < 0)
+            printSystemError("close() -- ERROR");
+        if (close(pipesOutput[i][1]) < 0)
+            printSystemError("close() -- ERROR");
+    }
+}