我想创建一个子进程,将其标准输入和输出重定向到父进程,并与子进程进行交互。也就是说,父进程应该能够从子进程接收输入,处理它,并向子进程提供输出,这个循环不断重复(就像用户与shell进行交互一样,这实际上是最终目标:模拟用户交互)。
到目前为止,我已经成功地创建并重定向了管道(下面的代码只是从子进程通过用户在父进程中输入的方式回显输入)。问题是,我只能这样做一次,子进程在第一次I/O周期后终止,并且我会得到一个SIGPIPE信号。如何保持子进程处于活动状态,并使其在父进程写入时读取管道?
附言:我知道可以使用except来模拟用户交互,但我需要访问返回的数据以进行自定义分析,并且出于学术目的,我想这样做。
到目前为止,我已经成功地创建并重定向了管道(下面的代码只是从子进程通过用户在父进程中输入的方式回显输入)。问题是,我只能这样做一次,子进程在第一次I/O周期后终止,并且我会得到一个SIGPIPE信号。如何保持子进程处于活动状态,并使其在父进程写入时读取管道?
附言:我知道可以使用except来模拟用户交互,但我需要访问返回的数据以进行自定义分析,并且出于学术目的,我想这样做。
#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);}
}
}
}