feat[OS/lab5]: completed part A
This commit is contained in:
12
OSs/lab5/part-A/Makefile
Normal file
12
OSs/lab5/part-A/Makefile
Normal file
@ -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
|
||||||
132
OSs/lab5/part-A/main.c
Normal file
132
OSs/lab5/part-A/main.c
Normal file
@ -0,0 +1,132 @@
|
|||||||
|
#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;
|
||||||
|
}
|
||||||
Reference in New Issue
Block a user