diff options
-rw-r--r-- | c/pipe/.gitignore | 1 | ||||
-rw-r--r-- | c/pipe/Makefile | 8 | ||||
-rw-r--r-- | c/pipe/pipe.c | 75 |
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; +} |