diff --git a/task1/examples/10_exec_pipes.c b/task1/examples/10_exec_pipes.c index bf77c3a..1814de0 100644 --- a/task1/examples/10_exec_pipes.c +++ b/task1/examples/10_exec_pipes.c @@ -26,27 +26,42 @@ void seq_pipe(char ***cmd) int fd_in = 0; int i = 0; - while (cmd[i] != NULL) { + while (cmd[i] != NULL) + { pipe(p); + printf("New used pipe descriptors: %d %d\n",p[0],p[1]); printf("Input descriptor for current child process: %d\n", fd_in); - if ((pid = fork()) == -1) { + + if ((pid = fork()) == -1) + { exit(1); - } else if (pid == 0) { + } + else if (pid == 0) + { if (i > 0) - dup2(fd_in, 0); //stdin <- read from fd_in (dup / dup2(int oldfd, int newfd) newfd <--copy( oldfd ) ) + dup2(fd_in, 0); //d) newfd <--copy( oldfd ) ) + + fprintf(stdout, "%d\n", fd_in); + if (cmd[i+1] != NULL) dup2(p[1], 1); //stdout -> write to pipe + close(p[0]); + execvp((cmd)[i][0], cmd[i]); exit(2); - } else { + } + else + { wait(NULL); close(p[1]); + if (i>0) close(fd_in); // old pipe from previous step is not used further, and can be destroyed + fd_in = p[0]; //fd_in <--read from pipe - i++; + i++; } } return; @@ -56,8 +71,7 @@ int main() { char *ls[] = {"/bin/ls","-ltr",".", NULL}; char *grep1[] = {"grep","rw",NULL}; - char *grep2[] = {"grep","1", NULL}; + char **cmd[] = {ls, grep1, NULL}; + seq_pipe(cmd); char *grep2[] = {"grep","1", NULL}; char *grep3[] = {"grep", "89", NULL}; - char **cmd[] = {ls, grep1, grep2, grep3, NULL}; - seq_pipe(cmd); } diff --git a/task1/examples/a.out b/task1/examples/a.out new file mode 100755 index 0000000..d6fcfde Binary files /dev/null and b/task1/examples/a.out differ diff --git a/task1/examples/beta.c b/task1/examples/beta.c new file mode 100644 index 0000000..d226e9d --- /dev/null +++ b/task1/examples/beta.c @@ -0,0 +1,43 @@ +/* Небольшое улучшение примера 10, которое позволяет держать не более 2 пайпов открытыми +Пайп пересоздается n-1 раз, но старые пайпы закрываются за ненадобностью. На одном пайпе я не вижу смысла делать, так как ввод и вывод перемешаются +Для того, чтобы убедиться, посмотрите вывод используемых дескрипторов (строка 22-23). +У меня это: +New used pipe descriptors: 3 4 +Input descriptor for current child process: 0 +New used pipe descriptors: 4 5 +Input descriptor for current child process: 3 +New used pipe descriptors: 3 5 +Input descriptor for current child process: 4 +New used pipe descriptors: 4 5 +Input descriptor for current child process: 3 +*/ + + + +#include +#include +#include +#include + +void seq_pipe(char ***cmd) +{ + int pipe_fd[2] = {-1, -1}; + pid_t pid ; + int fd_in = 0; + int i = 0; + + + + + return; +} + +int main() +{ + char *ls[] = {"/bin/ls","-ltr",".", NULL}; + char *grep1[] = {"grep","rw",NULL}; + char *grep2[] = {"grep","1", NULL}; + char *grep3[] = {"grep", "89", NULL}; + char **cmd[] = {ls, grep1, grep2, grep3, NULL}; + seq_pipe(cmd); +} diff --git a/task1/homework/main.c b/task1/homework/main.c new file mode 100644 index 0000000..a12a298 --- /dev/null +++ b/task1/homework/main.c @@ -0,0 +1,31 @@ +#include "pcmd.h" +#include "tokenizator.h" + +int main() +{ + fprintf(stdout, "BASH:(0)_(0): "); + + struct CmdTokens s_cmd = {}; + + if (constructTokens(&s_cmd) == CONSTRUCT_ERR) + { + fprintf(stderr, "ERROR: Unable to construct token structure\n"); + destructEmptyTokens(&s_cmd); + return CONSTRUCT_ERR; + } + + if (tokenizator(&s_cmd) == MAX_NUM_TOKENS_ERR) + { + fprintf(stderr, "ERROR: Maximum number of commands exceeded\n"); + destructEmptyTokens(&s_cmd); + return MAX_NUM_TOKENS_ERR; + } + + run(&s_cmd); + + destructTokens(&s_cmd); + + return 0; +} + + diff --git a/task1/homework/makefile b/task1/homework/makefile new file mode 100644 index 0000000..0b2fe4f --- /dev/null +++ b/task1/homework/makefile @@ -0,0 +1,4 @@ +CC=gcc + +all: + gcc main.c pcmd.c tokenizator.c -D _DEBUG -ggdb3 -O0 -Wall -Wextra -Waggressive-loop-optimizations -Wmissing-declarations -Wcast-align -Wcast-qual -Wchar-subscripts -Wconversion -Wempty-body -Wfloat-equal -Wformat-nonliteral -Wformat-security -Wformat-signedness -Wformat=2 -Winline -Wlogical-op -Wopenmp-simd -Wpacked -Wpointer-arith -Winit-self -Wredundant-decls -Wshadow -Wsign-conversion -Wstrict-overflow=2 -Wsuggest-attribute=noreturn -Wsuggest-final-methods -Wsuggest-final-types -Wswitch-default -Wswitch-enum -Wsync-nand -Wundef -Wunreachable-code -Wunused -Wvariadic-macros -Wno-missing-field-initializers -Wno-narrowing -Wno-varargs -Wstack-protector -fcheck-new -fstack-protector -fstrict-overflow -flto-odr-type-merging -fno-omit-frame-pointer -pie -fPIE -fsanitize=address,alignment,bool,bounds,enum,float-cast-overflow,float-divide-by-zero,integer-divide-by-zero,leak,nonnull-attribute,null,object-size,return,returns-nonnull-attribute,shift,signed-integer-overflow,undefined,unreachable,vla-bound,vptr \ No newline at end of file diff --git a/task1/homework/pcmd.c b/task1/homework/pcmd.c new file mode 100644 index 0000000..67a2fcf --- /dev/null +++ b/task1/homework/pcmd.c @@ -0,0 +1,52 @@ +#include "pcmd.h" + + +void run(struct CmdTokens* s_commands) +{ + // example /bin/ls -ltr . | grep rw + + int pipeFd[2] = {-1, -1}; + pid_t pid = -1; + int fd_in = -1; + + for (size_t counter = 0; counter < s_commands->pipelineCapacity + 1; counter++) + { + pipe(pipeFd); + + if ((pid = fork()) == -1) + { + fprintf(stderr, "ERROR:Unable to create process. A system-imposed limit on the number of threads was encountered\n"); + } + else if (pid == 0) + { + if (counter > 0) + dup2(fd_in, 0); //stdin + + if (counter != s_commands->pipelineCapacity) dup2(pipeFd[1], 1); //stdout + + close(pipeFd[0]); + + if (execvp(s_commands->flags[counter][0], s_commands->flags[counter]) == - 1) + { + fprintf(stderr, "ERROR: execvp error, check errno; Command not found.\n"); + } + + exit(-1); + } + else + { + int status = 0; + + waitpid(pid, &status, WNOHANG); + + s_commands->exitStatus[counter] = WEXITSTATUS(status); + + close(pipeFd[1]); + + if (counter > 0) close(fd_in); + + fd_in = pipeFd[0]; + } + } + return; +} diff --git a/task1/homework/pcmd.h b/task1/homework/pcmd.h new file mode 100644 index 0000000..0b87771 --- /dev/null +++ b/task1/homework/pcmd.h @@ -0,0 +1,16 @@ +#ifndef PCMD_H +#define PCMD_H + +#include +#include +#include +#include +#include + +#include "tokenizator.h" + +void run(struct CmdTokens* s_commads); + + + +#endif \ No newline at end of file diff --git a/task1/homework/tokenizator.c b/task1/homework/tokenizator.c new file mode 100644 index 0000000..84b0c1a --- /dev/null +++ b/task1/homework/tokenizator.c @@ -0,0 +1,249 @@ +#include "tokenizator.h" + +size_t constructTokens(struct CmdTokens* s_commands) +{ + assert(s_commands); + + s_commands->tokensCapacity = 0; + s_commands->pipelineCapacity = 0; + s_commands->flagsNum = NULL; + + for (int i = 0; i < MAX_NUM_TOKENS; i++) + { + s_commands->tokens[i] = NULL; + } + + return OK; +} + +size_t tokenizator(struct CmdTokens* s_commands) +{ + assert(s_commands); + + char delim[] = " ,;\n"; + + char cmd[CMD_MAX_SIZE] = {}; + + fgets(cmd, CMD_MAX_SIZE, stdin); + + size_t cmdCounter = 0; + char* token = NULL; + char* pos = NULL; + + for (token = godStrtok(cmd, delim, &pos); ((token!=NULL)&(cmdCounterpipelineCapacity++; + s_commands->tokens[cmdCounter] = token; + cmdCounter++; + } + else if (strchr(token, '|') != NULL) + { + char* tokenBefore = fixBeforeTok(token); + char* tokenAfter = fixAfterTok(token, delim); + free(token); + s_commands->tokens[cmdCounter] = tokenBefore; + s_commands->pipelineCapacity++; + cmdCounter++; + char* tmp = (char*)calloc(2, sizeof(char)); + tmp[0] = '|'; + tmp[1] = '\0'; + s_commands->tokens[cmdCounter] = tmp; + cmdCounter++; + + if (tokenAfter != NULL) + { + s_commands->tokens[cmdCounter]; + cmdCounter++; + } + } + else + { + s_commands->tokens[cmdCounter] = token; + cmdCounter++; + } + } + + if (cmdCounter == MAX_NUM_TOKENS) + { + s_commands->tokensCapacity = MAX_NUM_TOKENS + 1; + return MAX_NUM_TOKENS_ERR; + } + + s_commands->tokensCapacity = cmdCounter; + + s_commands->flagsNum = (size_t*)calloc(s_commands->pipelineCapacity + 1, sizeof(size_t)); + s_commands->flags = (char***)calloc(s_commands->pipelineCapacity + 1, sizeof(char***)); + + inputFlags(s_commands, cmdCounter); + + return OK; +} + + +void inputFlags(struct CmdTokens* s_commands, size_t tokensCapcity) +{ + assert(s_commands); + + size_t flagsNum = 0; + size_t pipelineCounter = 0; + + for (size_t flagsCounter = 0; flagsCounter < tokensCapcity; flagsCounter++) + { + if (strcmp(s_commands->tokens[flagsCounter], "|") == 0) + { + s_commands->flagsNum[pipelineCounter] = flagsNum; + pipelineCounter++; + flagsNum = 0; + } + else + { + flagsNum++; + } + } + + s_commands->flagsNum[pipelineCounter] = flagsNum; + + flagsNum = 0; + size_t tokensCounter = 0; + + for (size_t flagsCounter = 0; flagsCounter < s_commands->pipelineCapacity + 1; flagsCounter++) + { + s_commands->flags[flagsCounter] = calloc(s_commands->flagsNum[flagsCounter] + 1, sizeof(char*)); + + for (size_t i = 0; i < s_commands->flagsNum[flagsCounter]; i++) + { + s_commands->flags[flagsCounter][i] = s_commands->tokens[tokensCounter]; + tokensCounter++; + } + s_commands->flags[flagsCounter][s_commands->flagsNum[flagsCounter]] = NULL; + + tokensCounter++; + } +} + +void destructTokens(struct CmdTokens* s_commands) +{ + assert(s_commands); + + for (size_t counter = 0; counter < s_commands->tokensCapacity; counter++) + { + free(s_commands->tokens[counter]); + s_commands->tokens[counter] = NULL; + } + + for (size_t counter = 0; counter < s_commands->pipelineCapacity + 1; counter++) + { + free(s_commands->flags[counter]); + s_commands->flags[counter] = NULL; + } + + free(s_commands->flags); + s_commands->flags = NULL; + + free(s_commands->flagsNum); + s_commands->flags = NULL; +} + +void destructEmptyTokens(struct CmdTokens* s_commands) +{ + for (size_t counter = 0; counter < s_commands->tokensCapacity; counter++) + { + free(s_commands->tokens[counter]); + s_commands->tokens[counter] = NULL; + } +} + + +char* strDuplicator(const char* start, const char* end) +{ + size_t lenStr = end - start; + + char* dup = calloc(lenStr + 1, sizeof(char)); + + if (dup != NULL) + { + strncpy(dup, start, lenStr); + } + + return dup; +} + +char* godStrtok(char* string, char* delimeters, char** pos) +{ + if (string == NULL) + { + string = *pos; + } + + char* walker = string; + char* token = NULL; + + while (*walker != '\0') + { + if (strchr(delimeters, *walker) == 0) + { + walker++; + } + else + { + token = strDuplicator(string, walker); + *pos = walker + strspn(walker, delimeters); + break; + } + } + return token; +} + + +char* fixBeforeTok(char* token) +{ + char* pos = strchr(token, '|'); + + char* result = strDuplicator(token, pos); + + return result; +} + +char* fixAfterTok(char* token, char* delim) +{ + char* tmp = strchr(token, '|'); + + if (strlen(tmp) == 1) + { + return NULL; + } + else + { + char* walker = tmp; + while (strchr(walker, *delim) == 0) + { + walker++; + } + + char* result = strDuplicator(tmp + 1, walker); + + return result; + } +} + +void printTokens(struct CmdTokens* s_commands) +{ + for (size_t i = 0; i < s_commands->pipelineCapacity + 1; i++) + { + printf("flags in %lu pipeline: %lu;\nflags: ", i + 1, s_commands->flagsNum[i]); + + for (size_t j = 0; j < s_commands->flagsNum[i]; j++) + { + printf("%s ", s_commands->flags[i][j]); + } + printf("\n"); + } + + for (size_t i = 0; i < s_commands->pipelineCapacity + 1; i++) + { + printf("exit status of [%lu] process:%d\n", i, s_commands->exitStatus[i]); + } + +} \ No newline at end of file diff --git a/task1/homework/tokenizator.h b/task1/homework/tokenizator.h new file mode 100644 index 0000000..0d6c4ee --- /dev/null +++ b/task1/homework/tokenizator.h @@ -0,0 +1,56 @@ +#ifndef TOKENIZATOR_H +#define TOKENIZATOR_H + +#include +#include +#include +#include + + +enum CMD +{ + MAX_NUM_TOKENS = 256, + CMD_MAX_SIZE = 155, +}; + +enum CMD_ERRORS +{ + MAX_NUM_TOKENS_ERR = 0x00F, + CONSTRUCT_ERR = 0x01F, + OK = 0x111, +}; + +struct CmdTokens +{ + char* tokens[MAX_NUM_TOKENS + 1]; + char*** flags; + + int exitStatus[MAX_NUM_TOKENS]; + + size_t tokensCapacity; + size_t pipelineCapacity; + + size_t* flagsNum; +}; + +size_t tokenizator(struct CmdTokens* s_commands); + +void inputFlags(struct CmdTokens* s_commands, size_t tokensCapcity); + +size_t constructTokens(struct CmdTokens* s_commands); + +void destructTokens(struct CmdTokens* s_commands); + +void destructEmptyTokens(struct CmdTokens* s_commands); + +char* strDuplicator(const char *start, const char *end); + +char* godStrtok(char* string, char* delimeters, char** pos); + +char* fixBeforeTok(char* token); + +char* fixAfterTok(char* token, char* delim); + +void printTokens(struct CmdTokens* s_commands); + +#endif \ No newline at end of file diff --git a/task2/homework/.gitignore b/task2/homework/.gitignore new file mode 100644 index 0000000..786bc06 --- /dev/null +++ b/task2/homework/.gitignore @@ -0,0 +1,4 @@ +a.out +file.txt +child.txt +parent.txt \ No newline at end of file diff --git a/task2/homework/main.c b/task2/homework/main.c new file mode 100644 index 0000000..82c6940 --- /dev/null +++ b/task2/homework/main.c @@ -0,0 +1,13 @@ +#include "transfer.h" + + +int main() +{ + Pipe duplex = {}; + + constructPipe(&duplex); + + run(&duplex); + + free(duplex.dataIn); +} \ No newline at end of file diff --git a/task2/homework/makefile b/task2/homework/makefile new file mode 100644 index 0000000..a01edb0 --- /dev/null +++ b/task2/homework/makefile @@ -0,0 +1,2 @@ +all: + gcc main.c transfer.c -D _DEBUG -ggdb3 -O0 -Wall -Wextra -Waggressive-loop-optimizations -Wmissing-declarations -Wcast-align -Wcast-qual -Wchar-subscripts -Wconversion -Wempty-body -Wfloat-equal -Wformat-nonliteral -Wformat-security -Wformat-signedness -Wformat=2 -Winline -Wlogical-op -Wopenmp-simd -Wpacked -Wpointer-arith -Winit-self -Wredundant-decls -Wshadow -Wsign-conversion -Wstrict-overflow=2 -Wsuggest-attribute=noreturn -Wsuggest-final-methods -Wsuggest-final-types -Wswitch-default -Wswitch-enum -Wsync-nand -Wundef -Wunreachable-code -Wunused -Wvariadic-macros -Wno-missing-field-initializers -Wno-narrowing -Wno-varargs -Wstack-protector -fcheck-new -fstack-protector -fstrict-overflow -flto-odr-type-merging -fno-omit-frame-pointer -pie -fPIE -fsanitize=address,alignment,bool,bounds,enum,float-cast-overflow,float-divide-by-zero,integer-divide-by-zero,leak,nonnull-attribute,null,object-size,return,returns-nonnull-attribute,shift,signed-integer-overflow,undefined,unreachable,vla-bound,vptr \ No newline at end of file diff --git a/task2/homework/transfer.c b/task2/homework/transfer.c new file mode 100644 index 0000000..2584487 --- /dev/null +++ b/task2/homework/transfer.c @@ -0,0 +1,132 @@ +#include "transfer.h" + +#define $$ fprintf(stdout, "HERE %d\n", __LINE__); + + +const size_t MAXBUFSIZE = 65536; + +size_t findFileSize(FILE* in) +{ + assert(in); + + size_t fileSize = 0; + + fseek (in, 0, SEEK_END); + + fileSize = ftell (in); + + fseek (in, 0, SEEK_SET); + + return (fileSize); +} + +void constructPipe(Pipe* self) +{ + assert(self); + + FILE* parent = fopen("parent.txt", "r"); + + self->len = findFileSize(parent); + self->lenParts = self->len / MAXBUFSIZE; + + self->dataIn = calloc(MAXBUFSIZE, sizeof(char)); + + if (self->dataIn == NULL) fprintf(stderr, "ERROR: can't calloc memory for data on %d LINE", __LINE__); + + self->actions.rcv = readDuplex; + self->actions.send = writeDuplex; + + fclose(parent); +} + + +ssize_t readDuplex(Pipe* self, int curFd) +{ + ssize_t tmp = read(curFd, self->dataIn, MAXBUFSIZE); + return (tmp); +} + + +ssize_t writeDuplex(Pipe* self, int curFd) +{ + ssize_t tmp = write(curFd, self->dataIn, MAXBUFSIZE); + + return (tmp); +} + +void run(Pipe* self) +{ + pipe(self->fdParent); + pipe(self->fdChild); + + size_t tmpSize = self->len; + + pid_t pid = -1; + + if ((pid = fork()) == -1) + { + fprintf(stderr, "ERROR: Can't create new proccess\n"); + } + else if (pid == 0) + { + close(self->fdChild[1]); + close(self->fdParent[0]); + //---------------------------------------------------------------- + + for (size_t i = 0; i < self->lenParts; i++) + self->actions.rcv(self, self->fdChild[0]); + + if ((tmpSize - MAXBUFSIZE * self->lenParts) != 0) + { + self->actions.rcv(self, self->fdChild[0]); + } + //---------------------------------------------------------------- + + for (size_t i = 0; i < self->lenParts; i++) + { + self->actions.send(self, self->fdParent[1]); + } + if ((tmpSize - MAXBUFSIZE * self->lenParts) != 0) + { + self->actions.send(self, self->fdParent[1]); + } + + //---------------------------------------------------------------- + } + else + { + FILE* parent = fopen("parent.txt", "r"); + if (parent == NULL) fprintf(stderr, "ERROR: can't open file with data on %d LINE", __LINE__); + //-------------------------------------------------------------------------------------------------------------- + + for (size_t i = 0; i < self->lenParts; i++) + { + fread(self->dataIn, sizeof(char), MAXBUFSIZE, parent); + self->actions.send(self, self->fdChild[1]); + } + if ((self->len - MAXBUFSIZE * self->lenParts) != 0) + { + fread(self->dataIn, sizeof(char), MAXBUFSIZE, parent); + self->actions.send(self, self->fdChild[1]); + } + //-------------------------------------------------------------------------------------------------------------- + fclose(parent); + + FILE* child = fopen("child.txt", "w"); + if (child == NULL) fprintf(stderr, "ERROR: can't open file with data on %d LINE", __LINE__); + + for (size_t i = 0; i < self->lenParts; i++) + { + self->actions.rcv(self, self->fdParent[0]); + fwrite(self->dataIn, sizeof(char), MAXBUFSIZE, child); + } + if ((self->len - MAXBUFSIZE * self->lenParts) != 0) + { + self->actions.rcv(self, self->fdParent[0]); + fwrite(self->dataIn, sizeof(char), MAXBUFSIZE, child); + } + //-------------------------------------------------------------------------------------------------------------- + + fclose(child); + } +} \ No newline at end of file diff --git a/task2/homework/transfer.h b/task2/homework/transfer.h new file mode 100644 index 0000000..18568a6 --- /dev/null +++ b/task2/homework/transfer.h @@ -0,0 +1,47 @@ +#ifndef TRANSFER_H +#define TRANSFER_H + +#include +#include +#include +#include +#include +#include +#include +#include + + +typedef struct pPipe Pipe; + +typedef struct op_table Ops; + +typedef struct op_table +{ + ssize_t (*rcv) (Pipe *self, int curFd); + ssize_t (*send)(Pipe *self, int curFd); +} Ops; + +typedef struct pPipe +{ + char* dataIn; + + int fdChild[2]; + int fdParent[2]; + + size_t len; + size_t lenParts; + + Ops actions; +} Pipe; + +void constructPipe(Pipe* self); + +ssize_t readDuplex(Pipe* self, int curFd); + +ssize_t writeDuplex(Pipe* self, int curFd); + +size_t findFileSize(FILE* f); + +void run(Pipe* self); + +#endif \ No newline at end of file diff --git a/task3/homework/.gitignore b/task3/homework/.gitignore new file mode 100644 index 0000000..edd9727 --- /dev/null +++ b/task3/homework/.gitignore @@ -0,0 +1,8 @@ +FIFO/FIFOReceiver.out +FIFO/FIFOSender.out +mqSYSV/mqSYSVReceiver.out +mqSYSV/mqSYSVSender.out +shmPOSIX/shmClientPOSIX.out +shmPOSIX/shmServerPOSIX.out +input.txt +FIFO/output.txt \ No newline at end of file diff --git a/task3/homework/FIFO/FIFOReceiver.c b/task3/homework/FIFO/FIFOReceiver.c new file mode 100644 index 0000000..d4e7b79 --- /dev/null +++ b/task3/homework/FIFO/FIFOReceiver.c @@ -0,0 +1,46 @@ +#include +#include +#include +#include +#include +#include + +#define FIFO "fifo" + +#define DEFAULT_SIZE 65536 + +#ifdef SMALL_SIZE +#define SIZE 4096 +#endif + +#ifdef MEDIUM_SIZE +#define SIZE 104857600 +#endif + +#ifdef LARGE_SIZE +#define SIZE 2147483648 +#endif + + +int main() +{ + mknod(FIFO, S_IFIFO | 0666, 0); + printf("Waiting for a writer\n"); + int fd = open(FIFO, O_RDONLY); + printf("A writer is connected\n"); + + int size = 0; + + char buf[DEFAULT_SIZE]; + + FILE* out = fopen("./FIFO/output.txt", "w"); + + while ((size = read(fd, buf, sizeof(buf))) > 0) + { + fwrite(buf, sizeof(char), size, out); + } + + close(fd); + fclose(out); + return 0; +} \ No newline at end of file diff --git a/task3/homework/FIFO/FIFOSender.c b/task3/homework/FIFO/FIFOSender.c new file mode 100644 index 0000000..d5c1a84 --- /dev/null +++ b/task3/homework/FIFO/FIFOSender.c @@ -0,0 +1,50 @@ +#include +#include +#include +#include +#include +#include + + +#define DEFAULT_SIZE 65536 +#define FIFO "fifo" + +#ifdef SMALL_SIZE +#define SIZE 4096 +#endif + +#ifdef MEDIUM_SIZE +#define SIZE 104857600 +#endif + +#ifdef LARGE_SIZE +#define SIZE 2147483648 +#endif + + +int main() +{ + mknod(FIFO, S_IFIFO | 0666, 0); + printf("Waiting for a reader\n"); + int fd_FIFO = open(FIFO, O_WRONLY); + int fd_in = open("./input.txt", O_RDONLY); + if (fd_in < 0) + { + fprintf(stderr, "FILE NOT FOUND\n"); + } + printf("A reader is connected\n"); + + int size = 0; + + char buf[DEFAULT_SIZE]; + + while ((size = read(fd_in, buf, sizeof(buf))) > 0) + { + write(fd_FIFO, buf, size); + } + + close(fd_FIFO); + close(fd_in); + + return 0; +} \ No newline at end of file diff --git a/task3/homework/README.md b/task3/homework/README.md new file mode 100644 index 0000000..b9659dd --- /dev/null +++ b/task3/homework/README.md @@ -0,0 +1,41 @@ + +# HW 3 +## Interprocessor Communication Analysis + +### LAUNCH +__Calling the help line__
+```bash + python3 start.py -help +``` +__Start tests__
+``` bash + python3 start.py -flag +``` +___FLAGS:___ ```-small```, ```-medium```, ```-large```
+ +### Tests were carried out with these parameters + +|FLAG | -small |-medium|-large| +|------|--------|-------|------| +|INPUT | 4kB | 104MB |2.1GB | + + +|BUF IN BYTES |512 | 4096 | 65536 | +|--------------|----|------|-------| + + +### GRAPH: + +![Imaga small](https://github.com/shaazmik/3_sem_22_23/blob/main/task3/homework/img/small.png?raw=true) +
+![Image medium](https://github.com/shaazmik/3_sem_22_23/blob/main/task3/homework/img/medium.png?raw=true) +
+![Image large](https://github.com/shaazmik/3_sem_22_23/blob/main/task3/homework/img/large.png?raw=true) + + +### CONCLUSION: + +The most effective in these tests was ___virtual-shared memory___, which allows you to immediately access data from another process,
+without the preliminary cost of reading.
+__Message queue__ is the most efficient for sending short messages.
+__FIFO__ stably keeps in the middle among all and the easiest method to implement.
diff --git a/task3/homework/img/large.png b/task3/homework/img/large.png new file mode 100644 index 0000000..c7e0cde Binary files /dev/null and b/task3/homework/img/large.png differ diff --git a/task3/homework/img/medium.png b/task3/homework/img/medium.png new file mode 100644 index 0000000..25ada87 Binary files /dev/null and b/task3/homework/img/medium.png differ diff --git a/task3/homework/img/small.png b/task3/homework/img/small.png new file mode 100644 index 0000000..c600b4f Binary files /dev/null and b/task3/homework/img/small.png differ diff --git a/task3/homework/mqSYSV/mqSYSVReceiver.c b/task3/homework/mqSYSV/mqSYSVReceiver.c new file mode 100644 index 0000000..5fca4f0 --- /dev/null +++ b/task3/homework/mqSYSV/mqSYSVReceiver.c @@ -0,0 +1,59 @@ +#include +#include +#include +#include +#include +#include + + +#define DEFAULT_KEY 1337 +#define MAX_MSG_SIZE 4096 +#define DEFAULT_TYPE 1488 + + +#ifdef SMALL_SIZE +#define SIZE 4096 +#endif + +#ifdef MEDIUM_SIZE +#define SIZE 104857600 +#endif + +#ifdef LARGE_SIZE +#define SIZE 2147483648 +#endif + +typedef struct msgbuf +{ + long mtype; + char mtext[MAX_MSG_SIZE]; +} message_buf; + + +int main() +{ + int msqid = -1; + key_t key = DEFAULT_KEY; + message_buf rbuf; + rbuf.mtype = DEFAULT_TYPE; + + if ((msqid = msgget(key, 0666)) < 0) + { + perror("msgget"); + exit(1); + } + + + for (size_t bytes = SIZE; bytes > 0;) + { + if (msgrcv(msqid, &rbuf, MAX_MSG_SIZE, DEFAULT_TYPE, 0) < 0) + { + perror("msg in RECEIVER:"); + exit(1); + } + + bytes-=MAX_MSG_SIZE; + } + + return 0; +} \ No newline at end of file diff --git a/task3/homework/mqSYSV/mqSYSVSender.c b/task3/homework/mqSYSV/mqSYSVSender.c new file mode 100644 index 0000000..e7edc81 --- /dev/null +++ b/task3/homework/mqSYSV/mqSYSVSender.c @@ -0,0 +1,91 @@ +#include +#include +#include +#include +#include +#include +#include + + +#define DEFAULT_KEY 1337 +#define DEFAULT_TYPE 1488 +#define MAX_MSG_SIZE 4096 + + +#ifdef SMALL_SIZE +#define SIZE 4096 +#endif + +#ifdef MEDIUM_SIZE +#define SIZE 104857600 +#endif + +#ifdef LARGE_SIZE +#define SIZE 2147483648 +#endif + +typedef struct msgbuf +{ + long mtype; + char mtext[MAX_MSG_SIZE]; +} message_buf; + + +int findFileSize(FILE* in) +{ + assert(in); + + int fileSize = 0; + + fseek (in, 0, SEEK_END); + + fileSize = ftell (in); + + fseek (in, 0, SEEK_SET); + + return (fileSize); +} + + +int main() +{ + int msqid = -1; + int msgflg = IPC_CREAT | 0666; + key_t key = DEFAULT_KEY; + message_buf sbuf; + sbuf.mtype = DEFAULT_TYPE; + + + if ((msqid = msgget(key, msgflg)) < 0) + { + perror("msgget"); + exit(1); + } + else + printf("msgget: msgget succeeded: msqid = %d\n", msqid); + + + FILE* in = fopen("./input.txt", "r"); + if (!in) + { + fprintf(stderr,"FILE NOT FOUND\n"); + return 1; + } + + for (size_t bytes = SIZE; bytes > 0;) + { + fread(sbuf.mtext, sizeof(char), MAX_MSG_SIZE, in); + + if (msgsnd(msqid, &sbuf, MAX_MSG_SIZE, 0) < 0) + { + perror("msg in SENDER:"); + msgctl(msqid, IPC_RMID, NULL); + exit(1); + } + bytes-=MAX_MSG_SIZE; + } + + fclose(in); + + return 0; +} diff --git a/task3/homework/shmPOSIX/shmClientPOSIX.c b/task3/homework/shmPOSIX/shmClientPOSIX.c new file mode 100644 index 0000000..b231945 --- /dev/null +++ b/task3/homework/shmPOSIX/shmClientPOSIX.c @@ -0,0 +1,93 @@ +#include +#include +#include +#include +#include +#include +#include +#include + +const char* name = "HESOYAM"; + +#define DEFAULT_SIZE 65536 + + +#ifdef SMALL_SIZE +#define SIZE 4097 +#endif + +#ifdef MEDIUM_SIZE +#define SIZE 104857601 +#endif + +#ifdef LARGE_SIZE +#define SIZE 2147483649 +#endif + + +size_t findFileSize(FILE* in) +{ + assert(in); + + size_t fileSize = 0; + + fseek (in, 0, SEEK_END); + + fileSize = ftell (in); + + fseek (in, 0, SEEK_SET); + + return (fileSize); +} + + +int main() +{ + int shm_fd = -1; + + void* ptr = NULL; + + shm_fd = shm_open(name, O_CREAT | O_RDWR, 0666); + + ftruncate(shm_fd, SIZE); + + ptr = mmap(0, SIZE, PROT_WRITE, MAP_SHARED, shm_fd, 0); + + if(ptr == MAP_FAILED) + { + perror("mmap"); + exit(1); + } + + char inBuf[DEFAULT_SIZE]; + + FILE* in = fopen("./input.txt", "r"); + if (!in) + { + fprintf(stderr, "File not found\n"); + return 1; + } + + + size_t file_size = findFileSize(in); + + if (file_size >= SIZE) + { + fprintf(stderr, "DATA TOO BIG\n"); + return 1; + } + + size_t rSize = 0; + size_t counter = 0; + while(rSize = fread((char*)(ptr + rSize), sizeof(char), DEFAULT_SIZE, in) > 0) + { + counter++; + } + + + fprintf(stdout, "Packets of %d bytes = %lu\n", DEFAULT_SIZE, counter); + + fclose(in); + + return 0; +} \ No newline at end of file diff --git a/task3/homework/shmPOSIX/shmServerPOSIX.c b/task3/homework/shmPOSIX/shmServerPOSIX.c new file mode 100644 index 0000000..112eb60 --- /dev/null +++ b/task3/homework/shmPOSIX/shmServerPOSIX.c @@ -0,0 +1,52 @@ +// C program for Consumer process illustrating +// POSIX shared-memory API. +// monitor it using ipcs +// lsof -p 16894 +// fuser some-huge-file.txt +#include +#include +#include +#include +#include +#include + +const char* name = "HESOYAM"; + +#define DEFAULT_SIZE 65536 + +#ifdef SMALL_SIZE +#define SIZE 4097 +#endif + +#ifdef MEDIUM_SIZE +#define SIZE 104857601 +#endif + +#ifdef LARGE_SIZE +#define SIZE 2147483649 +#endif + + +int main() +{ + sleep(0,0001); + + int shm_fd = -1; + + void* ptr = NULL; + + + shm_fd = shm_open(name, O_RDONLY, 0666); + + ptr = mmap(0, SIZE, PROT_READ, MAP_SHARED, shm_fd, 0); + + if(ptr == MAP_FAILED) + { + perror("mmap"); + exit(1); + } + + + shm_unlink(name); + return 0; +} \ No newline at end of file diff --git a/task3/homework/start.py b/task3/homework/start.py new file mode 100644 index 0000000..2efc67d --- /dev/null +++ b/task3/homework/start.py @@ -0,0 +1,176 @@ +import os +import sys +import time + + +## hate makefiles.... +class ANSI(): + def background(code): + return "\33[{code}m".format(code=code) + + def style_text(code): + return "\33[{code}m".format(code=code) + + def color_text(code): + return "\33[{code}m".format(code=code) + + +argc = len(sys.argv) + +if (argc > 1): + if (sys.argv[1] == "-h"): + print("Write 'start.py -small' for testing with SMALL_SIZE") + print("Write 'start.py -medium' for testing with MEDIUM_SIZE") + print("Write 'start.py -large' for testing with LARGE_SIZE") + exit() + + + if (sys.argv[1] == '-small'): + cmd = "gcc -DSMALL_SIZE ./mqSYSV/mqSYSVSender.c -o ./mqSYSV/mqSYSVSender.out -lrt" + os.system(cmd) + cmd = "gcc -DSMALL_SIZE ./mqSYSV/mqSYSVReceiver.c -o ./mqSYSV/mqSYSVReceiver.out -lrt" + os.system(cmd) + cmd = "gcc -DSMALL_SIZE ./shmPOSIX/shmClientPOSIX.c -o ./shmPOSIX/shmClientPOSIX.out -lrt" + os.system(cmd) + cmd = "gcc -DSMALL_SIZE ./shmPOSIX/shmServerPOSIX.c -o ./shmPOSIX/shmServerPOSIX.out -lrt" + os.system(cmd) + cmd = "gcc -DSMALL_SIZE ./FIFO/FIFOReceiver.c -o ./FIFO/FIFOReceiver.out -lrt" + os.system(cmd) + cmd = "gcc -DSMALL_SIZE ./FIFO/FIFOSender.c -o ./FIFO/FIFOSender.out -lrt" + os.system(cmd) + print("") + cmd = "dd if=/dev/urandom of=input.txt bs=4096 count=1" + os.system(cmd) + print("") + + cmd = "./FIFO/FIFOReceiver.out & ./FIFO/FIFOSender.out" + start = time.time() + os.system(cmd) + end = time.time() + + passedTime = end - start + outputFormat = ANSI.background(49) + ANSI.color_text(31) + ANSI.style_text(7) + print(outputFormat + "FIFO TIME:", passedTime) + print("") + + cmd = "./mqSYSV/mqSYSVReceiver.out & ./mqSYSV/mqSYSVSender.out" + start = time.time() + os.system(cmd) + end = time.time() + + passedTime = end - start + print("MESSAGE QUEUE SYSV TIME:", passedTime) + print("") + + cmd = "./shmPOSIX/shmClientPOSIX.out & ./shmPOSIX/shmServerPOSIX.out" + start = time.time() + os.system(cmd) + end = time.time() + + passedTime = end - start + print("SHARED MEMORY POSIX TIME:", passedTime) + print("") + + if (sys.argv[1] == '-medium'): + cmd = "gcc -DMEDIUM_SIZE ./mqSYSV/mqSYSVSender.c -o ./mqSYSV/mqSYSVSender.out -lrt" + os.system(cmd) + cmd = "gcc -DMEDIUM_SIZE ./mqSYSV/mqSYSVReceiver.c -o ./mqSYSV/mqSYSVReceiver.out -lrt" + os.system(cmd) + cmd = "gcc -DMEDIUM_SIZE ./shmPOSIX/shmClientPOSIX.c -o ./shmPOSIX/shmClientPOSIX.out -lrt" + os.system(cmd) + cmd = "gcc -DMEDIUM_SIZE ./shmPOSIX/shmServerPOSIX.c -o ./shmPOSIX/shmServerPOSIX.out -lrt" + os.system(cmd) + cmd = "gcc -DMEDIUM_SIZE ./FIFO/FIFOReceiver.c -o ./FIFO/FIFOReceiver.out -lrt" + os.system(cmd) + cmd = "gcc -DMEDIUM_SIZE ./FIFO/FIFOSender.c -o ./FIFO/FIFOSender.out -lrt" + os.system(cmd) + cmd = "dd if=/dev/urandom of=input.txt bs=25600 count=4096" + os.system(cmd) + print("") + + cmd = "./FIFO/FIFOReceiver.out & ./FIFO/FIFOSender.out" + start = time.time() + os.system(cmd) + end = time.time() + + passedTime = end - start + outputFormat = ANSI.background(49) + ANSI.color_text(31) + ANSI.style_text(7) + print(outputFormat + "FIFO TIME:", passedTime) + print("") + + cmd = "./mqSYSV/mqSYSVReceiver.out & ./mqSYSV/mqSYSVSender.out" + start = time.time() + os.system(cmd) + end = time.time() + + passedTime = end - start + print("MESSAGE QUEUE SYSV TIME:", passedTime) + print("") + + cmd = "./shmPOSIX/shmClientPOSIX.out & ./shmPOSIX/shmServerPOSIX.out" + start = time.time() + os.system(cmd) + end = time.time() + + passedTime = end - start + print("SHARED MEMORY POSIX TIME:", passedTime) + print("") + + if (sys.argv[1] == '-large'): + cmd = "gcc -DLARGE_SIZE ./mqSYSV/mqSYSVSender.c -o ./mqSYSV/mqSYSVSender.out -lrt" + os.system(cmd) + cmd = "gcc -DLARGE_SIZE ./mqSYSV/mqSYSVReceiver.c -o ./mqSYSV/mqSYSVReceiver.out -lrt" + os.system(cmd) + cmd = "gcc -DLARGE_SIZE ./shmPOSIX/shmClientPOSIX.c -o ./shmPOSIX/shmClientPOSIX.out -lrt" + os.system(cmd) + cmd = "gcc -DLARGE_SIZE ./shmPOSIX/shmServerPOSIX.c -o ./shmPOSIX/shmServerPOSIX.out -lrt" + os.system(cmd) + cmd = "gcc -DLARGE_SIZE ./FIFO/FIFOReceiver.c -o ./FIFO/FIFOReceiver.out -lrt" + os.system(cmd) + cmd = "gcc -DLARGE_SIZE ./FIFO/FIFOSender.c -o ./FIFO/FIFOSender.out -lrt" + os.system(cmd) + cmd = "dd if=/dev/urandom of=input.txt bs=1048576 count=2048" + os.system(cmd) + print("") + + cmd = "./FIFO/FIFOReceiver.out & ./FIFO/FIFOSender.out" + start = time.time() + os.system(cmd) + end = time.time() + + passedTime = end - start + outputFormat = ANSI.background(49) + ANSI.color_text(31) + ANSI.style_text(7) + print(outputFormat + "FIFO TIME:", passedTime) + print("") + + cmd = "./mqSYSV/mqSYSVReceiver.out & ./mqSYSV/mqSYSVSender.out" + start = time.time() + os.system(cmd) + end = time.time() + + passedTime = end - start + print("MESSAGE QUEUE SYSV TIME:", passedTime) + print("") + + cmd = "./shmPOSIX/shmClientPOSIX.out & ./shmPOSIX/shmServerPOSIX.out" + start = time.time() + os.system(cmd) + end = time.time() + + passedTime = end - start + print("SHARED MEMORY POSIX TIME:", passedTime) + print("") + +else: + print("Write 'start.py -h' for information.") + + +# -small BUF SIZE 512 FIFO 0.00245 MSQ 0.00228 SHM 0.00584 +# -medium BUF SIZE 512 FIFO 0.39691 MSQ 1.19831 SHM 0.00657 +# -large BUF SIZE 512 FIFO 16.18651 MSQ 15.76633 SHM 0.00860 +# -small BUF SIZE 4096 FIFO 0.00481 MSQ 0.00231 SHM 0.00280 +# -medium BUF SIZE 4096 FIFO 0.25731 MSQ 0.23929 SHM 0.00410 +# -large BUF SIZE 4096 FIFO 4.94263 MSQ 12.67133 SHM 0.00595 +# -small BUF SIZE 65536 FIFO 0.00284 ------------ SHM 0.00234 +# -medium BUF SIZE 65536 FIFO 0.25731 ------------ SHM 0.00351 +# -large BUF SIZE 65536 FIFO 3.57521 ------------ SHM 0.00337 \ No newline at end of file diff --git a/task3/test.c b/task3/test.c new file mode 100644 index 0000000..7104b16 --- /dev/null +++ b/task3/test.c @@ -0,0 +1,18 @@ +#include +#include +#include +#include + +int main() +{ + sem_t* s = sem_open("/sem1", O_CREAT | 0644); + + if (s != SEM_FAILED) + sem_init(s, 1, 5); + else + perror("sem_open"); + + sem_post(s); + sem_post(s); + return 0; +} \ No newline at end of file diff --git a/task3/test1.c b/task3/test1.c new file mode 100644 index 0000000..1531786 --- /dev/null +++ b/task3/test1.c @@ -0,0 +1,15 @@ +#include +#include +#include +#include +#include + +int main() +{ + sem_t* s = sem_open("/sem1", O_RDWR); + + sem_wait(s); + + printf("Leaving semaphore %lu\n", getpid()); + return 0; +} \ No newline at end of file diff --git a/task4/homework/README.md b/task4/homework/README.md new file mode 100644 index 0000000..ec62c55 --- /dev/null +++ b/task4/homework/README.md @@ -0,0 +1 @@ +![Img alt](https://github.com/shaazmik/3_sem_22_23/blob/main/task4/homework/TimeThreads.png) diff --git a/task4/homework/TimeThreads.png b/task4/homework/TimeThreads.png new file mode 100644 index 0000000..c0069d3 Binary files /dev/null and b/task4/homework/TimeThreads.png differ diff --git a/task4/homework/integral.h b/task4/homework/integral.h new file mode 100644 index 0000000..62fdf17 --- /dev/null +++ b/task4/homework/integral.h @@ -0,0 +1,49 @@ +#ifndef INTEGRAL_H +#define INTEGRAL_H + +#include +#include +#include +#include + + +#define PTHREAD_SQRT 4 +#define NPOINTS 100000000 +#define YMAX 8886110 +#define XMAX 4 +#define YMIN 0 +#define XMIN -1 + +#define EPS 0.000001 +//----------------------------------------- +struct PthreadData +{ + double xmin; + double ymin; + + double xmax; + double ymax; + + double(*func)(double); +}; + + +pthread_mutex_t mutex; + +static int P = 0; + +//------------------------------------------ + + +int integralMonteCarlo(double xmax,double ymax,double xmin,double ymin,int count,double(*func)(double)); + +short isEqual(double x, double y); + +void calculate(double(*func)(double), int xmax, int ymax, int xmin, int ymin); + +void* pthreadCalcStep(void* data); + +void printAnswer(double square, int xmax, int xmin); + + +#endif diff --git a/task4/homework/main.c b/task4/homework/main.c new file mode 100644 index 0000000..f514310 --- /dev/null +++ b/task4/homework/main.c @@ -0,0 +1,121 @@ +#include "integral.h" + +#define $ fprintf(stderr, "HERE %d\n", __LINE__); + +#include + +extern int P; + +double func(double x) +{ + return exp(x*x); +} + +short isEqual(double x, double y) +{ + if (abs(x-y) < EPS) return 1; + + return 0; +} + +int integralMonteCarlo(double xmax, double ymax, double xmin, double ymin, int count, double(*func)(double)) +{ + unsigned int id = time(NULL) + pthread_self(); + srand(id); + + double x = 0, y = 0; + int points = 0; + + for (int i = 0; i < count; i++) + { + x = (double)rand_r(&id) / RAND_MAX * (xmax - xmin) + xmin; + y = (double)rand_r(&id) / RAND_MAX * (ymax - ymin) + ymin; + if ( y <= func(x)) points++; + } + + return points; +} + +void* pthreadCalcStep(void* data) +{ + if (!data) + { + fprintf(stderr, "ERR:THREAD DATA HAS BEEN LOST\n"); + return NULL; + } + + struct PthreadData* integralData = (struct PthreadData*)data; + + double xmax = integralData->xmax; + double ymax = integralData->ymax; + double xmin = integralData->xmin; + double ymin = integralData->ymin; + + int points = integralMonteCarlo(xmax, ymax, xmin, ymin, NPOINTS/(PTHREAD_SQRT * PTHREAD_SQRT), integralData->func); + + pthread_mutex_lock(&mutex); + + P += points; + + pthread_mutex_unlock(&mutex); +} + +void calculate(double(*func)(double), int xmax, int ymax, int xmin, int ymin) +{ + pthread_mutex_init(&mutex, NULL); + + double stepScale = (1.0/PTHREAD_SQRT); + double square = (xmax-xmin) * (ymax-ymin); + double xStep = (xmax-xmin) * stepScale; + double yStep = (ymax-ymin) * stepScale; + double curX = xmin; + double curY = ymin; + + struct PthreadData integralData[PTHREAD_SQRT * PTHREAD_SQRT]; + + pthread_t tid[PTHREAD_SQRT * PTHREAD_SQRT]; + + for (int i = 0; i < PTHREAD_SQRT; i++) + { + curY = ymin; + for (int j = 0; j < PTHREAD_SQRT; j++) + { + integralData[i*PTHREAD_SQRT + j].xmin = curX; + integralData[i*PTHREAD_SQRT + j].ymin = curY; + integralData[i*PTHREAD_SQRT + j].xmax = curX + xStep; + curY += yStep; + integralData[i*PTHREAD_SQRT + j].ymax = curY; + integralData[i*PTHREAD_SQRT + j].func = func; + pthread_create(tid + i*PTHREAD_SQRT + j, NULL, pthreadCalcStep, (void*)(integralData + i*PTHREAD_SQRT + j)); + } + curX += xStep; + } + + + for(int i = 0; i < (PTHREAD_SQRT * PTHREAD_SQRT); i++) + { + pthread_join(tid[i], NULL); + } + pthread_mutex_destroy(&mutex); + + printAnswer(square, xmax, xmin); +} + +void printAnswer(double square, int xmax, int xmin) +{ + if (P == 0) + { + fprintf(stderr, "ERR: No selected points (P = 0)\n"); + return; + } + fprintf(stdout, "Integral from xmin = %d to xmax = %d\nValue:%lf\n", xmin, xmax, (square*P)/NPOINTS); +} + +int main() +{ + calculate(func, XMAX, YMAX, XMIN, YMIN); + + return 0; +} + +// pthread 1 = 2,301s pthread 4 = 0,609s pthread 2 = 1,139s pthread 3 = 0,980s pthread 9 = 0,610 etc diff --git a/task4/homework/makefile b/task4/homework/makefile new file mode 100644 index 0000000..a6fafeb --- /dev/null +++ b/task4/homework/makefile @@ -0,0 +1,5 @@ +all: + gcc main.c -o a.out -lm -pthread -fsanitize=address -O0 + +clean: + rm a.out \ No newline at end of file diff --git a/task5/homework/log.txt b/task5/homework/log.txt new file mode 100644 index 0000000..b4d885f --- /dev/null +++ b/task5/homework/log.txt @@ -0,0 +1,26 @@ +MESSAGE WAS WRITTEN, MSG:"swdawudawuduawduajsdlawldkawhldawhd hllajwdhlawdhlawhldlawdjlawdhawhd" +child work is done +MESSAGE WAS WRITTEN, MSG:"wdawdawjdawjawjhd hj" +child work is done +MESSAGE WAS WRITTEN, MSG:"wajdjawjdawjdjawdjkadkjaldawhdalhwkd" +child work is done +parent work is done +parent work is done +message was read +message was read +MESSAGE WAS WRITTEN, MSG:"asduawudwaudhawjddkjawkdjawkdhawdhawkhd" +message was read +MESSAGE WAS WRITTEN, MSG:"daw awd" +message was read +MESSAGE WAS WRITTEN, MSG:"awdhawdjawdjawdawjd" +message was read +parent work is done +child work is done +MESSAGE WAS WRITTEN, MSG:"dajwdjawjdajwdjawjdawjdjawdjawjdjawdjkjdkawhkdhawdkhawhdkawdhawkkjawdkjadw" +message was read +MESSAGE WAS WRITTEN, MSG:"wwwadawda" +message was read +MESSAGE WAS WRITTEN, MSG:"ajwdjwajdjawjdawjdjawdjawj jawdjawjdawjdkawjdkjawdjkwajkdjawkd\" +message was read +MESSAGE WAS WRITTEN, MSG:"awdkawkdkawdkawdkkawd" +message was read diff --git a/task5/homework/main.c b/task5/homework/main.c new file mode 100644 index 0000000..43f1abd --- /dev/null +++ b/task5/homework/main.c @@ -0,0 +1,202 @@ +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +enum MY_SIG +{ + WRITE_SIG = 45, + READ_SIG = 46, + END_SIG = 2 +}; + +enum BOOL_STATUS +{ + WRITE_BOOL = 1, + READ_BOOL = 2, + END_WR_BOOL = 3, + END_RD_BOOL = 4 +}; + +short parent_flag = 1; +short child_flag = 0; +short parent_flag_end = 0; +short child_flag_end = 0; + +const char* name = "HESOYAM"; + +#define SIZE 20480 + +void parent_sigHandler(int signo, siginfo_t* siginf, void* context) +{ + parent_flag = WRITE_BOOL; +} + +void parent_terminationHandler(int signo, siginfo_t* siginf, void* context) +{ + parent_flag_end = END_WR_BOOL; +} + +void child_sigHandler(int signo, siginfo_t* siginf, void* context) +{ + child_flag = READ_BOOL; + FILE* output = fopen("out.txt", "a"); + + fprintf(output, "%s\n", (char*)siginf->si_value.sival_ptr ); + fclose(output); + + FILE* log = fopen("log.txt", "a" ); + fprintf(log, "message was read\n" ); + fclose(log); + + return; +} + +void child_terminationHandler(int signo, siginfo_t* siginf, void* context) +{ + child_flag_end = END_RD_BOOL; +} + + +int main(int argc, const char* argv[]) +{ + int shm_fd = -1; + + void* ptr = NULL; + + shm_fd = shm_open(name, O_CREAT | O_RDWR, 0666); + + ftruncate(shm_fd, SIZE); + + ptr = mmap(0, SIZE, PROT_WRITE, MAP_SHARED, shm_fd, 0); + + if(ptr == MAP_FAILED) + { + perror("mmap"); + exit(1); + } + + pid_t parent_pid = getpid(); + pid_t child_pid = fork(); + + if (child_pid == -1) + { + perror("fork:"); + exit(1); + } + + if (child_pid > 0) + { + size_t size = 0; + + sigset_t mask; + + sigemptyset(&mask); + sigaddset(&mask, WRITE_SIG); + sigaddset(&mask, END_SIG); + + struct sigaction sa_write, sa_end; + + sa_end.sa_sigaction = parent_terminationHandler; + sa_end.sa_mask = mask; + sa_end.sa_flags = SA_SIGINFO; + sa_write.sa_sigaction = parent_sigHandler; + sa_write.sa_mask = mask; + sa_write.sa_flags = SA_SIGINFO; + + union sigval val; + + sigaction(END_SIG, &sa_end, NULL); + sigaction(WRITE_SIG, &sa_write, NULL); + + FILE* log = NULL; + + while (1) { + + if (parent_flag == WRITE_BOOL) { + + if ( scanf( "%[^\n]", (char*)(ptr + size) ) == 1 ){ + + while( getchar() != '\n' ); + val.sival_ptr = ptr + size; + parent_flag = 0; + log = fopen("log.txt", "a" ); + fprintf(log, "MESSAGE WAS WRITTEN, MSG:\"%s\"\n", (char*)(ptr + size)); + fclose(log); + size += strlen( (char*)(ptr + size) ); + if ( size >= SIZE ) size = 0; + sigqueue( child_pid, READ_SIG, val); + } + + } + + if ( parent_flag_end == END_WR_BOOL ) + { + log = fopen("log.txt", "a" ); + fprintf( log, "parent work is done\n"); + fclose( log ); + child_flag_end = END_RD_BOOL; + parent_flag_end = 0; + parent_flag = 0; + int status = 0; + waitpid(child_pid, &status, 0); + kill(child_pid, END_SIG); + return 0; + } + } + } + else + { + close(0); + close(1); + close(2); + FILE* log = NULL; + + sigset_t mask; + sigemptyset( &mask ); + sigaddset( &mask, END_SIG ); + sigaddset( &mask, READ_SIG ); + + struct sigaction sa_end, sa_read; + + sa_end.sa_sigaction = child_terminationHandler; + sa_end.sa_mask = mask; + sa_end.sa_flags = SA_SIGINFO; + sa_read.sa_sigaction = child_sigHandler; + sa_read.sa_mask = mask; + sa_read.sa_flags = SA_SIGINFO; + + sigaction(END_SIG, &sa_end, NULL); + sigaction(READ_SIG, &sa_read, NULL); + + while(1) + { + + if (child_flag == READ_BOOL) { + + child_flag = 0; + kill( parent_pid, WRITE_SIG); + } + + if ( child_flag_end == END_RD_BOOL ) + { + + log = fopen("log.txt", "a" ); + fprintf(log, "child work is done\n"); + fclose(log); + shm_unlink(name); + munmap(ptr, SIZE); + kill(parent_pid, SIGCHLD); + return 0; + } + } + } + + return 0; +} \ No newline at end of file diff --git a/task5/homework/out.txt b/task5/homework/out.txt new file mode 100644 index 0000000..5e15764 --- /dev/null +++ b/task5/homework/out.txt @@ -0,0 +1,4 @@ +dajwdjawjdajwdjawjdawjdjawdjawjdjawdjkjdkawhkdhawdkhawhdkawdhawkkjawdkjadw +wwwadawda +ajwdjwajdjawjdawjdjawdjawj jawdjawjdawjdkawjdkjawdjkwajkdjawkd\ +awdkawkdkawdkawdkkawd diff --git a/task6/homework/bashDiff.sh b/task6/homework/bashDiff.sh new file mode 100644 index 0000000..545bc8b --- /dev/null +++ b/task6/homework/bashDiff.sh @@ -0,0 +1,15 @@ +#! /bin/bash + +printf '\n%90s\n' | tr ' ' = >> $2 +printf '\n%90s\n' | tr ' ' ? >> $2 +printf '\n%90s\n\n' | tr ' ' = >> $2 + +for sample_name in `ls ./SampleData | sort -r -d | head -$1` +do + cat ./SampleData/$sample_name >> $2 + echo "" >> $2 +done + +printf '\n%90s\n' | tr ' ' = >> $2 +printf '\n%90s\n' | tr ' ' ! >> $2 +printf '\n%90s\n\n' | tr ' ' = >> $2 \ No newline at end of file diff --git a/task6/homework/daemon.h b/task6/homework/daemon.h new file mode 100644 index 0000000..1bd53ab --- /dev/null +++ b/task6/homework/daemon.h @@ -0,0 +1,69 @@ +#ifndef DAEMON_H +#define DAEMON_H + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include "log.h" +#include + +#define _GNU_SOURCE + + +enum Mods getCMDargs(int argc, char* argv[], pid_t* pid); +char* getCurDir(pid_t pid, char* curDir); +int saveDirData(const char* curDir); +int cp(const char *to, const char *from); +int createDir(const char* dir_name); + +void createDaemon(); + +void registerSignals(); +FILE* prepareInterface(); +int fifo_init(); +int getCmdFromBuff(const char* cmd_buffer, int* arg); +int getInterface(int fifo_fd, int* arg); + +int pollSamples(int inotify_fd, const char* work_dir); +void create_diff (const char* observed_file_path, const char* file_name); +int is_text_file(const char* file); +void create_sample(); +void getTimestamp(char* timestamp); + + + +#define PATH_MAX_SIZE 255 +#define CMD_SIZE 4096 +#define NOTIFY_SIZE (10 * (sizeof(struct inotify_event) + NAME_MAX + 1)) +#define STAMP_SIZE 255 + + +#define DAEMON_DIR "./DaemonData" +#define DAEMON_CMD "DaemonCmd.txt" +#define DIFF_DIR "./DaemonDiff" +#define FIFO_DIR "./tmp/LogDaemon.fifo" +#define SAMPLE_DATA_DIR "./SampleData" + +enum Mods +{ + BASH = 0, + DAEMON = 1, +}; + +enum Interface +{ + PRINTLOGS = 1336, + KILL_DAEMON = 1337, + NO_CMD = 1338, + PERIOD = 1339, + ERROR = 1400, +}; + +#endif \ No newline at end of file diff --git a/task6/homework/interface.c b/task6/homework/interface.c new file mode 100644 index 0000000..83aa97d --- /dev/null +++ b/task6/homework/interface.c @@ -0,0 +1,138 @@ +#include "daemon.h" + +void createDaemon() +{ + pid_t pid; + /* Fork off the parent process */ + pid = fork(); + + /* An error occurred */ + if (pid < 0) + exit(EXIT_FAILURE); + + /* Success: Let the parent terminate */ + if (pid > 0) + { + exit(EXIT_SUCCESS); + } + + /* On success: The child process becomes session leader */ + if (setsid() < 0) + exit(EXIT_FAILURE); + + /* Fork off for the second time*/ + pid = fork(); + + /* An error occurred */ + if (pid < 0) + exit(EXIT_FAILURE); + + /* Success: Let the parent terminate */ + if (pid > 0) + { + exit(EXIT_SUCCESS); + } +} + + +void signalHnd() +{ + fprintf(stdout, "Can't sent signal to proccess pid:%d\n", getpid()); + LOG("Trying send signal\n"); +} + +void registerSignals() +{ + signal(SIGINT, signalHnd); + signal(SIGQUIT, signalHnd); + signal(SIGABRT, signalHnd); + signal(SIGTRAP, signalHnd); + signal(SIGTERM, signalHnd); + signal(SIGCONT, signalHnd); + signal(SIGTSTP, signalHnd); +} + +FILE* prepareInterface() +{ + registerSignals(); + + FILE* cmdFile = fopen(DAEMON_CMD, "w"); + + if (!cmdFile) + { + LOG("ERROR CMD FILE:"); + return NULL; + } + + mode_t old_umask = umask(0); + + createDir(DAEMON_DIR); + createDir(DIFF_DIR); + createDir(SAMPLE_DATA_DIR); + + return cmdFile; +} + + +int fifo_init() +{ + createDir("tmp"); + mkfifo(FIFO_DIR, 0666); + + int fifo_fd = -1; + fprintf(stdout, "Write something in FIFO to start DAEMON\n"); + + fifo_fd = open(FIFO_DIR, O_RDONLY); + fprintf(stdout, "fifo_fd: %d\n", fifo_fd); + + return fifo_fd; +} + +int getInterface(int fifo_fd, int* arg) +{ + char cmdBuffer[CMD_SIZE] = {}; + size_t readRet = 0; + + readRet = read(fifo_fd, cmdBuffer, CMD_SIZE); + + if (readRet == 0 || (readRet == -1 && errno == EAGAIN)) + return NO_CMD; + + int cmd = getCmdFromBuff(cmdBuffer, arg); + + return cmd; +} + +int getCmdFromBuff(const char* cmd_buffer, int* arg) +{ + char cmdStr[CMD_SIZE] = {}; + int ret_val = sscanf(cmd_buffer, "%s %d", cmdStr, arg); + + switch (ret_val) + { + case 2: + if (!strcmp(cmdStr, "setTime")) + { + return PERIOD; + } + if (!strcmp(cmdStr, "printLog")) + { + return PRINTLOGS; + } + return ERROR; + break; + + case 1: + if (!strcmp(cmdStr, "kill")) + return KILL_DAEMON; + else + return ERROR; + break; + + default: + LOG("CMD GETTING FROM BUFF ERROR"); + return NO_CMD; + } + + return ERROR; +} \ No newline at end of file diff --git a/task6/homework/log.c b/task6/homework/log.c new file mode 100644 index 0000000..4f86d70 --- /dev/null +++ b/task6/homework/log.c @@ -0,0 +1,38 @@ +#include "log.h" + + +void closeLog() +{ + fclose(log); +} + +void startLogging() +{ + log = fopen("log.txt", "w"); + + atexit(closeLog); +} + +void showExample() +{ + fprintf(stderr, "Program example:\n" + "MODS: -b [BASH MOD], -d [DAEMON MOD]\n" + "\'name.out -b 5\'\n" + "BASH MOD WITH PID = 5\n" + "\'name.out -d 13\'\n" + "DAEMON MOD WITH PID = 13\n" + "\'name.out 19\'\n" + "BASH MOD [BY DEFAULTS] WITH PID = 19\n"); +} + + +void logVar(const char* format, ...) +{ + va_list args; + va_start(args, format); + + vfprintf(log, format, args); + fputc('\n', log); + fflush(log); + va_end(args); +} \ No newline at end of file diff --git a/task6/homework/log.h b/task6/homework/log.h new file mode 100644 index 0000000..5d21111 --- /dev/null +++ b/task6/homework/log.h @@ -0,0 +1,41 @@ +#ifndef LOG_H +#define LOG_H + +#include +#include +#include + +FILE* log; + +#ifndef NDEBUG + +#define $ fprintf(stderr, "LINE %d\n", __LINE__); + +#endif + +#define LOG_FUNC(function_name) fprintf(log, "CALLING FUNC: \'%s\' ON %d LINE\n", #function_name, __LINE__); \ + fprintf(stderr, "ERROR: check log.txt\n"); + + + + +#define LOG(msg) fprintf(log, "\nLOGGER_MSG\n" \ + "MSG: %s\n" \ + "FUNC:%s\n" , msg, __FUNCTION__); \ + + + +void closeLog(); + +void startLogging(); + +void showExample(); + +void logVar(const char* format, ...); + + +#define EXIT_ERROR -1337 + + + +#endif \ No newline at end of file diff --git a/task6/homework/main.c b/task6/homework/main.c new file mode 100644 index 0000000..8fd7fa8 --- /dev/null +++ b/task6/homework/main.c @@ -0,0 +1,88 @@ +#include "daemon.h" +#include "log.h" + + +int main(int argc, char* argv[]) +{ + system("make clean"); + startLogging(); + pid_t pid = 0; + + FILE* cmdFile = prepareInterface(); + int mod = getCMDargs(argc, argv, &pid); + + fprintf(stdout, "DaemonLog pid: %d\n", getpid()); + + if (mod == DAEMON) + { + createDaemon(); + } + + char workDir[PATH_MAX_SIZE] = {}; + + if (!getCurDir(pid, workDir)) + { + LOG_FUNC(getCurDir); + return -1; + } + + saveDirData(workDir); + + int inotify_fd = 0; + inotify_fd = inotify_init(); + + fcntl(inotify_fd, F_SETFL, fcntl (inotify_fd, F_GETFL) | O_NONBLOCK); + + int fifo_fd = fifo_init(); + if (fifo_fd == -1) return -1; + + fcntl(fifo_fd, F_SETFL, fcntl (inotify_fd, F_GETFL) | O_NONBLOCK); + + inotify_add_watch(inotify_fd, workDir, IN_MODIFY); + + int T = 3; + char cmd_buffer[CMD_SIZE] = {}; + int DAEMON_HP = 1; + + for (int i = 0; DAEMON_HP; i++, sleep(T)) + { + LOG("START SAMPLING"); + int arg = -1; + int cmd = getInterface(fifo_fd, &arg); + + switch (cmd) + { + case KILL_DAEMON: + LOG("KILL DAEMON"); + DAEMON_HP = 0; + break; + + case PERIOD: + logVar("Set period:from %d to %d\n", T, arg); + T = arg; + break; + + case PRINTLOGS: + logVar("Count of last logs: %d\n", arg); + sprintf(cmd_buffer, "bash bashDiff.sh %d %s", arg, DAEMON_CMD); + system(cmd_buffer); + break; + + case ERROR: + LOG("ERROR"); + break; + + case NO_CMD: + LOG("NO CMD\n"); + break; + } + + pollSamples(inotify_fd, workDir); + system("bash saveSamples.sh -k1"); + } + + fclose(cmdFile); + close(fifo_fd); + + return 0; +} \ No newline at end of file diff --git a/task6/homework/makefile b/task6/homework/makefile new file mode 100644 index 0000000..b8d43c9 --- /dev/null +++ b/task6/homework/makefile @@ -0,0 +1,12 @@ +all: + gcc main.c log.c parser.c interface.c polling.c -o daemon.out -ggdb3 -O0 -w -Wfloat-equal -Wformat-nonliteral -Wformat-security -Wformat-signedness -Wformat=2 -Winline -Wlogical-op -Wopenmp-simd -Wpacked -Wpointer-arith -Winit-self -Wredundant-decls -Wshadow -Wsign-conversion -Wstrict-overflow=2 -Wsuggest-attribute=noreturn -Wsuggest-final-methods -Wsuggest-final-types -Wswitch-default -Wswitch-enum -Wsync-nand -Wundef -Wunreachable-code -Wunused -Wvariadic-macros -Wno-missing-field-initializers -Wno-narrowing -Wno-varargs -Wstack-protector -fcheck-new -fstack-protector -fstrict-overflow -flto-odr-type-merging -fno-omit-frame-pointer -pie -fPIE -fsanitize=address,alignment,bool,bounds,enum,float-cast-overflow,float-divide-by-zero,integer-divide-by-zero,leak,nonnull-attribute,null,object-size,return,returns-nonnull-attribute,shift,signed-integer-overflow,undefined,unreachable,vla-bound,vptr + +gg: + gcc main.c log.c parser.c interface.c polling.c -o daemon.out -DNDEBUG + +clean: + rm -rf DaemonData + rm -rf tmp + rm -rf DaemonDiff + rm -rf SampleData + rm DaemonCmd.txt \ No newline at end of file diff --git a/task6/homework/parser.c b/task6/homework/parser.c new file mode 100644 index 0000000..a754b6a --- /dev/null +++ b/task6/homework/parser.c @@ -0,0 +1,194 @@ +#include "daemon.h" + +enum Mods getCMDargs(int argc, char* argv[], pid_t* pid) +{ + int mod = BASH; + + switch (argc) + { + case 3: + if (!strcmp(argv[1], "-b")) + { + mod = BASH; + } + else if(!strcmp(argv[1], "-d")) + { + mod = DAEMON; + } + else + { + fprintf(stderr, "Wrong Mod:\n\n"); + showExample(); + exit(EXIT_ERROR); + } + + *pid = atoi(argv[2]); + if (*pid == 0) + { + fprintf(stderr, "Wrong PID:\n\n"); + showExample(); + exit(EXIT_ERROR); + } + return mod; + break; + + case 2: + *pid = atoi(argv[1]); + if (*pid == 0) + { + fprintf(stderr, "Wrong PID:\n\n"); + showExample(); + exit(EXIT_ERROR); + } + break; + + default: + fprintf(stderr, "Wrong arguments:\n\n"); + showExample(); + exit(1); + break; + } + + return BASH; +} + + +char* getCurDir(pid_t pid, char* curDir) +{ + char proc_dir_path[PATH_MAX_SIZE] = {}; + + sprintf(proc_dir_path, "/proc/%d/cwd", pid); + + if(readlink(proc_dir_path, curDir, PATH_MAX_SIZE) == -1) + { + perror("readlink:"); + LOG("readlink:"); + return NULL; + } + + return curDir; +} + +int cp(const char *to, const char *from) +{ + int fd_to, fd_from; + char buf[4096]; + ssize_t nread; + int saved_errno; + + fd_from = open(from, O_RDONLY); + if (fd_from < 0) + return -1; + + fd_to = open(to, O_WRONLY | O_CREAT | O_EXCL, 0666); + if (fd_to < 0) + goto out_error; + + while (nread = read(fd_from, buf, sizeof buf), nread > 0) + { + char *out_ptr = buf; + ssize_t nwritten; + + do { + nwritten = write(fd_to, out_ptr, nread); + + if (nwritten >= 0) + { + nread -= nwritten; + out_ptr += nwritten; + } + else if (errno != EINTR) + { + goto out_error; + } + } while (nread > 0); + } + + if (nread == 0) + { + if (close(fd_to) < 0) + { + fd_to = -1; + goto out_error; + } + close(fd_from); + + return 0; + } + +out_error: + saved_errno = errno; + + close(fd_from); + if (fd_to >= 0) + close(fd_to); + + errno = saved_errno; + return -1; +} + +int createDir(const char* dir_name) +{ + mode_t old_umask = umask(0); + + int ret = mkdir(dir_name, 0777); + + if (ret == ERROR && errno != EEXIST) + { + perror("mkdir:"); + LOG("mkdir:"); + return ERROR; + } + + umask(old_umask); + + return ret; +} + +int saveDirData(const char* curDir) +{ + char* destPath[PATH_MAX_SIZE] = {}; + strcpy(destPath, DAEMON_DIR); + char* destDirEnd = strchr(destPath,'\0'); + *destDirEnd++ = '/'; + *destDirEnd = '\0'; + + char srcPath[PATH_MAX_SIZE] = {}; + strcpy(srcPath, curDir); + char* srcDirEnd = strchr(srcPath, '\0'); + *srcDirEnd++ = '/'; + *srcDirEnd = '\0'; + + DIR *dirp; + struct dirent* sdir; + + dirp = opendir(curDir); + + if (dirp == NULL) + { + LOG("opendir failed in PATH\n"); + return -1; + } + + for (;;) + { + sdir = readdir(dirp); + + if (sdir == NULL) + break; + + if (sdir->d_type != DT_REG) + continue; + + strcat(destPath, sdir->d_name); + strcat(srcPath, sdir->d_name); + cp(destPath, srcPath); + + *destDirEnd = '\0'; + *srcDirEnd = '\0'; + } + + closedir(dirp); + + return 0; +} \ No newline at end of file diff --git a/task6/homework/polling.c b/task6/homework/polling.c new file mode 100644 index 0000000..8205fd6 --- /dev/null +++ b/task6/homework/polling.c @@ -0,0 +1,104 @@ +#include "daemon.h" + +int pollSamples(int inotify_fd, const char* work_dir) +{ + char buf[NOTIFY_SIZE] = {}; + errno = 0; + + int numRead = read(inotify_fd, buf, NOTIFY_SIZE); + + if (numRead == 0) + { + LOG("read() from inotify fd returned 0!"); + } + else if (numRead == ERROR && errno == EAGAIN) + { + LOG("No events happened"); + return 0; + } + else if (numRead == ERROR) + { + LOG("inotify read error"); + return ERROR; + } + + char* p = NULL; + short f_textChanged = 0; + for (p = buf; p < buf + numRead; ) + { + struct inotify_event* event = (struct inotify_event *) p; + logVar("There is change with %s\n", event->name); + + char file[PATH_MAX] = {}; + sprintf(file, "%s/%s", work_dir, event->name); + + if (is_text_file(file)) + { + logVar("%s is text", event->name); + create_diff(file, event->name); + f_textChanged = 1; + } + + p += sizeof(struct inotify_event) + event->len; + } + + if (f_textChanged) + { + create_sample(); + } + + return f_textChanged; +} + + + +void create_diff (const char* observed_file_path, const char* file_name) +{ + char backup_file[PATH_MAX] = {}; + sprintf(backup_file, "%s/%s", DAEMON_DIR, file_name); + + char cmd[CMD_SIZE] = {}; + sprintf(cmd, "diff -Nbur %s %s > %s/%s.diff", + backup_file, observed_file_path, DIFF_DIR, file_name); + + system(cmd); +} + +int is_text_file(const char* file) +{ + char cmd[CMD_SIZE] = {}; + sprintf(cmd, "file %s | grep \":*text\" > /dev/null", file); + + int sys_ret = 0; + sys_ret = system(cmd); + + return sys_ret == 0 ? 1 : 0; +} + +void create_sample() +{ + char timestamp[STAMP_SIZE] = {}; + getTimestamp(timestamp); + + char cmd[CMD_SIZE] = {}; + + sprintf(cmd, "cat %s/*.diff > %s/%s.sample", DIFF_DIR, SAMPLE_DATA_DIR, timestamp); + logVar("SAMPLE execut: %s", cmd); + system(cmd); + + sprintf(cmd, "rm %s/*.diff", DIFF_DIR); + system(cmd); +} + +void getTimestamp(char* timestamp) +{ + static int timetmp = 0; + + sprintf (timestamp,"%d", timetmp); + timetmp++; + + for (; *timestamp; timestamp++) + if (*timestamp == ' ' || *timestamp == '\n') *timestamp = '_'; + + return 0; +} \ No newline at end of file diff --git a/task6/homework/saveSamples.sh b/task6/homework/saveSamples.sh new file mode 100644 index 0000000..f3a0043 --- /dev/null +++ b/task6/homework/saveSamples.sh @@ -0,0 +1,16 @@ +#! /bin/bash + +while getopts ":k:r" options; +do + case "$options" in + r) patch_reverse=-R + echo "$OPTARG" + ;; + k) sample_deep=${OPTARG};; + esac +done + +for sample_name in `ls ./SampleData | sort -r -d | head -$sample_deep` +do + patch -s -N $patch_reverse -d ./DaemonData < ./SampleData/$sample_name > /dev/null +done \ No newline at end of file