我的实现使用递归用多个管道执行命令,因此从理论上讲,我只需要2个管道即可。但是,在第二次迭代后,读取()阻止了我的程序停止。我只能执行" ls -la | cat -a"的" ls -la | cat -a | cat -a | cat -a"的一部分,但我的程序会陷入read()而永远不会退出。如果我评论引起此问题的读取,则该程序到达结束并退出,但是当然,我没有输出。有人知道为什么会发生这种情况吗?我也尝试了迭代实现,但是我遇到了相同的错误。
char* buf[1000];
int recursion_fd[2];
int output_size;
auto pipe_recursion_fd = pipe(recursion_fd);
void execute_pipe(vector<vector<string>> commands)
{
//PUT THE COMMAND INTO ARRAY TO CALL WITH EXEC
char* args[] = {0,0,0,0,0,0,0,0,0,0};
for(int i=0; i < commands.at(0).size();++i)
{
int size = commands.at(0).at(i).size() + 1;
args[i] = new char[size];
strcpy(args[i],commands.at(0).at(i).c_str());
}
//CREAT PIPE AND FORK
int fd[2];
pipe(fd);
int pid = fork();
//CHILD
if(pid == 0)
{
dup2(recursion_fd[0],STDIN_FILENO);
dup2(fd[1],STDOUT_FILENO);
//dup(recursion_fd[0]);
//dup(fd[1]);
int exec_status = execvp(args[0],args);
cout << "exec failed - not a valid command" << endl;
exit(0);
}
//PARENT
if(pid != 0)
{
waitpid(pid,NULL,WNOHANG);
//close(fd[1]);
//THIS IS THE RECURSION CONDITION, THE LAST ITERATTION SHOULD PRINT 0
cout << " num pipes " << num_pipes(commands) << endl;
if(num_pipes(commands) > 0)
{
//THIS CAUSES HOLD
output_size = read(fd[0],buf,sizeof(buf));
printf("inside buf:: %s n",buf); //PRINT TO TEST ITERATIONS
write(recursion_fd[1],buf,output_size);
commands.erase(commands.begin()); //erase completed command
commands.erase(commands.begin()); //erase pipe
execute_pipe(commands);
}
else
{
//THIS CAUSES HOLD
output_size = read(fd[0],buf,sizeof(buf));
return;
}
}
}
void test_execute_pipe()
{
string command;
cout << ":: ";
getline(cin,command);
vector<vector<string>> test = seperate_command(command);
cout << "test size = " << test.size() << endl;
for(int i=0; i < test.size(); ++i)
{
for(int c=0; c < test.at(i).size(); ++c)
{
cout << test.at(i).at(c) << "~";
}
cout <<endl;
}
memset(buf,0,sizeof(buf));
execute_pipe(test);
//cout << "right before buf print" << endl;
printf("buf:: n");
write(STDOUT_FILENO,buf,output_size);
}
int main(int argc, char** argv)
{
test_execute_pipe();
}
您似乎假设您可以将任意数量的数据写入管道的一端,然后从另一端将所有数据写入。但是你不能。有一些缓冲区可用,但不多。如果您在阅读之前写得更多,则write
将阻止。
另外,此:
dup2(recursion_fd[0],STDIN_FILENO);
似乎假设recursion_fd
已设置为某物,但我看不到哪里。