commit 65edaf3b3b0ea2d26bed884549b29b9e6b01a768
Author: Martin Kloeckner <mjkloeckner@gmail.com>
Date: Fri, 21 Aug 2026 21:31:19 -0300
Add `ejs/process_unidir_pipe.c`
Diffstat:
1 file changed, 124 insertions(+), 0 deletions(-)
diff --git a/ejs/process_unidir_pipe.c b/ejs/process_unidir_pipe.c
@@ -0,0 +1,124 @@
+/*
+ * Process Ping Pong
+ * Martin Klöckner - mklockner@fi.uba.ar
+ *
+ * Based on example given in wait(2) man page
+ */
+
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+#include <unistd.h>
+#include <sys/wait.h>
+#include <stdint.h>
+
+#define LOG_ENABLE true
+#define PIPE_READ_END 0
+#define PIPE_WRITE_END 1
+
+#if true == LOG_ENABLE
+#define LOG(fmt, ...) do { \
+ printf("[LOG] "fmt, ##__VA_ARGS__); \
+ } while (0)
+#define LOG_ID(fmt, ...) do { \
+ printf("[LOG][%ld] "fmt, proc_count, ##__VA_ARGS__); \
+ } while (0)
+#else
+#define LOG(fmt, ...)
+#define PROC_LOG(fmt, ...)
+#endif
+
+int main (void)
+{
+ int wstatus, cpid, proc_count;
+ int pipefd[2];
+ char buf;
+
+ proc_count = 0;
+
+ if (pipe(pipefd) == -1)
+ {
+ perror("pipe");
+ exit(EXIT_FAILURE);
+ }
+
+ cpid = fork();
+
+ if (cpid == -1)
+ {
+ perror("fork");
+ exit(EXIT_FAILURE);
+ }
+ else if (cpid == 0)
+ {
+ // Child
+
+ proc_count++;
+ LOG_ID("PID is %jd\n", (intmax_t) getpid());
+
+ if (close(pipefd[1]) == -1) {
+ // Close unused write end
+ perror("close");
+ exit(EXIT_FAILURE);
+ }
+
+ while (read(pipefd[0], &buf, 1) > 0) {
+ if (write(STDOUT_FILENO, &buf, 1) != 1)
+ {
+ perror("write");
+ exit(EXIT_FAILURE);
+ }
+
+ if(buf == '\n')
+ {
+ break;
+ }
+ }
+
+ exit(EXIT_SUCCESS);
+ }
+ else
+ {
+ // Parent
+
+ if (close(pipefd[0]) == -1) {
+ // Close unused read end
+ perror("close");
+ exit(EXIT_FAILURE);
+ }
+
+ LOG_ID("PID is %jd\n", (intmax_t) getpid());
+ const char *str = "Hello, World!\n\0";
+ write(pipefd[PIPE_WRITE_END], str, strlen(str));
+
+ do
+ {
+ if(waitpid(cpid, &wstatus, WUNTRACED | WCONTINUED) == -1)
+ {
+ perror("waitpid");
+ exit(EXIT_FAILURE);
+ }
+
+ if (WIFEXITED(wstatus))
+ {
+ LOG_ID("Child exited with status %d\n", WEXITSTATUS(wstatus));
+ }
+ else if (WIFSIGNALED(wstatus))
+ {
+ LOG_ID("Child killed by signal %d\n", WTERMSIG(wstatus));
+ }
+ else if (WIFSTOPPED(wstatus))
+ {
+ LOG_ID("Child stopped by signal %d\n", WSTOPSIG(wstatus));
+ }
+ else if (WIFCONTINUED(wstatus))
+ {
+ LOG_ID("Child continued\n");
+ }
+
+ } while (!WIFEXITED(wstatus) && !WIFSIGNALED(wstatus));
+ exit(EXIT_SUCCESS);
+ }
+
+ exit(EXIT_SUCCESS);
+}