Вопрос

I want to write a small program that prints out a long list which can be paged in the terminal through more (or less) so that the list can be examined from head to toe...

The program:

  • fork's off a child process in which the more program is executed
  • In the parent process, the list is printed
  • There is a pipe set up between parent/child so that the list printed to stdout by the parent is sent to the more program's stdin

code:

int main(int argc, char *argv[])
{
    int pager, status;
    int pipes[2];

    pipe(pipes);

    pager = fork();

    if (pager == 0) { // child

        dup2(pipes[0], 0);
        close(pipes[1]);
        char *args[] = {"more", NULL}; 
        execvp(args[0], args);

    } else { // parent

        dup2(pipes[1], 1);

        int x;
        for (x = 0; x < 500; x++) {
            printf("Hello World! %d\n", x);
        }  

        close(pipes[0]);
        close(pipes[1]);

        wait(&status);
    } 

    return 0;
}

I have this working for the most part:

  • The long list of "Hello World!..." messages are printed on the terminal clipped by a --More-- so I know the basic pipe setup is working.
  • If I press [q] before the entire list finishes printing (quit the more process) the programs (parent/child) exit as expected

The only problem I am having is that if I keep pressing [space] or [return] (which advances the output given by more) and reach the end of my list (the 500th "Hello World!..." message) then the terminal just hangs. Pressing [q] is unresponsive (I have to [ctrl+c] to get out).

The parent process is stuck on wait. The more process is not exiting even though I have closed both pipes in the parent

Это было полезно?

Решение

In your code you are closing pipe[0] which is not the descriptor you are writing to the child. You did a dup2(pipes[1], 1) so in order to tell the child that the pipe has ended you must close the one you are writing to.

close(1);

Of course you'd have to restore the original output if you intend to continue your process using stdout, as this would be closed now.

Лицензировано под: CC-BY-SA с атрибуция
Не связан с StackOverflow
scroll top