如何解决尝试使用循环制作可扩展的管道和 execvp 程序
该程序尝试执行大于 1 的任意数量的命令,并使用管道、execvp 和 fork 将它们链接在一起,就像 shell 一样。在这段代码中,我有一个硬编码的“ls”、“wc”和“less”,它们应该像在 shell 上运行“ls | wc | less”一样。出于某种原因,管道没有按预期工作。我有一大段评论解释了我认为第 99 行的问题(从 "The read end of the..." 开始)。我知道没有错误检查,任何帮助表示赞赏。
#include <iostream>
#include <string.h>
#include <string>
#include <vector>
#include <sys/types.h>
#include <unistd.h>
using namespace std;
#define READ 0
#define WRITE 1
//This program will do three different commands ls,wc,then less.
int main(){
pid_t pid;
int cmd=3;
//One less pipe than command is required.
int fd[cmd-1][2];
//The pipes are created in a for loop.
for(int i=0; i<(cmd-1); i++){
if(pipe(fd[i])==-1){
cout<<"Help"<<endl;
}
}
//The commands are put in c.
char* c[3];
c[0]="ls";
c[1]="wc";
c[2]="less";
//First fork
pid=fork();
if(pid==0){
//Pipe 0 is linked up.
close(fd[0][READ]);
dup2(fd[0][WRITE],1);
close(fd[0][WRITE]);
//Remaining pipes are closed.
for(int i=1; i<(cmd-1); i++){
close(fd[i][READ]);
close(fd[i][WRITE]);
}
//The command is prepared and then execvp is executed.
char* temp[2];
temp[0]=c[0];
temp[1]=NULL;
char* x=temp[0];
execvp(x,temp);
}
//This for loop executes two times less than the number of commands.
for(int i=0; i<(cmd-2); i++){
pid=fork();
if(pid==0){
//I link up the read connection with pipe 0,I am fairly certain that
//this part is working. You can put a cout after this pipe and it will
//print that of command 1.
close(fd[i][WRITE]);
dup2(fd[i][READ],0);
close(fd[i][READ]);
//This is the linking of pipe 1.
close(fd[i+1][READ]);
dup2(fd[i+1][WRITE],1);
close(fd[i+1][WRITE]);
//This closes the remaining pipes,in this case there are none.
for(int j=0; j<(cmd-1); j++){
if(j==i || j==(i+1)){
continue;
}
close(fd[j][READ]);
close(fd[j][WRITE]);
}
//The command is prepared and executed
char* temp[2];
temp[0]=c[i+1];
temp[1]=NULL;
char* x=temp[0];
execvp(x,temp);
}
}
pid=fork();
if(pid==0){
//The read end of the final pipe is linked here.
//THIS IS WERE THE PROBLEM IS! For some reason after dup2,I can no longer
//use cin. Inbetween the linking of pipe 0 and pipe 1 (line 66),I can
//use cin to make sure that the first execvp works and put its output in the
//pipe. I also know that the second execvp works as intended. I just need to
//know why dup2 messes up my program here.
close(fd[cmd-2][WRITE]);
dup2(fd[cmd-2][READ],0);
close(fd[cmd-2][READ]);
//closes the remaining pipes.
for(int i=0; i<(cmd-2); i++){
close(fd[i][READ]);
close(fd[i][WRITE]);
}
//Preps next command.
char* temp[2];
temp[0]=c[cmd];
temp[1]=NULL;
char* x=temp[0];
execvp(x,temp);
//}
//closes all pipes.
for(int i=0; i<(cmd-1); i++){
close(fd[i][READ]);
close(fd[i][WRITE]);
}
return 0;
}
解决方法
您的代码有多个问题 例如您没有为命令分配内存,并且您的代码似乎没有正确括在括号内
我已将您的代码修改如下:
#include <iostream>
#include <string.h>
#include <string>
#include <vector>
#include <sys/types.h>
#include <unistd.h>
using namespace std;
//This program will do three different commands ls,wc,then less.
int main(){
pid_t pid = 0;
int cmd=3,i;
//One less pipe than command is required.
int fd[cmd-1][2];
//The pipes are created in a for loop.
for(int i=0; i<(cmd-1); i++){
if(pipe(fd[i])==-1){
cout<<"Help"<<endl;
}
}
//The commands are put in c.
char c[3][8] = {{'l','s','\0'},{'w','c',{'l','e','\0'}},*temp[2];
for(i = 0; i < cmd-1; i ++){
pid = fork();
if(pid == 0){
if(i != 0){
// read from previous fd
close(fd[i-1][1]);
dup2(fd[i-1][0],STDIN_FILENO);
close(fd[i-1][0]);
}
// write to current fd
close(fd[i][0]);
dup2(fd[i][1],STDOUT_FILENO);
close(fd[i][1]);
temp[0] = c[i];
temp[1] = NULL;
execvp(c[i],temp);
exit(0);
}
else{
if(i != 0){
// close unnecessary fds in parent
close(fd[i-1][0]);
close(fd[i-1][1]);
}
}
}
// the last command i.e. less here
if(i > 0){
close(fd[i-1][1]);
dup2(fd[i-1][0],STDIN_FILENO);
close(fd[i-1][0]);
}
temp[0] = c[i];
temp[1] = NULL;
execvp(c[i],temp);
return 0;
}
告诉我它是否适合您!
版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 dio@foxmail.com 举报,一经查实,本站将立刻删除。