0
我正在編寫一個基本的shell課程作業,它將在給定的路徑列表中找到一個命令,並執行該命令。它也意味着處理管道。 但是,當我fork一個子進程時,在gdb中出現「Write error:Broken Pipe」消息,並且程序突然終止。使用管道分岔過程中的程序崩潰
我似乎無法理解爲什麼會發生這種情況,因爲我一直對打開和關閉正確的管道和流程分叉持謹慎態度,似乎按需要工作。能有更多C和unix編程經驗的人能幫我診斷問題嗎?我的fork實現/管道實現有沒有邏輯上不正確的東西?
//commands is of the format {"ls -al", "more", NULL}
//it represents commands connected by pipes, ex. ls -al | more
char **commands = parseArgv(consoleinput, SPECIAL_CHARS[4]);
int numcommands = 0;
while(commands[numcommands]!=NULL)
{
numcommands++;
}
const int numpipes = 2*(numcommands-1);
int pipefds[numpipes];
int i=0;
for(i=0; i<numpipes;i=i+2)
{
pipe(pipefds+i);
}
int pipe_w = 1;
int pipe_r = pipe_w - 3;
int curcommand = 0;
while(curcommand < numcommands)
{
if(pipe_w < numpipes)
{
//open write end
dup2(pipefds[pipe_w], 1);
}
if(pipe_r > 0)
{
//open read end
dup2(pipefds[pipe_r], 0);
}
for(i=0;i<numpipes;i++) //close off all pipes
{
close(pipefds[i]);
}
//Parse current command and Arguments into format needed by execv
char **argv = parseArgv(commands[curcommand], SPECIAL_CHARS[0]);
//findpath() replaces argv[0], i.e. command name by its full path ex. ls by /bin/ls
if(findPath(argv) == 0)
{
int child_pid = fork();
//Program crashes after this point
//Reason: /bin/ls: write error, broken pipe
if(child_pid < 0)
{
perror("fork error:");
}
else if(child_pid == 0) //fork success
{
if(execv(argv[0], argv) == -1)
{
perror("Bad command or filename:");
}
}
else
{
int child_status;
child_pid = waitpid(child_pid, &child_status, 0);
if(child_pid < 0)
{
perror("waitpid error:");
}
}
}
else
{
printf("Bad command or filename");
}
free(argv);
curcommand++;
pipe_w = pipe_w + 2;
pipe_r = pipe_r + 2;
}
//int i=0;
for(i=0;i<numpipes;i++) //close off all pipes
{
close(pipefds[i]);
}
free(commands);
你能構建一個[最小測試用例](http://sscce.org)嗎? – 2013-02-10 17:14:18
'pipe_w - 3'?真? – 2013-02-10 17:15:43
在關閉正常標準輸入/輸出描述符之前複製管道描述符,請檢查errors_。你也應該在孩子身上覆制它們。 – 2013-02-10 17:17:16