Jonathan Chiou
Jonathan Chiou

Reputation: 359

Piping problems (Broken pipe)

Given a command in this format:

cat < inputfile.txt | tee outputfile.txt

I'm trying to have inputfile.txt write to a pipe and then have outputfile.txt read from the pipe, and I've written the following fucntions to do so:

void piperead(char** input, int* fd, int start) {

    dup2(fd[0], 0);
    close(fd[1]);
    execl("usr/bin/tee", "usr/bin/tee", input[start + 1], NULL);

}

void pipewrite(char** input, int* fd, int start, int end) {

    dup2(fd[1], 1);
    close(fd[0]);
    execl("usr/bin/cat", "usr/bin/tee", input[start + 2], NULL);

}

void dopiping(char** input, int start, int end) {

    int fd[2];
    if (pipe(fd) == -1) {
        cout << "Error: Pipe failed." << endl;
        exit(1);
    }
    int pid = fork();
    switch(pid = fork()) {        
        case 0:
            piperead(input, fd, start, end);
        default:
            pipewrite(input, fd, end + 1);        
        case -1:
            exit(1);
    }


}

I've converted the command into an array of c_strings (let's call it cmdarray), and then I call dopiping(cmdarray, 0, 3). The moment the program gets to the line:

 dup2(fd[1], 1)

the program terminates because the program received SIGPIPE. Why is my pipe broken, and how do I fix this?

Upvotes: 1

Views: 790

Answers (1)

Beano
Beano

Reputation: 7841

So looking at this logically

  • SIGPIPE is delivered to a process that does a write() to a closed or pipe/socket.
  • Therefore the reading side of the pipe you create has to have been closed.
  • Your code does not close fd[0] after you have performed your dup2()
  • So it looks like the child process is exiting.
  • I would guess that either the execl() is failing - you should try specifying "/usr/bin/tee" (full path not relative path)
  • or your tee is failing - need to make sure that input[start+1] points to a null terminated string that represents a valid file path.

Upvotes: 1

Related Questions