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 containwait()
orwaitpid()
. 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), thecat
command is blocked waiting for something to read from the pipe, but nothing will read from the pipe until thecat
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.