I'm trying to understand what's going on during the execution of this code:
I've this function to fork a process that execute a command
void ft_fork(t_shell *shell, t_cmd *tmp_cmd)
{
pid_t cmd;
int status;
status = 0;
cmd = fork();
if (cmd < 0)
ft_clean(shell, 1);
if (cmd == 0)
{
ft_execute_cmd(shell, tmp_cmd);
close(STDIN_FILENO);
close(STDOUT_FILENO);
exit (EXIT_SUCCESS);
}
waitpid(cmd, &status, 0);
if (!WTERMSIG(status))
g_status = status >> 8;
}
and the ft_execute_cmd
void ft_execute_cmd(t_shell *shell, t_cmd *tmp_cmd)
{
char *binpath;
binpath = ft_search_cmd(shell, tmp_cmd);
if (binpath)
{
if (execve(binpath, tmp_cmd->sim_cmd, shell->env) < 0)
{
ft_print_error(5);
exit(127);
}
}
}
when I try to execute cat ./small_size_file | grep oi the program do what I expect, but when I try to execute cat .big_size_file | grep oi the parent stop and keep waiting for the child. this is the structure of the file descriptors before the fork
ls -l /proc/17912/fd
total 0
lrwx------ 1 joao joao 64 dez 4 18:30 0 -> /dev/pts/4
l-wx------ 1 joao joao 64 dez 4 18:34 1 -> 'pipe:[47741]'
lrwx------ 1 joao joao 64 dez 4 18:34 2 -> /dev/pts/4
lrwx------ 1 joao joao 64 dez 4 18:34 3 -> /dev/pts/4
lrwx------ 1 joao joao 64 dez 4 18:34 4 -> /dev/pts/4
lr-x------ 1 joao joao 64 dez 4 18:34 5 -> 'pipe:[47741]'
can anyone explain what I'm doing wrong?
I've tried with small files and the program executes the cat as I expected but freezes with big ones.
Transferring a comment into an answer.
You're waiting before you've executed all the processes in the pipeline — which is incorrect. The processes in a pipeline must all execute concurrently to avoid any of the processes being blocked.
The ft_fork()
function should not contain wait()
or waitpid()
. If the file is bigger than the maximum pipe size (usually 64 KiB these days; once upon an æon ago, it was usually 5 KiB), the cat
command is blocked waiting for something to read from the pipe, but nothing will read from the pipe until the cat
command completes — deadlock. With a small file, the pipe can hold the data.
You will need to re-engineer the code — most likely by having ft_fork()
return the PID of the child process so that you can wait for it after launching all the processes in the pipeline.
I note that since you've not provided an MCVE (Minimal, Complete, Verifiable Example — or MRE or whatever name SO now uses) or an SSCCE (Short, Self-Contained, Correct Example — the same idea by a different name), we cannot easily show working code for you.