133 lines
3.0 KiB
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;
|
|
}
|