c - 自己的 shell -> 在子节点上使用 pipe 和 dup2 后挂断
问题描述
我正在做我自己的 tcsh 版本(用于家庭作业),当涉及到管道和重定向(现在是管道)时我遇到了问题。
正如我所说,我尝试将一个程序的输出重定向到另一个程序的输入。在遇到以下问题之前,我几乎做到了:执行的第二个程序挂起并等待不应该发生的用户输入。我的代码还有调试。有创建孩子的地方:
static int generate_child(shell_t *shell, parsing_t *cmd, char *path, char **env)
{
pid_t child = 0;
printf("Child fds will be: %i & %i\n", cmd->fds[STDIN_FILENO], cmd->fds[STDOUT_FILENO]);
child = fork();
if (child == -1)
return (ERR_FORK);
if (child != 0)
wait_for_child(shell, cmd->args[0]);
else {
if (cmd->fds[STDIN_FILENO] > 0) {
dup2(cmd->fds[STDIN_FILENO], STDIN_FILENO);
printf("[#1] Closing fd: %i\n", cmd->fds[STDIN_FILENO]);
close(cmd->fds[STDIN_FILENO]);
}
if (cmd->fds[STDOUT_FILENO] != -1 && cmd->fds[STDIN_FILENO] != 1) {
dup2(cmd->fds[STDOUT_FILENO], STDOUT_FILENO);
printf("[#2] Closing fd: %i\n", cmd->fds[STDOUT_FILENO]);
close(cmd->fds[STDOUT_FILENO]);
}
execve(path, cmd->args, env);
display_perror(shell, cmd->args[0]);
_exit(ERR_CHILD);
}
return (ERR_NONE);
}
创建新的 fd 并将当前节点/cmd 与下一个链接。
int link_pipe(shell_t *shell, parsing_t *current)
{
int new_pipe[2];
if (pipe2(new_pipe, O_CLOEXEC))
return (ERR_PIPE);
current->piped[STDOUT_FILENO] = new_pipe[STDOUT_FILENO];
current->piped[STDIN_FILENO] = new_pipe[STDIN_FILENO];
printf("[Pipe] %s s' fds are: %i & %i\n", current->args[0], current->piped[STDIN_FILENO], current->piped[STDOUT_FILENO]);
if (current->fds[STDOUT_FILENO] == -1)
current->fds[STDOUT_FILENO] = current->piped[STDOUT_FILENO];
if (current->next != NULL)
current->next->fds[STDIN_FILENO] = current->piped[STDIN_FILENO];
return (ERR_NONE);
}
Aaand,执行所有命令:
static int affect_all_cmds(shell_t *shell)
{
parsing_t *current = shell->cmds;
int returned_val = ERR_NONE;
while (current != NULL) {
execute_alias(shell, ¤t->args);
returned_val = apply_linkers(shell, current); // link_pipe is used here
if (returned_val != ERR_NONE)
return (returned_val);
returned_val = redirect_cmds(shell, current); // generate_child is used here
if (returned_val != ERR_NONE)
return (returned_val);
current = current->next;
}
remove_all_queued_cmd(&shell->cmds); // Here are removed (from 'piped[...]') every fds open by 'pipe2'
return (returned_val);
}
我可能确定我没有正确关闭某些东西,但我没有找到它。一周以来我尝试了很多东西,但没有任何效果。此外,对于我的测试,我会执行以下操作:ls | grep c
我现在得到的结果是:
$ ls | grep c
ls -> 2 // Detecting a pipe
[Pipe] ls s fds are: 3 & 5 // Generating fds
Child fds will be: 0 & 5 // Running 'ls' with edited fds
grep -> 0 // No pipe or redirections detected
Child fds will be: 3 & -1 // Running 'grep'
[#1] Closing fd: 3
cmake-build-debug
include
main.c
src
之后它会一直挂,直到我按 CTRL+C。
解决方案
推荐阅读
- python - 打开pyxl。忽略具有样式但没有值的单元格
- django - Django - 将对象添加到模型查询集中而不先保存
- java - Eclipse Java 以相反的顺序编写希伯来语单词
- html - 切换文本时未交换表情符号
- linux - 内核如何知道有多少个内核
- snowflake-cloud-data-platform - 如何一次将 S3 存储桶上多个 CSV 文件中的几列插入雪花表(在单个查询中)
- plone - Plone 和 nginx 配置没有返回任何明显的结果
- android - 设置微调器弹出背景颜色
- python - 上传图片会损坏,但不会损坏 txt 文件
- tableau-api - 在具有固定 LOD(详细程度)的 Tableau 中计算 YTD MTD