aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--c/pipe/.gitignore1
-rw-r--r--c/pipe/Makefile8
-rw-r--r--c/pipe/pipe.c75
3 files changed, 84 insertions, 0 deletions
diff --git a/c/pipe/.gitignore b/c/pipe/.gitignore
new file mode 100644
index 0000000..6b14dd0
--- /dev/null
+++ b/c/pipe/.gitignore
@@ -0,0 +1 @@
+pipe
diff --git a/c/pipe/Makefile b/c/pipe/Makefile
new file mode 100644
index 0000000..2d32167
--- /dev/null
+++ b/c/pipe/Makefile
@@ -0,0 +1,8 @@
+include ../base.mk
+
+all: pipe
+pipe: pipe.c
+ $(CC) $(CFLAGS) -lpthread -o $@ $<
+
+clean:
+ rm -f pipe
diff --git a/c/pipe/pipe.c b/c/pipe/pipe.c
new file mode 100644
index 0000000..f8ed9c7
--- /dev/null
+++ b/c/pipe/pipe.c
@@ -0,0 +1,75 @@
+#include <sys/wait.h>
+
+#include <err.h>
+#include <errno.h>
+#include <pthread.h>
+#include <stdlib.h>
+#include <time.h>
+#include <unistd.h>
+
+#define MILLISECOND (1e6)
+
+enum pipe_ends {
+ R,
+ W,
+};
+
+static void *work(void *);
+
+int
+main(void)
+{
+ static const char msg[] = u8"Olá Mundo!\n";
+
+ int fds[2];
+ if (pipe(fds) == -1)
+ err(1, "pipe");
+ if (write(fds[W], msg, sizeof(msg) - 1) == -1)
+ err(1, "write[1]");
+
+ pthread_t thrd;
+ if ((errno = pthread_create(&thrd, NULL, work, (void *)fds)) != 0)
+ err(1, "pthread_create");
+
+ struct timespec ts = {.tv_nsec = 500 * MILLISECOND};
+ if (nanosleep(&ts, NULL) == -1)
+ err(1, "nanosleep");
+
+ if (write(fds[W], msg, sizeof(msg) - 1) == -1)
+ err(1, "write[2]");
+
+ close(fds[W]);
+
+ if ((errno = pthread_join(thrd, NULL)) != 0)
+ err(1, "pthread_join");
+
+ return EXIT_SUCCESS;
+}
+
+void *
+work(void *_fds)
+{
+ int *fds = _fds;
+
+ struct timespec ts = {.tv_nsec = 250 * MILLISECOND};
+ if (nanosleep(&ts, NULL) == -1)
+ err(1, "nanosleep");
+
+ pid_t pid = fork();
+ if (pid == -1)
+ err(1, "fork");
+ if (pid == 0) {
+ close(STDIN_FILENO);
+ if (dup2(fds[R], STDIN_FILENO) == -1)
+ err(1, "dup2");
+ close(fds[R]);
+ close(fds[W]);
+ execlp("cat", "cat", NULL);
+ err(1, "exec");
+ }
+
+ close(fds[R]);
+ if (wait(NULL) == -1)
+ err(1, "wait");
+ return NULL;
+}