【发布时间】:2014-10-10 22:34:11
【问题描述】:
我正在为家庭作业编写自己的 shell,但遇到了问题。
我的 shell 程序从控制台获取输入 cat scores | grep 100并按预期打印输出,但 grep 命令没有终止,我可以看到它从 ps 命令无限运行。
编辑 - 关闭 fds 时出错。现在 grep 命令未执行,控制台输出为 -
grep:(标准输入):错误的文件描述符
我正在从控制台读取命令数量并创建必要的管道并将它们存储在二维int array fd[][] 中,然后再分叉第一个进程。
fd[0][0] 将包含第一个管道的读取端,fd[0][1] 将包含第一个管道的写入端。 fd[1][0] 将包含第二个管道的读取端,fd[1][1] 将包含第二个管道的写入端,依此类推。
每个新进程将其stdin 与其管道的读取端复制到前一个进程,并将其stdout 与其管道的写入端复制到下一个进程。
下面是我的功能:
void run_cmds(char **args, int count,int pos)
{
int pid,status;
pid = fork();
if ( pid == 0 )
{
if(pos != 0) dup2(fd[pos-1][0],0); // not changing stdin for 1st process
if(pos != count) dup2(fd[pos][1],1); //not changing stdout for last process
close_fds(pos);
execvp(*args,args);
}
else
{
waitpid(pid,&status,0);
count--;
pos++;
//getting next command and storing it in args
if(count > 0)
run_cmds(args,count,pos);
}
}
}
- args 将包含命令的参数。
- count 是我需要创建的命令数。
- pos 是命令在输入中的位置
我无法找出问题所在。在此之前,我对硬编码值使用了相同的方法并且它正在工作。
我对@987654333@/fork 的理解/实现缺少什么以及为什么命令无限等待?
任何输入都会有很大帮助。过去几天对此感到震惊!
编辑:close_fds() 函数如下 - 对于任何进程,我都会关闭链接该进程的两个管道。
void close_fds(int pos)
{
if ( pos != 0 )
{
close(fd[pos-1][0]);
close(fd[pos-1][1]);
}
if ( pos != count)
{
close(fd[pos][0]);
close(fd[pos][1]);
}
}
【问题讨论】:
-
请检查您调用的每个系统调用的返回值(例如
fork、waitpid、dup2、execvp)。如果他们返回错误代码,请使用perror或strerror(errno)打印错误。请更新问题,说明没有错误。请在execvp之后调用abort();以确保子进程不会继续运行。 -
请将您的整个程序 (sscce.org) 发布在一个 .c 文件中。