我在实现管道和输出重定向时遇到问题。 单独使用效果很好,但是当我尝试时
'ls | wc > a',
它的功能与真正的 Bash 不同。它创建文件“a”,但它不会将 'ls | wc'
的输出重定向到该文件并创建无限循环它等待 pid,但我有循环等待最后的所有函数,我做了一个错误,但我不知道哪里?
我有一个用于创建管道及其执行的函数,以及用于重定向的函数,我找不到我的问题的解决方案 为什么我的| wc > file' 未从我的文件重定向
管道.c
void create_pipe(int pipe_fd[2], int i, int last)
{
if (i < (last - 1))
{
if (pipe(pipe_fd) == -1)
{
perror("pipe");
exit(EXIT_FAILURE);
}
}
}
void close_pipes_in_parent(int i, t_data *data, int *input_fd)
{
if (i != data->first)
close(*input_fd);
if (i < data->last)
{
close(data->pipe_fd[1]);
*input_fd = data->pipe_fd[0];
}
}
pid_t fork_process_pipe(int i, int input_fd, t_data *data, t_Token *curr, char **envp, t_Token *lst_tok)
{
pid_t pid = fork();
if (pid == 0)
{
printf("111111111111111111");
if (i != data->first)
{
dup2(input_fd, STDIN_FILENO);
close(input_fd);
}
if (i < data->last)
{
dup2(data->pipe_fd[1], STDOUT_FILENO);
close(data->pipe_fd[0]);
close(data->pipe_fd[1]);
}
data->path_exe = ft_get_reading(data, curr, envp);
if(!data->path_exe)
{
printf("Bash : command not found : %s\n", data->cmd[0]);
ft_free_tabtab(data->cmd);
free_token(lst_tok);
exit(EXIT_FAILURE);
}
if (execve(data->path_exe, data->cmd, envp) == -1)
{
ft_free_tabtab(data->cmd);
free(data->path_exe);
exit(EXIT_FAILURE);
}
free(curr->Token_str);
free(curr);
}
return (pid);
}
redir.c
int *creat_fd_out(t_data *data, t_Token *curr, int *output_fd)
{
int i;
i = 0;
while(i < data->nb_file)
{
output_fd[i] = open(curr->next->next->Token_str, O_CREAT | O_WRONLY | O_TRUNC, 0644);
if (output_fd[i] == -1)
exit(EXIT_FAILURE);
i++;
curr = curr->next->next ;
}
return(output_fd);
}
void close_fd_in(t_data *data, int *output_fd)
{
int i;
i = 0;
while(i < data->nb_file)
{
close(output_fd[i]);
i++;
}
}
pid_t fork_process_redi(t_data *data, t_Token *curr, char **envp, t_Token *lst_tok)
{
pid_t pid = fork();
int *output_fd = malloc(data->nb_file * sizeof(int));
if (pid == 0)
{
if ((curr->type == E_WORD && curr->next != NULL) && (curr->next->Token_str[0] == '>'))
{
data->path_exe = ft_get_reading(data, curr, envp);
if(!data->path_exe)
{
printf("Bash : command not found : %s\n", data->cmd[0]);
ft_free_tabtab(data->cmd);
free_token(lst_tok);
}
output_fd = creat_fd_out(data, curr, output_fd);
dup2(output_fd[data->nb_file -1], STDOUT_FILENO);
close_fd_in(data, output_fd);
}
if (execve(data->path_exe, data->cmd, envp) == -1)
{
ft_free_tabtab(data->cmd);
free(data->path_exe);
exit(EXIT_FAILURE);
}
free(curr->Token_str);
free(curr);
}
return (pid);
}
lanch_exe.c
void execute_pipeline_redirection(t_data *data, t_Token *list_token, char **envp)
{
int index_fork;
int input_fd;
t_Token *curr;
data->last = data->nb_cmd;
curr = list_token;
input_fd = STDIN_FILENO;
data->first = 0;
index_fork = 0;
pid_t pid[data->last];
while (curr != NULL)
{
if ((curr->type == E_WORD && curr->next != NULL) && (curr->next->Token_str[0] == '>') && (curr->next->next->type == E_FILE))
{
pid[index_fork] = -1;
pid[index_fork] = fork_process_redi(data, curr, envp, list_token);
index_fork++;
}
if (((curr->type == E_WORD || curr->next->type == E_FILE ) && curr->next != NULL && curr->next->Token_str[0] == '|') && (curr->type == E_WORD && curr->next == NULL))
{
pid[index_fork] = -1;
create_pipe(data->pipe_fd, index_fork, data->last);
pid[index_fork] = fork_process_pipe(index_fork, input_fd, data, curr, envp, list_token);
close_pipes_in_parent(index_fork, data, &input_fd);
index_fork++;
}
curr = curr->next;
}
wait_for_children(data->last, pid);
}
当我像
ls | wc > a
那样进行crestin测试时,我的PID似乎无限期地保持等待状态,而当我执行
母鸡ls | cat fichier.txt > a
,它工作正常
-> test.txt""><-
在 fork_process_redi 中,您正在设置输出文件描述符,而不是输入,就像您在 fork_process_pipe 中所做的那样。带有重定向的管道中的最后一个命令将从 STDIN 读取,直到 EoF 读取,而不是从最后一个命令的管道读取。 “cat file”不会从标准输入读取,并且运行正常。
不相关,但是execve之后的空闲语句永远不会被执行。当分叉进程退出时,内存会被释放,所以这不是问题。