我刚刚完成了shell解释器,但我认为我的管道实现是错误的。
它正在工作,像ls | cat -e这样的基本东西可以工作,但是如果文件描述符超过60 ko,我担心segmentation fault可能会出现。我还发现了一个无限循环,当我做一个文件的猫,它的长度超过60 ko。例如,如果do是cat foo | cat -e,而foo是一个长文件,则会发生无限循环。
或者其他例子--当我执行cat /dev/urandom | cat -e时,它没有显示任何显示,所以它首先执行cat /dev/urandom,然后执行cat -e。
这是我的密码:
int son(int *fd_in, int p[2], t_list *cmd, char **env)
{
(void)env;
dup2(*fd_in, 0);
if (cmd->act != ENDACT && cmd->act != LEFT && cmd->act != DLEFT)
dup2(p[1], 1);
close(p[0]);
execve(cmd->av[0], cmd->av, NULL);
return (-1);
}
t_list *execute_pipe(t_list *cmd, int *fd_in)
{
int p[2];
pid_t pid;
*fd_in = 0;
while (cmd->act != -1)
{
pipe(p);
if ((pid = fork()) == -1)
return (NULL);
else if (pid == 0)
son(fd_in, p, cmd, NULL);
else
{
wait(NULL);
close(p[1]);
*fd_in = p[0];
if (cmd->act != PIPE)
return (cmd);
cmd = cmd->next;
}
}
return (cmd);
}发布于 2015-05-12 13:59:40
shell管道的部分思想是所涉及的进程同时运行(或可能运行)。在启动下一个子进程之前,您提供的代码可以通过wait()对每个子进程积极地防止这种情况发生。除其他外,这可能会在任何事情准备就绪之前填充(OS-级)管道的缓冲区。这将导致死锁,或者,如果幸运的话,会生成一个错误。
在较高级别上,程序应如下所示:
C作为管道第一个段的命令,并将fd0设置为STDIN_FILENOpipe(),并将fd1设置为该管道的写入端;fd1设置为STDOUT_FILENO
fork()运行命令C的子程序。在其中:fd0与STDIN_FILENO不同,则dup2() fd0到STDIN_FILENO并关闭fd0fd1与STDOUT_FILENO不同,则dup2() fd1到STDOUT_FILENO并关闭fd1C
STDIN_FILENO不同,则关闭fd0STDOUT_FILENO不同,则关闭fd1C设置为下一个命令fd0设置为上述步骤(2)中管道的读取端
wait()或waitpid()请注意,对于包含任意数量的命令(包括1 )的管道来说,这同样有效。
https://stackoverflow.com/questions/30190809
复制相似问题