I am trying to create a child process, redirect its stdin and stdout to the parent process, and interact with the child process. That is, the parent process should be able to receive input from the child, process it, and provide output to the child, and the cycle repeats (like user interaction with a shell, which is the actually the end goal: to simulate user interaction).
Thus far I have been able to create and redirect pipes successfully (the code below simply echoes the input on the parent process, from user, through the child). The problem is that I can only do this once, the child terminates after first I/O cycle, and I get a SIGPIPE. How can I keep the child alive, and have it read from pipe when the parent writes to it?
P.S. I know except can be used to simulate user interaction, but I need access to the returned data to do custom analysis, and I'd like to go this way for academic purposes.
#include <iostream>
#include <string>
#include <sstream>
#include <unistd.h>
#include <stdio.h>
#include <sys/wait.h>
#include <limits.h>
#include <sys/types.h>
#include <cstdlib>
#define MAX_CMD_SIZE 256
#define MAX_BUFF_SIZE 512
#define NUM_PIPES 2
#define PARENT_READ_PIPE pipes[0]
#define PARENT_WRITE_PIPE pipes[1]
#define READ_END 0
#define WRITE_END 1
#define PARENT_READ_FD PARENT_READ_PIPE[READ_END]
#define PARENT_WRITE_FD PARENT_WRITE_PIPE[WRITE_END]
#define CHILD_READ_FD PARENT_WRITE_PIPE[READ_END]
#define CHILD_WRITE_FD PARENT_READ_PIPE[WRITE_END]
int pipes[NUM_PIPES][2];
int main()
{
pipe(PARENT_READ_PIPE);
pipe(PARENT_WRITE_PIPE);
pid_t process_id = fork();
if (process_id<0) //throw diag::DiagError("ERROR: error during fork()");
{std::cerr<<"ERROR: error during fork()"; exit(1);}
else if (process_id==0)
{//CHILD process
dup2(CHILD_READ_FD, STDIN_FILENO);
dup2(CHILD_WRITE_FD, STDOUT_FILENO);
close(CHILD_READ_FD);
close(CHILD_WRITE_FD);
close(PARENT_READ_FD);
close(PARENT_WRITE_FD);
char buffer[MAX_BUFF_SIZE];
int count = read(STDIN_FILENO, buffer, MAX_BUFF_SIZE-1);
if (count >= 0)
{
buffer[count] = 0;
printf("%s", buffer);
}
else //{throw diag::DiagError("IO Error");}
{std::cerr<<"ERROR: error during fork()"; exit(1);}
exit(0);
}
else
{//PARENT process
close(CHILD_READ_FD);
close(CHILD_WRITE_FD);
char buffer[MAX_BUFF_SIZE];
std::string temp="";
while(std::getline(std::cin,temp))
{
write(PARENT_WRITE_FD, temp.c_str(), temp.size());
//wait(&status);
int count = read(PARENT_READ_FD, buffer, MAX_BUFF_SIZE-1);
if (count >= 0)
{
buffer[count] = 0;
printf("%s", buffer);
}
else //{throw diag::DiagError("IO Error");}
{std::cerr<<"ERROR: error during fork()"; exit(1);}
}
}
}