Search code examples
cforkexecve

why program stop with big files


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.


Solution

  • 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.