#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; }