From 949f1b8ac4f16b285a52514ea1276e65fef3ec86 Mon Sep 17 00:00:00 2001 From: ElectronixTM Date: Thu, 2 Oct 2025 22:55:31 +0300 Subject: [PATCH] feat[OS/lab5]: completed part A --- OSs/lab5/part-A/Makefile | 12 ++++ OSs/lab5/part-A/main.c | 132 +++++++++++++++++++++++++++++++++++++++ 2 files changed, 144 insertions(+) create mode 100644 OSs/lab5/part-A/Makefile create mode 100644 OSs/lab5/part-A/main.c diff --git a/OSs/lab5/part-A/Makefile b/OSs/lab5/part-A/Makefile new file mode 100644 index 0000000..da8fa15 --- /dev/null +++ b/OSs/lab5/part-A/Makefile @@ -0,0 +1,12 @@ +targets = main +all: $(targets) + +main: main.o + $(CC) -o $@ $^ $(CFLAGS) + +%.o: %.c + $(CC) -c $^ -o $@ $(CFLAGS) + +clean: + rm -f $(targets) + rm -f *.o diff --git a/OSs/lab5/part-A/main.c b/OSs/lab5/part-A/main.c new file mode 100644 index 0000000..fb46854 --- /dev/null +++ b/OSs/lab5/part-A/main.c @@ -0,0 +1,132 @@ +#include +#include +#include +#include +#include +#include +#include + +#define PIPE_READ_IDX 0 +#define PIPE_WRITE_IDX 1 + +int client(int fd_read, int fd_write); +int server(int fd_read, int fd_write); + +#define DO_OR_FAIL(cond) if (cond) return EXIT_FAILURE +int main() +{ + int pipe_to_server[2], pipe_to_client[2]; + DO_OR_FAIL(pipe(pipe_to_server) < 0); + DO_OR_FAIL(pipe(pipe_to_client) < 0); + + pid_t client_pid; + if ((client_pid = fork()) == 0) { // server + DO_OR_FAIL(close(pipe_to_server[PIPE_WRITE_IDX])); + DO_OR_FAIL(close(pipe_to_client[PIPE_READ_IDX])); + + DO_OR_FAIL( + server( + pipe_to_server[PIPE_READ_IDX], + pipe_to_client[PIPE_WRITE_IDX] + ) + ); + } + // client + DO_OR_FAIL(close(pipe_to_server[PIPE_READ_IDX])); + DO_OR_FAIL(close(pipe_to_client[PIPE_WRITE_IDX])); + + DO_OR_FAIL( + client( + pipe_to_client[PIPE_READ_IDX], + pipe_to_server[PIPE_WRITE_IDX] + ) + ); + + return 0; +} + +char *ltrim(char *s) +{ + while(isspace(*s)) s++; + return s; +} + +char *rtrim(char *s) +{ + char* back = s + strlen(s); + while(isspace(*--back)); + *(back+1) = '\0'; + return s; +} + +char *trim(char *s) +{ + return rtrim(ltrim(s)); +} + +#define BUF_SIZE 256 + +#define DO_OR_PROPAGATE(call, expected, tmp_var) \ + if ((tmp_var = (call)) != expected)) return tmp_var + +/** + * Performs client actions + * + * @fd_read - pipe to read from + * @fd_write - pipe to write t\no + * + * returns 0 on success or -errno on fail + */ +int client(int fd_read, int fd_write) +{ + char buf[BUF_SIZE] = {0}; + if (!fgets(buf, BUF_SIZE, stdin)) return -EFAULT; + const char *s = trim(buf); + size_t len = strlen(s); + ssize_t n_written = write(fd_write, s, len); + if (n_written < 0 || n_written < len) { + return -EFAULT; + } + memset(buf, 0, BUF_SIZE); + size_t n; + while ((n = read(fd_read, buf, BUF_SIZE)) > 0) { + len = strlen(buf); + n_written = fwrite(buf, sizeof(buf[0]), strlen(buf), stdout); + if (n_written < 0 || n_written < len) { + return -EFAULT; + } + memset(buf, 0, sizeof(buf)); + } + return 0; +} + +/** + * Performs server actions + * + * @fd_read - pipe to read from + * @fd_write - pipe to write to + * + * returns 0 on success or -errno on fail + */ +int server(int fd_read, int fd_write) +{ + char buf[BUF_SIZE] = {0}; + size_t n = read(fd_read, buf, BUF_SIZE); + if (n == 0) return -EFAULT; + FILE *f = fopen(buf, "r"); + // не 100% правильно, но наиболее вероятно + if (f == NULL) { + const char error_msg[] = "Can't open requested file\n"; + write(fd_write, error_msg, sizeof(error_msg)); + goto epilog; + } + + while ((n = fread(buf, sizeof(buf[0]), BUF_SIZE, f)) > 0) { + write(fd_write, buf, n); + memset(buf, 0, sizeof(buf)); + } + +epilog: + fclose(f); + return 0; +}