Files
AwesomePolytech/OSs/lab5/part-A/main.c

133 lines
3.0 KiB
C

#include <unistd.h>
#include <stdlib.h>
#include <stdio.h>
#include <errno.h>
#include <stdbool.h>
#include <string.h>
#include <ctype.h>
#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;
}