I am new to linux programming. I am trying to spawn two child processes and connect them through pipe. The generating child process should generate random numbers and the other child process should run a binary which takes those two numbers and finds their greatest common divider. The binary already works well with stdin so I am trying to redirect it to read end of a pipe. Similarly I do that with generating process with stdout connected to write end of a pipe.
But I think I didn't do good job wiring it together, because there is no output. Any help would be much appreciated!
I didn't find many materials on this online so suggesting those would also help a lot. Thanks.
#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <sys/wait.h>
#define exec_path "nsd"
void create_pipe(int *proc_pipe);
int create_proc();
void sig_handler(int sig);
int main() {
int proc_pipe[2];
pid_t gen_proc;
pid_t nsd_proc;
int proc_stat;
create_pipe(proc_pipe);
gen_proc = create_proc();
if (gen_proc == 0) {
// child exec
struct sigaction act;
act.sa_handler = &sig_handler;
close(proc_pipe[0]);
dup2(proc_pipe[1], 1);
close(proc_pipe[1]);
while (1) {
printf("%d %d\n", rand() % 4096, rand() % 4096);
sleep(1);
if (sigaction(SIGTERM, &act, NULL) == -1) exit(2);
}
} else {
nsd_proc = create_proc();
if (nsd_proc == 0) {
// child exec
close(proc_pipe[1]);
dup2(proc_pipe[0], 0);
close(proc_pipe[0]);
execl(exec_path, "nsd", (char *) NULL);
} else {
close(proc_pipe[0]);
close(proc_pipe[1]);
sleep(5);
kill(gen_proc, SIGTERM);
wait(&proc_stat);
if (proc_stat != 0) {
perror("ERROR");
return 1;
} else {
printf("OK\n");
return 0;
}
}
}
}
void sig_handler(int sig) {
if (sig == SIGTERM) {
perror("GEN TERMINATED");
exit(0);
}
}
pid_t create_proc() {
pid_t pid = fork();
if (pid == -1) {
perror("error forking new process");
exit(2);
}
return pid;
}
void create_pipe(int *proc_pipe) {
if (pipe(proc_pipe) == -1) {
perror("failed to create pipe");
exit(2);
}
}
printf
doesn't call write until it fills a buffer. You aren't giving your child enough time to fill that buffer. Add fflush(stdout)
before the child goes to sleep so some data is actually written into the pipe.