aboutsummaryrefslogtreecommitdiff
path: root/semestr-5/so/lista5/so21_lista_5/prime.c
diff options
context:
space:
mode:
Diffstat (limited to 'semestr-5/so/lista5/so21_lista_5/prime.c')
-rw-r--r--semestr-5/so/lista5/so21_lista_5/prime.c97
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;
+}