commit 3bf497ca1d55d7fea7cb032de44561cf0fac14f9
parent 65edaf3b3b0ea2d26bed884549b29b9e6b01a768
Author: Martin Kloeckner <mjkloeckner@gmail.com>
Date: Fri, 21 Aug 2026 21:56:51 -0300
Add `process_pingpong`
Diffstat:
1 file changed, 146 insertions(+), 0 deletions(-)
diff --git a/ejs/process_pingpong.c b/ejs/process_pingpong.c
@@ -0,0 +1,146 @@
+/*
+ * Process Ping Pong
+ * Martin Klöckner - mklockner@fi.uba.ar
+ *
+ * Based on examples given in wait(2) man page
+ */
+
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+#include <sys/wait.h>
+#include <stdint.h>
+#include <time.h>
+#include <unistd.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"\n", ##__VA_ARGS__); \
+ } while (0)
+#define LOG_ID(fmt, ...) do { \
+ printf("[LOG][%ld] "fmt"\n", proc_count, ##__VA_ARGS__); \
+ } while (0)
+#else
+#define LOG(fmt, ...)
+#define PROC_LOG(fmt, ...)
+#endif
+
+void sleep_ms(long ms)
+{
+ struct timespec ts = {
+ .tv_sec = ms / 1000,
+ .tv_nsec = (ms % 1000) * 1000000L
+ };
+
+ nanosleep(&ts, NULL);
+}
+
+/*
+ * Parent ===pipefd_1===> Child
+ * Parent <==pipefd_2==== Child
+ */
+
+int main (void)
+{
+ int wstatus, cpid, proc_count;
+ int pipefd_1[2], pipefd_2[2];
+ uint32_t ball;
+
+ proc_count = 0;
+ ball = 0;
+
+ if ((pipe(pipefd_1) == -1) || (pipe(pipefd_2) == -1))
+ {
+ perror("pipe");
+ exit(EXIT_FAILURE);
+ }
+
+ cpid = fork();
+
+ if (cpid == -1)
+ {
+ perror("fork");
+ exit(EXIT_FAILURE);
+ }
+
+ if (cpid == 0)
+ {
+ // Child
+ proc_count++;
+ LOG_ID("PID is %jd", (intmax_t) getpid());
+ sleep_ms(1000);
+
+ if (close(pipefd_1[PIPE_WRITE_END]) == -1)
+ {
+ // Close unused pipefd_1 write end
+ perror("close");
+ exit(EXIT_FAILURE);
+ }
+
+ if (close(pipefd_2[PIPE_READ_END]) == -1)
+ {
+ // Close unused pipefd_2 read end
+ perror("close");
+ exit(EXIT_FAILURE);
+ }
+
+ while (true)
+ {
+ // Wait for response from the other end
+ while (read(pipefd_1[PIPE_READ_END], &ball, 1) <= 0)
+ {
+ ;
+ }
+ sleep_ms(1000);
+
+ ball++;
+ LOG_ID("%d", ball);
+ write(pipefd_2[PIPE_WRITE_END], &ball, 1);
+ }
+
+ exit(EXIT_SUCCESS);
+ }
+ else
+ {
+ // Parent
+ LOG_ID("PID is %jd", (intmax_t) getpid());
+ sleep_ms(1000);
+
+ if (close(pipefd_1[PIPE_READ_END]) == -1)
+ {
+ // Close unused pipefd_1 read end
+ perror("close");
+ exit(EXIT_FAILURE);
+ }
+
+ if (close(pipefd_2[PIPE_WRITE_END]) == -1)
+ {
+ // Close unused pipefd_2 write end
+ perror("close");
+ exit(EXIT_FAILURE);
+ }
+
+ while (true)
+ {
+ ball++;
+ LOG_ID("%d", ball);
+ write(pipefd_1[PIPE_WRITE_END], &ball, 1);
+
+ // Wait for response from the other end
+ while (read(pipefd_2[PIPE_READ_END], &ball, 1) <= 0)
+ {
+ ;
+ }
+
+ sleep_ms(1000);
+ }
+
+ exit(EXIT_SUCCESS);
+ }
+
+ exit(EXIT_SUCCESS);
+}