diff options
Diffstat (limited to 'semestr-5/so/lista5/so21_lista_5/prime.c')
-rw-r--r-- | semestr-5/so/lista5/so21_lista_5/prime.c | 97 |
1 files changed, 97 insertions, 0 deletions
diff --git a/semestr-5/so/lista5/so21_lista_5/prime.c b/semestr-5/so/lista5/so21_lista_5/prime.c new file mode 100644 index 0000000..80ed3c6 --- /dev/null +++ b/semestr-5/so/lista5/so21_lista_5/prime.c @@ -0,0 +1,97 @@ +#include "csapp.h" + +typedef struct { + int read; + int write; +} pipe_t; + +static inline pipe_t MakePipe(void) { + int fds[2]; + Pipe(fds); + return (pipe_t){.read = fds[0], .write = fds[1]}; +} + +static inline void CloseReadEnd(pipe_t p) { + Close(p.read); +} + +static inline void CloseWriteEnd(pipe_t p) { + Close(p.write); +} + +static bool ReadNum(pipe_t p, long *valp) { + return Read(p.read, valp, sizeof(long)) == sizeof(long); +} + +static bool WriteNum(pipe_t p, long val) { + return Write(p.write, &val, sizeof(long)) == sizeof(long); +} + +static noreturn void generator(pipe_t out, long maxprime) { + for (long n = 2; n <= maxprime; n++) + WriteNum(out, n); + exit(EXIT_SUCCESS); +} + +static void filter(pipe_t in, pipe_t out, long prime) { + long num; + while (ReadNum(in, &num)) { + if (num % prime != 0) + WriteNum(out, num); + } +} + +static noreturn void filter_chain(pipe_t in) { + long prime; + + /* TODO: Something is missing here! */ + pipe_t out = MakePipe(); + if (!ReadNum(in, &prime)) { + exit(EXIT_SUCCESS); + } + printf("%ld\n", prime); + if (Fork()) { /* parent */ + close(out.read); + filter(in, out, prime); + close(out.write); + close(in.read); + Wait(NULL); + } else { /* child */ + close(out.write); + close(in.read); + filter_chain(out); + } + + exit(EXIT_SUCCESS); +} + +int main(int argc, char *argv[]) { + if (argc != 2) + app_error("Usage: %s [MAXPRIME]", argv[0]); + + long maxprime = atol(argv[1]); + + if (maxprime < 2 || maxprime > 10000) + app_error("Give maximum prime number in range from 2 to 10000!"); + + /* Spawn generator. */ + pipe_t gen_pipe = MakePipe(); + if (Fork()) { /* parent */ + CloseWriteEnd(gen_pipe); + } else { /* child */ + CloseReadEnd(gen_pipe); + generator(gen_pipe, maxprime); + } + + /* Spawn filter chain. */ + if (Fork()) { /* parent */ + CloseReadEnd(gen_pipe); + } else { /* child */ + filter_chain(gen_pipe); + } + + for (int i = 0; i < 2; i++) + Wait(NULL); + + return 0; +} |