From 72d5756b795386610593f42bce0f3bde58c9b604 Mon Sep 17 00:00:00 2001 From: ElectronixTM Date: Fri, 3 Oct 2025 00:24:30 +0300 Subject: [PATCH] feat[OS/lab5]: completed part B --- OSs/lab5/part-B/Makefile | 15 ++++++++ OSs/lab5/part-B/client.c | 80 ++++++++++++++++++++++++++++++++++++++++ OSs/lab5/part-B/common.h | 45 ++++++++++++++++++++++ OSs/lab5/part-B/server.c | 66 +++++++++++++++++++++++++++++++++ 4 files changed, 206 insertions(+) create mode 100644 OSs/lab5/part-B/Makefile create mode 100644 OSs/lab5/part-B/client.c create mode 100644 OSs/lab5/part-B/common.h create mode 100644 OSs/lab5/part-B/server.c diff --git a/OSs/lab5/part-B/Makefile b/OSs/lab5/part-B/Makefile new file mode 100644 index 0000000..959d36a --- /dev/null +++ b/OSs/lab5/part-B/Makefile @@ -0,0 +1,15 @@ +targets = server client +all: $(targets) + +server: server.o + $(CC) -o $@ $^ $(CFLAGS) + +client: client.o + $(CC) -o $@ $^ $(CFLAGS) + +%.o: %.c + $(CC) -c $^ -o $@ $(CFLAGS) + +clean: + rm -f $(targets) + rm -f *.o diff --git a/OSs/lab5/part-B/client.c b/OSs/lab5/part-B/client.c new file mode 100644 index 0000000..3b5d104 --- /dev/null +++ b/OSs/lab5/part-B/client.c @@ -0,0 +1,80 @@ +#include +#include +#include +#include +#include +#include +#include + +#include "common.h" + +int client(int fd_read, int fd_write); + +int main() +{ + int read_fd, write_fd; + FAIL_ON((write_fd=open(FIFO_SERVER_PATH, O_WRONLY)) < 0); + FAIL_ON((read_fd=open(FIFO_CLIENT_PATH, O_RDONLY)) < 0); + + FAIL_ON(client(read_fd, write_fd)); + + FAIL_ON(unlink(FIFO_SERVER_PATH) < 0); + printf("unlinked %s\n", FIFO_SERVER_PATH); + FAIL_ON(unlink(FIFO_CLIENT_PATH) < 0); + printf("unlinked %s\n", FIFO_CLIENT_PATH); + + return EXIT_SUCCESS; +} + +#define BUF_SIZE 256 + +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)); +} + +/** + * 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; + struct custom_ds ds; + while ((n = recv_msg(fd_read, &ds)) > 0) { + len = ds.hdr.len; + n_written = fwrite(ds.msg, sizeof(ds.msg[0]), len, stdout); + if (n_written < 0 || n_written < len) { + return -EFAULT; + } + memset(buf, 0, sizeof(buf)); + } + return 0; +} diff --git a/OSs/lab5/part-B/common.h b/OSs/lab5/part-B/common.h new file mode 100644 index 0000000..c733f78 --- /dev/null +++ b/OSs/lab5/part-B/common.h @@ -0,0 +1,45 @@ +#ifndef COMMON_H_ +#define COMMON_H_ + +#include +#include +#include + +#define FIFO_SERVER_PATH "/tmp/fifo.to_server" // server reads this file +#define FIFO_CLIENT_PATH "/tmp/fifo.to_client" // client reads this file + +#define __DATA_STRUCT_MSG_LEN 4096 + +enum ds_types { + DS_MESSAGE, + DS_FAIL +}; + +struct custom_ds { + struct { + long len; + long type; + } hdr; + char msg[__DATA_STRUCT_MSG_LEN]; +}; + +static inline ssize_t send_msg(int fd, const struct custom_ds *ds) +{ + return write(fd, ds, sizeof(ds->hdr) + ds->hdr.len); +} + +static inline ssize_t recv_msg(int fd, struct custom_ds *reciever) +{ + size_t n_hdr = read(fd, reciever, sizeof(reciever->hdr)); + if (n_hdr == 0) return 0; // eof reached + if (n_hdr != sizeof(reciever->hdr)) return -ENOMSG; + if (reciever->hdr.len == 0) return 0; + + size_t n_payload = read(fd, &reciever->msg, reciever->hdr.len); + if (n_payload != reciever->hdr.len) return -EFAULT; + return n_hdr + n_payload; +} + +#define FAIL_ON(cond) if (cond) return EXIT_FAILURE + +#endif diff --git a/OSs/lab5/part-B/server.c b/OSs/lab5/part-B/server.c new file mode 100644 index 0000000..6acc413 --- /dev/null +++ b/OSs/lab5/part-B/server.c @@ -0,0 +1,66 @@ +#include +#include +#include +#include +#include + +#include "common.h" + +int server(int fd_read, int fd_write); + +int main() +{ + FAIL_ON(mknod(FIFO_SERVER_PATH, S_IFIFO | 0666, 0) < 0); + printf("created %s\n", FIFO_SERVER_PATH); + FAIL_ON(mknod(FIFO_CLIENT_PATH, S_IFIFO | 0666, 0) < 0); + printf("created %s\n", FIFO_CLIENT_PATH); + + int read_fd, write_fd; + FAIL_ON((read_fd=open(FIFO_SERVER_PATH, O_RDONLY)) < 0); + FAIL_ON((write_fd=open(FIFO_CLIENT_PATH, O_WRONLY)) < 0); + + return server(read_fd, write_fd); +} + +#define BUF_SIZE 256 + +/** + * 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"; + struct custom_ds payload = { + .hdr.len = sizeof(error_msg), + .hdr.type = DS_FAIL, + }; + strncpy(payload.msg, error_msg, sizeof(error_msg)); + send_msg(fd_write, &payload); + goto epilog; + } + + while ((n = fread(buf, sizeof(buf[0]), BUF_SIZE, f)) > 0) { + struct custom_ds payload = { + .hdr.len = n, + .hdr.type = DS_MESSAGE, + }; + strncpy(payload.msg, buf, n); + send_msg(fd_write, &payload); + memset(buf, 0, sizeof(buf)); + } + +epilog: + fclose(f); + return 0; +}