0

I'm doing my own version of tcsh (for an homework) and I've a problem when it comes pipes & redirections (pipe for now).

As I said, I try to redirect the output of a program to the input of an another one. I almost made it correctly until I got the problem below: The second program executed hang on and waiting for an user's input which should not happens. There is my code with debug left. There is where the child is created:

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);
}

Creating new fds and link the current node/cmd with the next one.

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, where all commands are executed:

static int affect_all_cmds(shell_t *shell)
{
    parsing_t *current = shell->cmds;
    int returned_val = ERR_NONE;

    while (current != NULL) {
        execute_alias(shell, &current->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);
}

I'm probably sure that I haven't closed correctly something but I don't find it. I tried numerous things since a week but nothing works. Also, for my tests I do things like: ls | grep c and the results I have for now are:

$ 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

And it hang on after that until I press CTRL+C.

Charles Duffy
  • 280,126
  • 43
  • 390
  • 441
Dayrion
  • 1
  • 2
  • 1
    In line with Emma's guidance, I've edited the self-answer out of the question (see also [Is it OK for users to edit the accepted answer into their question?](https://meta.stackoverflow.com/questions/262806/is-it-ok-for-users-to-edit-the-accepted-answer-into-their-question) and [Add description of used solution - how?](https://meta.stackoverflow.com/questions/298405/add-description-of-used-solution-how)) but you're welcome to use the "Add an Answer" button to add one yourself. – Charles Duffy Mar 31 '19 at 20:31
  • 1
    (That said, this is a very common question, and a very common mistake, so it could probably also be closed-as-duplicate). – Charles Duffy Mar 31 '19 at 20:35

0 Answers0