Ajdin Hukic
Ajdin Hukic

Reputation: 23

What is problem in my C piping for custom shell?

I making custom shell in c and when i give arguments for pipe it doesn't work as it should.

// Function where the piped system commands is executed
void execArgsPiped(char** parsed, char** parsedpipe)
{
    // 0 is read end, 1 is write end
    int pipefd[2]; 
    pid_t p1, p2;
  
    if (pipe(pipefd) < 0) {
        red();
        printf("\nPipe could not be initialized");
        resetColor();
        return;
    }
    p1 = fork();
    if (p1 < 0) {
        red();
        printf("\nCould not fork");
        return;
    }
  
    if (p1 == 0) {
        // Child 1 executing..
        // It only needs to write at the write end
        close(pipefd[0]);
        dup2(pipefd[1], STDOUT_FILENO);
        close(pipefd[1]);
  
        if (execvp(parsed[0], parsed) < 0) {
            red();
            printf("\nCould not execute command 1..");
            resetColor();
            exit(0);
        }
    } else {
        // Parent executing
        p2 = fork();
  
        if (p2 < 0) {
            red();
            printf("\nCould not fork");
            resetColor();
            return;
        }
  
        // Child 2 executing..
        // It only needs to read at the read end
        if (p2 == 0) {
            close(pipefd[1]);
            dup2(pipefd[0], STDIN_FILENO);
            close(pipefd[0]);
            if (execvp(parsedpipe[0], parsedpipe) < 0) {
                red();
                printf("\nCould not execute command 2..");
                resetColor();
                exit(0);
            }
        } else {
            // parent executing, waiting for two children
            wait(NULL);
            wait(NULL);
        }
    }
}

For example calling /bin/cat filename | more, displays first two lines of file and shell breaks, or /bin/cat filename | cowsay nothing happens just breaks shell. HELP

Upvotes: 0

Views: 129

Answers (1)

Ajdin Hukic
Ajdin Hukic

Reputation: 23

For anyone wondering read and write end closed before piping can end so code should look like.

// Function where the piped system commands is executed
void execArgsPiped(char** parsed, char** parsedpipe)
{
    pid_t pid;
    int fd[2];

    pipe(fd);
    pid = fork();

    if(pid==0)
    {
        dup2(fd[WRITE_END], STDOUT_FILENO);
        close(fd[READ_END]);
        close(fd[WRITE_END]);
        if (execv(parsed[0], parsed) < 0) {
            printf("\nCould not execute command..");
        }
        exit(1);
    }
    else
    { 
        pid=fork();

        if(pid==0)
        {
            dup2(fd[READ_END], STDIN_FILENO);
            close(fd[WRITE_END]);
            close(fd[READ_END]);
            if (execv(parsedpipe[0], parsedpipe) < 0) {
                printf("\nCould not execute command..");
            }
            exit(1);
        }
        else
        {
            int status;
            close(fd[READ_END]);
            close(fd[WRITE_END]);
            waitpid(pid, &status, 0);
        }
    }
}

Upvotes: 2

Related Questions