From 2ff817394d16f19d286c29e7d19fc96124570824 Mon Sep 17 00:00:00 2001 From: Santiago Lo Coco Date: Fri, 10 Sep 2021 20:47:36 -0300 Subject: [PATCH] Create a more modularized code Co-authored-by: Ezequiel Bellver Co-authored-by: Juan Barmasch --- Makefile | 18 ++++--- README.md | 22 ++++++--- error.c | 4 ++ master.c | 144 ++++++++++++++++++++---------------------------------- master.h | 16 ++++++ shr_mem.c | 78 +++++++++++++++++------------ shr_mem.h | 14 ++++-- siglib.c | 47 ++++++++++++++++++ siglib.h | 10 ++++ slave.c | 36 ++++---------- view.c | 56 +++++++-------------- 11 files changed, 241 insertions(+), 204 deletions(-) create mode 100644 master.h create mode 100644 siglib.c create mode 100644 siglib.h diff --git a/Makefile b/Makefile index 1eeb68e..84ab7bc 100644 --- a/Makefile +++ b/Makefile @@ -1,7 +1,7 @@ CC = gcc CCFLAGS = -Wall -std=c99 -pedantic -g -OBJECTS = master.o error.o slave.o shr_mem.o view.o solve view +OBJECTS = master.o error.o slave.o shr_mem.o view.o siglib.o solve view all: $(OBJECTS) @@ -15,10 +15,12 @@ shr_mem.o: shr_mem.c error.h $(CC) $(CCFLAGS) -c shr_mem.c view.o: view.c $(CC) $(CCFLAGS) -c view.c -solve: master.o error.o shr_mem.o - $(CC) $(CCFLAGS) -o solve master.o error.o shr_mem.o -lrt -lpthread -view: view.o error.o shr_mem.o - $(CC) $(CCFLAGS) -o view view.o error.o shr_mem.o -lrt -lpthread +siglib.o: siglib.c + $(CC) $(CCFLAGS) -c siglib.c +solve: master.o error.o shr_mem.o siglib.o + $(CC) $(CCFLAGS) -o solve master.o error.o shr_mem.o siglib.o -lm -lrt -lpthread +view: view.o error.o shr_mem.o siglib.o + $(CC) $(CCFLAGS) -o view view.o error.o shr_mem.o siglib.o -lrt -lpthread clean: rm -rf $(OBJECTS) @@ -28,9 +30,9 @@ test: pvs-studio-analyzer analyze plog-converter -a '64:1,2,3;GA:1,2,3;OP:1,2,3' -t tasklist -o report.tasks PVS-Studio.log cppcheck --quiet --enable=all --force --inconclusive . - valgrind --leak-check=full ./solve > valgrindSolve.output 2>&1 - valgrind --leak-check=full ./view ~ > valgrindView.output 2>&1 - valgrind --leak-check=full ./slave ~ > valgrindSlave.output 2>&1 + valgrind --leak-check=full --track-origins=yes ./solve HardTest/*.cnf > valgrindSolve.output 2>&1 + ./solve HardTest/*.cnf | valgrind --leak-check=full --show-leak-kinds=all ./view > valgrindView.output 2>&1 + valgrind --leak-check=full ./slave > valgrindSlave.output 2>&1 < Test/*.cnf .PHONY: all clean test diff --git a/README.md b/README.md index 7c41879..333cd97 100644 --- a/README.md +++ b/README.md @@ -3,8 +3,13 @@ BSSolver (Bottler Sat Solver) es un sistema que resuelve múltiples fórmulas proposicionales en CNF de forma distribuida. +## Table de contenidos +* [Requisitos](#requisitos) +* [Compilación](#compilación) +* [Ejecución](#ejecución) +* [Testeos](#tests) -## Requisitos +## Requisitos Debe instalar minisat. Este se encuentra disponible en el repositorio de la vasta mayoría de distribuciones de Linux/macOS. @@ -13,7 +18,7 @@ macOS (con [homebrew](https://brew.sh/)): `brew install minisat` Si tiene otra distribución consulte cómo hacerlo. -## Compilación +## Compilación Para compilar todos los archivos se debe hacer: @@ -21,7 +26,7 @@ Para compilar todos los archivos se debe hacer: make all ``` -## Ejecución +## Ejecución Ahora, tendrá dos ejecutables: `view` y `solve`. @@ -32,7 +37,7 @@ Para ejecutar el programa que se encarga de resolver usted debe pasarle los arch ``` Este enviará por salida estándar la cantidad de archivos a resolver y su PID, los cuales son necesarios para el programa `view`. Por lo tanto, usted tiene dos posibles modos de uso del sistema: -1) Enviar el output de solve directamente a view (con el uso de pipes): +1) Enviar el output de `solve` directamente a `view` (con el uso de pipes): ```bash ./solve $(CNF_FILES) | ./view @@ -46,9 +51,14 @@ Este enviará por salida estándar la cantidad de archivos a resolver y su PID, ```bash ./view $(TOTAL_FILES) $(PID) ``` -Debe notar que dispondrá de 5 segundos para correr el programa `view`. -## Test +3) No correr el proceso `view`. + +Debe notar que en todos los casos se escribirá el output un archivo llamado `ouputFile.txt`. + +Además, dispondrá de 5 segundos para correr el programa `view`. + +## Testeos En orden de realizar los testeos usted debe tener instalado [valgrind](https://valgrind.org/), [cppcheck](http://cppcheck.net/) y [pvs-studio](https://pvs-studio.com/). Luego, puede correr los testeos con: diff --git a/error.c b/error.c index d0a814d..aa4e0fc 100644 --- a/error.c +++ b/error.c @@ -1,3 +1,7 @@ +/* +This is a personal academic project. Dear PVS-Studio, please check it. +PVS-Studio Static Code Analyzer for C, C++ and C#: http://www.viva64.com +*/ #include #include diff --git a/master.c b/master.c index df29ee7..86a04eb 100644 --- a/master.c +++ b/master.c @@ -1,6 +1,9 @@ +/* +This is a personal academic project. Dear PVS-Studio, please check it. +PVS-Studio Static Code Analyzer for C, C++ and C#: http://www.viva64.com +*/ #define _SVID_SOURCE 1 //#define _DEFAULT_SOURCE 1 - #define _XOPEN_SOURCE 500 #define _POSIX_C_SOURCE 2 @@ -8,150 +11,108 @@ #include #include #include -#include #include -#include #include #include -#include -#include #include "error.h" #include "shr_mem.h" -#include -#include -#include -#include - -#define SLAVE_NUM 5 -#define MAX_SIZE 300 -#define MAX_PATH_SIZE 100 -#define MAX_OUTPUT_SIZE (200 + MAX_PATH_SIZE) - -void createPipes(int pipesOutput[SLAVE_NUM][2], int pipesInput[SLAVE_NUM][2]); -int writeOutput(char * output, FILE * outputFile, void * shmP, char viewLinked); -void closePipes(int pipesInput[SLAVE_NUM][2], int pipesOutput[SLAVE_NUM][2], int slave); -char sendTask(struct stat statBuf, char * fileName, int pipesInput[SLAVE_NUM][2], int slave); -void changeViewFlag(); +#include +#include "master.h" +#include "siglib.h" static char viewLinked = 0; +int slaveNum; + int main(int argc, char *argv[]) { if (setvbuf(stdout, NULL, _IONBF, 0) != 0) printSystemError("setvbuf() -- ERROR"); if (argc == 1) - printError("Error: no arguments provided"); + printError("No arguments provided -- ERROR"); - //sem_unlink("/EMPTY"); + slaveNum = floor(log2(argc - 1) * 2); + slaveNum = (slaveNum < MAX_SLAVES ? slaveNum : MAX_SLAVES); FILE * outputFile; - if ((outputFile = fopen("outputFile.txt", "w")) == NULL) + if ((outputFile = fopen(OUTPUT_NAME, "w")) == NULL) printSystemError("fopen() -- ERROR"); - char * shmPointer; - int shmFd; - shmFd = createShm((argc - 1) * MAX_OUTPUT_SIZE, &shmPointer); - void * shmStart; + char * shmPointer, * shmStart; + int totalSize = (argc - 1) * MAX_OUTPUT_SIZE; + int shmFd = createShm(totalSize); - printf("%d\n", argc - 1); - printf("%d\n", getpid()); - - struct sigaction sigAct; - sigAct.sa_handler = changeViewFlag; - sigAct.sa_flags = 0; - if (sigaction(SIGUSR1, &sigAct, NULL) == -1) - printSystemError("sigaction() -- ERROR"); + printf("%d\n%d\n", argc - 1, getpid()); + addSignalHandler(changeViewFlag); sleep(5); + blockSignal(); - /* - char * shmPointer; - int shmFd; - void * shmStart; - */ if (viewLinked) { - shmPointer = mmap(0, (argc - 1) * MAX_OUTPUT_SIZE, PROT_READ | PROT_WRITE, MAP_SHARED, shmFd, 0); - //shmFd = createShm((argc - 1) * MAX_OUTPUT_SIZE, &shmPointer); + mapShm(&shmPointer, totalSize, shmFd); shmStart = shmPointer; - //close(shmFd); } - int pipesOutput[SLAVE_NUM][2], pipesInput[SLAVE_NUM][2]; - createPipes(pipesOutput, pipesInput); + int pipesOutput[slaveNum][2], pipesInput[slaveNum][2]; + createPipesAndSlaves(pipesOutput, pipesInput); - struct stat statBuf; int tasks = 1; - for (int j = 0; tasks <= SLAVE_NUM && tasks < argc; tasks++) { - if (sendTask(statBuf, argv[tasks], pipesInput, j++) == 0) + for (int j = 0; tasks <= slaveNum && tasks < argc; tasks++) { + if (sendTask(argv[tasks], pipesInput, j++) == 0) continue; } - char buf[MAX_SIZE]; - fd_set pipesOutputSet; FD_ZERO(&pipesOutputSet); - int r, readBytes, flag, count; - if (tasks != SLAVE_NUM) { - for (int k = tasks - 1; k < SLAVE_NUM; k++) { - closePipes(pipesInput, pipesOutput, k); + char buf[MAX_SIZE], flag; + int r, readBytes, count; + if (tasks < slaveNum) { + for (int k = tasks - 1; k < slaveNum; k++) { + closePipes(pipesInput, pipesOutput, k, &pipesOutputSet); } } do { flag = 0; FD_ZERO(&pipesOutputSet); - for (int n = 0; n < SLAVE_NUM; n++) { + for (int n = 0; n < slaveNum; n++) { if (pipesOutput[n][0] != -1) { FD_SET(pipesOutput[n][0], &pipesOutputSet); flag = 1; } } if (flag) { - if ((count = select(pipesOutput[SLAVE_NUM - 1][1] + 1, &pipesOutputSet, NULL, NULL, NULL)) <= 0) + if ((count = select(pipesOutput[slaveNum - 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; + for (r = 0; r < slaveNum && count > 0; r++) { + if (FD_ISSET(pipesOutput[r][0], &pipesOutputSet) && pipesOutput[r][0] != -1) { + if ((readBytes = read(pipesOutput[r][0], buf, MAX_SIZE)) < 0) + printSystemError("read() -- ERROR"); + buf[readBytes] = '\0'; - // printf("\n%s\n", buf); - shmPointer += writeOutput(buf, outputFile, shmPointer, viewLinked); + shmPointer += writeOutput(buf, outputFile, shmPointer, r); count--; if (tasks < argc) { - if (sendTask(statBuf, argv[tasks++], pipesInput, r) == 0) + if (sendTask(argv[tasks++], pipesInput, r) == 0) continue; } else { - closePipes(pipesInput, pipesOutput, r); + closePipes(pipesInput, pipesOutput, r, &pipesOutputSet); } } } } } while (flag); - //sleep(5); - fclose(outputFile); - - for (int i = 0; i < SLAVE_NUM; i++){ - if (wait(NULL) == -1) - printSystemError("wait() -- ERROR"); - } - - sigset_t set; - sigaddset(&set, SIGUSR2); + if (fclose(outputFile) == EOF) + printSystemError("fclose() -- ERROR"); if (viewLinked) { - int temp = 0; - sigwait(&set, &temp); - terminateShm("/BottlerSHM", shmFd, shmStart, (argc - 1) * MAX_OUTPUT_SIZE); + waitForSignal(); + terminateShm(SHM_NAME, shmFd, shmStart, totalSize); closeSem(); } - //close(shmFd); return EXIT_SUCCESS; } @@ -159,7 +120,8 @@ void changeViewFlag() { viewLinked = 1; } -char sendTask(struct stat statBuf, char * fileName, int pipesInput[SLAVE_NUM][2], int slave) { +char sendTask(char * fileName, int pipesInput[slaveNum][2], int slave) { + struct stat statBuf; if (stat(fileName, &statBuf) == -1) printSystemError("Error, one of the specified paths is incorrect"); @@ -172,17 +134,19 @@ char sendTask(struct stat statBuf, char * fileName, int pipesInput[SLAVE_NUM][2] return EXIT_SUCCESS; } -void closePipes(int pipesInput[SLAVE_NUM][2], int pipesOutput[SLAVE_NUM][2], int slave) { +void closePipes(int pipesInput[][2], int pipesOutput[][2], int slave, fd_set * set) { +// FD_CLR(pipesOutput[slave][0], set); + if (close(pipesOutput[slave][0]) < 0) - printSystemError("close() -- ERROR"); + printSystemError("close1() -- ERROR"); if (close(pipesInput[slave][1]) < 0) - printSystemError("close() -- ERROR"); + printSystemError("close2() -- ERROR"); pipesOutput[slave][0] = -1; pipesInput[slave][0] = -1; } -int writeOutput(char * output, FILE * outputFile, void * shmPointer, char viewLinked) { +int writeOutput(char * output, FILE * outputFile, char * shmPointer, int i) { int length = strlen(output); if (fwrite(output, sizeof(char), length, outputFile) != length) @@ -194,10 +158,10 @@ int writeOutput(char * output, FILE * outputFile, void * shmPointer, char viewLi return length; } -void createPipes(int pipesOutput[SLAVE_NUM][2], int pipesInput[SLAVE_NUM][2]) { - pid_t pid[SLAVE_NUM]; +void createPipesAndSlaves(int pipesOutput[slaveNum][2], int pipesInput[slaveNum][2]) { + pid_t pid[slaveNum]; - for (int i = 0; i < SLAVE_NUM; i++) { + for (int i = 0; i < slaveNum; i++) { if (pipe(pipesOutput[i]) < 0) printSystemError("pipe() -- ERROR"); if (pipe(pipesInput[i]) < 0) diff --git a/master.h b/master.h new file mode 100644 index 0000000..7a0a944 --- /dev/null +++ b/master.h @@ -0,0 +1,16 @@ +#ifndef MASTER_H +#define MASTER_H + +#define MAX_SLAVES 500 +#define MAX_SIZE 300 +#define MAX_PATH_SIZE 100 +#define MAX_OUTPUT_SIZE (200 + MAX_PATH_SIZE) +#define OUTPUT_NAME "outputFile.txt" + +void createPipesAndSlaves(int pipesOutput[][2], int pipesInput[][2]); +int writeOutput(char * output, FILE * outputFile, char * shmPointers, int cacaDeEzequiel); +void closePipes(int pipesInput[][2], int pipesOutput[][2], int slave, fd_set * set); +char sendTask(char * fileName, int pipesInput[][2], int slave); +void changeViewFlag(); + +#endif \ No newline at end of file diff --git a/shr_mem.c b/shr_mem.c index b6184d5..480c8e9 100644 --- a/shr_mem.c +++ b/shr_mem.c @@ -1,65 +1,71 @@ +/* +This is a personal academic project. Dear PVS-Studio, please check it. +PVS-Studio Static Code Analyzer for C, C++ and C#: http://www.viva64.com +*/ #define _SVID_SOURCE 1 -//#define _DEFAULT_SOURCE 1 #define _POSIX_C_SOURCE 200112L -#include #include #include #include #include -#include "shr_mem.h" #include "error.h" #include #include #include -#include +#include "shr_mem.h" sem_t * sem = NULL; -int createShm(int totalSize, void ** shmPointer) { +int createShm(int totalSize) { int fd; - if ((fd = shm_open("/BottlerSHM", O_CREAT | O_RDWR, S_IRWXU)) < 0) + if ((fd = shm_open(SHM_NAME, O_CREAT | O_RDWR, S_IRWXU)) < 0) printSystemError("shm_open() -- ERROR"); ftruncate(fd, totalSize); - //* shmPointer = mmap(0, totalSize, PROT_READ | PROT_WRITE, MAP_SHARED, fd, 0); return fd; } -int writeShm(void * shmPointer, char * str, int len) { - if (sem == NULL) { - if ((sem = sem_open("/EMPTY", O_CREAT | O_RDWR, S_IRWXU, 0)) == SEM_FAILED) - printSystemError("sem_open() -- ERROR"); - } +void mapShm(char ** shmPointer, int totalSize, int fd) { + if ((* shmPointer = mmap(0, totalSize, PROT_READ | PROT_WRITE, MAP_SHARED, fd, 0)) == MAP_FAILED) + printSystemError("mmap() -- ERROR"); +} + +void writeShm(char * shmPointer, char * str, int len) { + openSem(); + if (memcpy(shmPointer, str, len) == NULL) printError("memcpy() -- ERROR"); if (sem_post(sem) < 0) printSystemError("sem_post() -- ERROR"); - - return EXIT_SUCCESS; } -void terminateShm(const char * name, int fd, void * shmPointer, int totalSize) { +void terminateShm(const char * name, int fd, char * shmPointer, int totalSize) { if (munmap(shmPointer, totalSize) == -1) printSystemError("munmap() -- ERROR"); if (shm_unlink(name) == -1) printSystemError("shm_unlink() -- ERROR"); if (close(fd) == -1) printSystemError("close() -- ERROR"); - return; +} + +void openSem() { + if (sem == NULL) { + if ((sem = sem_open(SEM_NAME, O_CREAT | O_RDWR, S_IRWXU, 0)) == SEM_FAILED) + printSystemError("sem_open() -- ERROR"); + } } void closeSem() { if (sem_close(sem) < 0) printSystemError("sem_close() -- ERROR"); - if (sem_unlink("/EMPTY") < 0) + if (sem_unlink(SEM_NAME) < 0) printSystemError("sem_unlink() -- ERROR"); } int copyShm(char * destPointer, char * srcPointer, int len) { int i; - //for (i = 0; srcPointer[i] != '\0' && i < len; i++) { - for (i = 0; srcPointer[i] != '\n' && srcPointer[i] != '\0' && i < len; i++) { + for (i = 0; i < len && srcPointer[i] != '\n' && srcPointer[i] != '\0'; i++) { destPointer[i] = srcPointer[i]; } destPointer[i++] = '\0'; @@ -68,20 +74,28 @@ int copyShm(char * destPointer, char * srcPointer, int len) { } int readShm(char * shmPointer, char * str, int len) { - if (sem == NULL) { - if ((sem = sem_open("/EMPTY", O_CREAT | O_RDWR, S_IRWXU, 0)) == SEM_FAILED) - printSystemError("sem_open() -- ERROR"); - } + openSem(); + if (sem_wait(sem) < 0) printSystemError("sem_wait() -- ERROR"); - int copied = copyShm(str, shmPointer, len); - - // Creo que es lo mismo si hacemos: - /* - memcpy(str, shmPointer, len); - *shmPointer += len; - */ - - return copied; + return copyShm(str, shmPointer, len); +} + +int openCreatedShm(char ** shmPointer, int totalSize) { + int fd; + if ((fd = shm_open(SHM_NAME, O_RDONLY, S_IRUSR)) < 0) + printSystemError("shm_open() -- ERROR"); + + if ((* shmPointer = mmap(0, totalSize, PROT_READ, MAP_SHARED, fd, 0)) == MAP_FAILED){ + printSystemError("mmap() -- ERROR"); + } + return fd; +} + +void closeCreatedShm(char * shmPointer, int totalSize, int fd) { + if (munmap(shmPointer, totalSize) == -1) + printSystemError("munmap() -- ERROR"); + if (close(fd) < 0) + printSystemError("close() -- ERROR"); } diff --git a/shr_mem.h b/shr_mem.h index 0196015..6497bd1 100644 --- a/shr_mem.h +++ b/shr_mem.h @@ -1,11 +1,17 @@ #ifndef SHR_MEM #define SHR_MEM -int createShm(); -char * attachShm(int shmId); -int writeShm(void * address, char * str, int len); +#define SHM_NAME "/BottlerSHM" +#define SEM_NAME "/EmptySEM" + +int createShm(int totalSize); +void mapShm(char ** shmPointer, int totalSize, int fd); +void writeShm(char * address, char * str, int len); int readShm(char * address, char * str, int len); -void terminateShm(const char * name, int fd, void * shmPointer, int totalSize); +void terminateShm(const char * name, int fd, char * shmPointer, int totalSize); +void openSem(); void closeSem(); +int openCreatedShm(char ** shmPointer, int totalSize); +void closeCreatedShm(char * shmPointer, int totalSize, int fd); #endif diff --git a/siglib.c b/siglib.c new file mode 100644 index 0000000..b20f4ac --- /dev/null +++ b/siglib.c @@ -0,0 +1,47 @@ +/* +This is a personal academic project. Dear PVS-Studio, please check it. +PVS-Studio Static Code Analyzer for C, C++ and C#: http://www.viva64.com +*/ +#define _POSIX_C_SOURCE 200112L + +#include "siglib.h" +#include +#include "error.h" +#include + +void addSignalHandler(void (*changeViewFlag)()) { + struct sigaction sigAct = {{0}}; + sigAct.sa_handler = changeViewFlag; + sigAct.sa_flags = 0; + + if (sigaction(SIGUSR1, &sigAct, NULL) == -1) + printSystemError("sigaction() -- ERROR"); +} + +// Podríamos de última hacer que devuelvan el sigset para no tener dos distintos... + +void blockSignal() { + sigset_t blockedSet = {{0}}; + sigaddset(&blockedSet, SIGUSR1); + sigprocmask(SIG_BLOCK, &blockedSet, NULL); +} + +void waitForSignal() { + sigset_t set; + sigaddset(&set, SIGUSR2); + int temp; + sigwait(&set, &temp); +} + +void sendSignal(int pid, int sig) { + union sigval value = {0}; + sigqueue(pid, sig, value); +} + +void sendStartSignal(int pid) { + sendSignal(pid, SIGUSR1); +} + +void sendFinishSignal(int pid) { + sendSignal(pid, SIGUSR2); +} diff --git a/siglib.h b/siglib.h new file mode 100644 index 0000000..3805199 --- /dev/null +++ b/siglib.h @@ -0,0 +1,10 @@ +#ifndef SIGLIB_H +#define SIGLIB_H + +void addSignalHandler(void (*changeViewFlag)()); +void blockSignal(); +void waitForSignal(); +void sendStartSignal(int pid); +void sendFinishSignal(int pid); + +#endif diff --git a/slave.c b/slave.c index 1fd47ea..9db0a8d 100644 --- a/slave.c +++ b/slave.c @@ -5,9 +5,9 @@ PVS-Studio Static Code Analyzer for C, C++ and C#: http://www.viva64.com #define _POSIX_C_SOURCE 2 #include -#include #include #include +#include #include "error.h" #define MAX_SIZE 300 @@ -17,24 +17,16 @@ void runCommand(char *, char *); void printOutput(char *, char *); int main(int argc, char *argv[]) { - setvbuf(stdout, NULL, _IONBF, 0); + if (setvbuf(stdout, NULL, _IONBF, 0) != 0) + printSystemError("setvbuf() -- ERROR"); - char output[MAX_SIZE]; - char input[MAX_SIZE]; - - /* - // Falta manejo de errores de fgets! - while (fgets(input, MAX_SIZE, stdin)) { - input[strcspn(input, "\n")] = '\0'; - runCommand(input, output); - printOutput(output, input); - } - */ + char output[MAX_SIZE], input[MAX_SIZE]; int readChars; - while ((readChars = read(STDIN_FILENO, input, MAX_SIZE) != 0)) { + while ((readChars = read(STDIN_FILENO, input, MAX_SIZE)) != 0) { if (readChars < 0) printSystemError("slave.c -- read()"); + input[readChars] = '\0'; char * inputLine = strtok(input, "\n"); while (inputLine != NULL) { @@ -44,21 +36,17 @@ int main(int argc, char *argv[]) { } } - - // int saved_flags = fcntl(fd, F_GETFL); - // fcntl(fd, F_SETFL, saved_flags & ~O_NONBLOCK); + return EXIT_SUCCESS; } void runCommand(char * inputLine, char * output) { char command[COMMAND_MAX_SIZE]; - //sprintf(command, "minisat %s | grep -o -e \"Number of .*[0-9]\\+\" -e \"CPU time.*\" -e \".*SATISFIABLE\" | awk '{if (NR == 1) {print $4} ; if (NR == 2) {print $4} ; if (NR == 3) {print $4 $5} ; if (NR == 4) {print $1}}'", inputLine); - sprintf(command, "minisat %s | grep -o -e \"Number of .*[0-9]\\+\" -e \"CPU time.*\" -e \".*SATISFIABLE\" | awk '{if (NR == 1) {printf \"Cantidad de variables: \" $4 \" - \"} ; if (NR == 2) {printf \"Cantidad de cláusulas: \" $4 \" - \"} ; if (NR == 3) {printf \"Tiempo de procesamiento: \" $4 $5 \" - \"} ; if (NR == 4) {printf \"Resultado: \" $1}}'", inputLine); + sprintf(command, "minisat %s | grep -o -e \"Number of .*[0-9]\\+\" -e \"CPU time.*\" -e \".*SATISFIABLE\" | awk '{if (NR == 1) {printf \"Cantidad de variables: \" $4 \" - \"} ; if (NR == 2) {printf \"Cantidad de clausulas: \" $4 \" - \"} ; if (NR == 3) {printf \"Tiempo de procesamiento: \" $4 $5 \" - \"} ; if (NR == 4) {printf \"Resultado: \" $1}}'", inputLine); // Pequeña ayuda para popen: https://stackoverflow.com/questions/646241/c-run-a-system-command-and-get-output - FILE * fp; - if (!(fp = popen(command, "r"))) + FILE * fp = popen(command, "r"); + if (fp == NULL) printSystemError("slave.c -- popen()"); - // Ver manejo de errores de fread! size_t outputLength = fread(output, sizeof(char), MAX_SIZE, fp); output[outputLength] = '\0'; @@ -67,12 +55,8 @@ void runCommand(char * inputLine, char * output) { if (pclose(fp) < 0) printSystemError("slave.c -- pclose()"); - } void printOutput(char * output, char * fileName) { printf("Nombre del archivo: %s - %s - Id del esclavo: %d\n", fileName, output, getpid()); - - // int saved_flags = fcntl(fd, F_GETFL); - // fcntl(fd, F_SETFL, saved_flags & O_NONBLOCK); } \ No newline at end of file diff --git a/view.c b/view.c index 36c0110..9f04c1f 100644 --- a/view.c +++ b/view.c @@ -1,16 +1,15 @@ +/* +This is a personal academic project. Dear PVS-Studio, please check it. +PVS-Studio Static Code Analyzer for C, C++ and C#: http://www.viva64.com +*/ #define _POSIX_C_SOURCE 200112L #include #include -#include #include #include "error.h" #include "shr_mem.h" -#include -#include -#include -#include -#include +#include "siglib.h" #define MAX_SIZE 300 #define MAX_AMOUNT_SIZE 10 @@ -19,8 +18,8 @@ #define MAX_OUTPUT_SIZE (200 + MAX_PATH_SIZE) int main(int argc, char * argv[]) { - char amount[MAX_AMOUNT_SIZE]; - char masterPid[MAX_PID_SIZE]; + char amount[MAX_AMOUNT_SIZE] = {0}; + char masterPid[MAX_PID_SIZE] = {0}; switch (argc) { case 1: fgets(amount, MAX_AMOUNT_SIZE, stdin); @@ -29,53 +28,34 @@ int main(int argc, char * argv[]) { masterPid[strcspn(masterPid, "\n")] = '\0'; break; case 3: - strcpy(amount, argv[1]); - strcpy(masterPid, argv[2]); + strncpy(amount, argv[1], MAX_AMOUNT_SIZE - 1); + strncpy(masterPid, argv[2], MAX_PID_SIZE - 1); + amount[MAX_AMOUNT_SIZE - 1] = '\0'; + masterPid[MAX_PID_SIZE - 1] = '\0'; break; default: - printError("View must receive amount of files and the pid of master process by argument or stdin"); + printError("View must receive amount of files and the pid of master process by argument or stdin -- ERROR"); } int files = atoi(amount); int mPid = atoi(masterPid); - printf("%d\n", files); - printf("%d\n", mPid); - union sigval value; - sigqueue(mPid, SIGUSR1, value); - - //sleep(2); - - int fd; - char * shmPointer; - - if ((fd = shm_open("/BottlerSHM", O_RDONLY, S_IRUSR)) < 0) - printSystemError("shm_open() -- ERROR"); + sendStartSignal(mPid); int totalSize = files * MAX_OUTPUT_SIZE; - - if ((shmPointer = mmap(0, totalSize, PROT_READ, MAP_SHARED, fd, 0)) == MAP_FAILED){ - printSystemError("mmap() -- ERROR"); - } - void * shmStart; + char * shmPointer, * shmStart; + int fd = openCreatedShm(&shmPointer, totalSize); shmStart = shmPointer; - int i = 0; char buf[MAX_SIZE]; while (files-- > 0) { - //buf[0] = '\0'; shmPointer += readShm(shmPointer, buf, MAX_SIZE); - printf("%d\t", i++); printf("%s\n", buf); } - if (munmap(shmStart, totalSize) == -1) - printSystemError("munmap() -- ERROR"); - - close(fd); -// terminateShm("/BottlerSHM", fd, shmStart, totalSize); - - sigqueue(mPid, SIGUSR2, value); + closeCreatedShm(shmStart, totalSize, fd); + sendFinishSignal(mPid); + closeSem(); return EXIT_SUCCESS; }