Akhmad Sumekenov
Akhmad Sumekenov

Reputation: 147

Why this code stalls when calling ./prog ls ls wc 1.txt?

when compiling this code and calling

./prog ls ls wc 1.txt

(supposed to be

(ls; ls) | wc > 1.txt

this code stalls and done right only after Control-d. What's the matter?

#include <unistd.h>
#include <sys/wait.h>
#include <sys/types.h>
#include <stdio.h>
#include <stdlib.h>
#include <fcntl.h>

int main(int argc, char const *argv[])
{
    int fd[2];
    pipe(fd);
    if (!fork()) {
        close(fd[0]);
        dup2(fd[1], 1);
        close(fd[1]);
        if (!(fork())) {
            execlp(argv[1], argv[1], NULL);
            _exit(1);
        }
        wait(NULL);
        if (!fork()) {
            execlp(argv[2], argv[2], NULL);
            _exit(1);
        }
        wait(NULL);
    }
    close(fd[1]);
    wait(NULL);
    if (!fork()) {
        dup2(fd[0], 0);
        close(fd[0]);
        int ffd = open(argv[4], O_WRONLY | O_CREAT | O_TRUNC, 0600);
        dup2(ffd, 1);
        close(ffd);
        execlp(argv[3], argv[3], NULL);
        _exit(1);
    }
    close(fd[0]);
    wait(NULL);
    return 0;
}

Upvotes: 1

Views: 153

Answers (1)

Barmar
Barmar

Reputation: 781761

You need to exit the program in the first child process, otherwise both the original process and the child execute the code at the bottom that runs wc reading from the pipe.

Or you can put all that code in an else block, so it doesn't run in the child process.

#include <unistd.h>
#include <sys/wait.h>
#include <sys/types.h>
#include <stdio.h>
#include <stdlib.h>
#include <fcntl.h>

int main(int argc, char const *argv[])
{
    int fd[2];
    pipe(fd);
    if (!fork()) {
        close(fd[0]);
        dup2(fd[1], 1);
        close(fd[1]);
        if (!(fork())) {
            execlp(argv[1], argv[1], NULL);
            _exit(1);
        }
        wait(NULL);
        if (!fork()) {
            execlp(argv[2], argv[2], NULL);
            _exit(1);
        }
        wait(NULL);
    } else {
        close(fd[1]);
        wait(NULL);
        if (!fork()) {
            dup2(fd[0], 0);
            close(fd[0]);
            int ffd = open(argv[4], O_WRONLY | O_CREAT | O_TRUNC, 0600);
            dup2(ffd, 1);
            close(ffd);
            execlp(argv[3], argv[3], NULL);
            _exit(1);
        }
        close(fd[0]);
        wait(NULL);
        return 0;
    }
}

Upvotes: 1

Related Questions