我创建了一个C-shell,可以执行用户输入的命令。此Shell的要求之一是在处理管道调用时,第一个子管道将其输出通过pipe1定向到父管道,然后父管道读取输出并将其通过pipe2写入第二个子管道。我面临的问题是,输入带有管道的参数时,程序在第一个子进程中挂起,并且不执行该参数。
下面给出的代码段是负责执行管道命令的功能(我已经标记了它的挂起点):
void execPipeArgs(char** befPipe, char** aftPipe, int n_reads){
pid_t child_1, child_2;
int pipe1[2]; // Fd for pipe1
int pipe2[2]; // Fd for pipe2
// Create pipe1
if(pipe(pipe1) < 0){
printf("%s\n", "Failure! Pipe1 not created" );
exit(0);
}
// Create pipe2
if(pipe(pipe2) < 0){
printf("%s\n", "Failure! Pipe2 not created" );
exit(0);
}
// Create first Child
child_1 = fork();
// Check if fork successfull
if(child_1 < 0){
printf("%s\n", "ERROR! CHILD 1 NOT CREATED" );
exit(0);
}
// In first child
if(child_1 == 0){
***"THIS IS WHERE IT HANGS"***
dup2(pipe1[1],1);
close(pipe1[0]);
close(pipe2[0]);
close(pipe2[1]);
if(execvp(befPipe[0],befPipe) < 0){
printf("%s\n", "Command not executed in child_1" );
exit(0);
}
}
// In PARENT
else {
// Wait for child_1
wait(NULL);
int readCalls = 0;
int charCount = 0;
int bytesRead = 0;
char* byteBuffer[500];
close(pipe1[1]);
//Get number of bytes, read/write calls
while((bytesRead = read(pipe1[0],byteBuffer,n_reads)) != NULL){
readCalls++;
charCount = charCount + bytesRead;
//write to pipe2
write(pipe2[1],byteBuffer,bytesRead);
}
// Second Child
child_2 = fork();
// In child_2
if(child_2 == 0){
dup2(pipe2[0],0);
close(pipe2[1]);
close(pipe1[1]);
close(pipe1[0]);
if(execvp(aftPipe[0],aftPipe) < 0){
printf("%s\n", "Command not executed in child_2" );
exit(0);
}
} // if child_2 end
else{
// In Parent
wait(NULL);
}
}
} // end of execArgsPipe
我在stackoverflow上发现了类似的问题,但是没有一种解决方案可以帮助我解决问题。最常见的答案是在我尝试过的适当位置关闭管道,但我的程序仍然挂起。
任何帮助将不胜感激。
答案 0 :(得分:0)
您如何知道child_1挂起?是因为您尝试添加打印但在stdout上没有看到任何内容吗?根据dup2手册页,'dup2()使newfd成为oldfd的副本,并在必要时首先关闭newfd'。因此,child_1中的stdout现在是pipe1 [1]的副本。因此child_1内部的任何打印语句都不会显示在屏幕上。
您也可以查看以下链接: Pipe implementation stuck at dup2 command