我在C中编写一个处理重定向操作符和管道的shell。以下想法是否适合处理管道?所以我按以下方式创建了一个管道:
int pipefd[2];
if (pipe(pipefd) == -1) {
perror("pipe");
myshell_exit(-1);
}
然后我分叉一个新进程并在新进程中将stdout重定向到管道的一端,如下所示:
dup2(STDOUT_FILENO,pipefd[1]);
所以父进程现在可以从管道中读取并将stdin重定向到用于读取的管道的末尾。像这样。
dup2(STDIN_FILENO,pipefd[0]);
然后我分叉一个新进程,所以执行下一个命令或程序时输入pipefd[0]
示例:cat file.txt | grep string
总之,我在父进程中分叉了两个进程。一个用于执行当前程序,另一个用于下一个程序。这项任务是归纳的。
这个想法是对的吗?
这是主要功能的代码。假设所有奇怪的功能都有效。
int myshell_execute(struct processNode* list)
{
int i;
char* program = list->program; // Get the program to be executed
char ** program_args = list->program_arguments; // get the programs and arguments to be executed
char ** redirection_string = list->redirection; //get the part of the command that contains redirection
int *status;
int* stdout;
int stdout_num = 1;
stdout = &stdout_num;
int fileDescriptor;
pid_t pid;
struct processNode* next_node = (*list).next; // next node to be handled
if(strcmp(program,"cd") == 0)
{
return myshell_cd(program_args);
}
else if (strcmp(program,"exit") == 0)
{
return myshell_exit(0);
}
int pipefd[2];
if (pipe(pipefd) == -1) {
perror("pipe");
myshell_exit(-1);
}
// Execute the current program
pid = fork();
if(pid == 0)
{
if(sizeOfLine(redirection_string) != 0)
{
redirectionHandler(redirection_string,stdout); // This works. This just handles redirection properly
}
if(*stdout == 1 && list->next !=NULL)
{
dup2(STDOUT_FILENO,pipefd[1]); // with this line of code, I intend to redirect the stdout to the file descriptor pipefd[1], so the next command can use it if there are pipes. The reason why I put it in an if is because 1) stdout may be handled by the function redirectionHandler, so we don't touch it or we are in the last node
}
if(execvp(program,program_args) !=-1)
{
perror("myshell:");
}
myshell_exit(-1);
}
else if (pid <0)
{
perror("myshell: ");
myshell_exit(-1);
}
else
{
wait(status);
}
// Go to the next command to be executed
if(list->next != NULL) // I parse the command line in a convenient mannner. Thar works too
{
dup2(STDIN_FILENO,pipefd[0]);
pid = fork();
if(pid == 0)
{
return myshell_execute(next_node);
}
else if (pid <0)
{
perror("myshell: ");
myshell_exit(-1);
}
else
{
wait(status);
}
}
else
{
myshell_exit(0);
}
}
所有不包含管道的命令都可以正确处理,但问题是当有管道要处理时。