尝试使用循环创建一个可伸缩的管道和execvp程序



这个程序正在尝试执行任意数量的大于1的命令,并使用管道、execvp和fork将它们链接在一起,就像shell一样。在这个代码中,我有一个硬编码的"ls"wc"one_answers";less"这应该会像运行';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', ''}, {'w', 'c', ''}, {'l','e','s','s', ''}}, *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;
}

让我知道它是否适合你!

最新更新