2

I have a program that is supposed to create a child process and run the ls command. The output of this command should be piped to the parent process where it is printed to the screen.

The problem is that the parent process receives the output of the child in sorted order. After 2 days of working on it, I still have no clue why it is doing this.

This is my code:

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

int main(){
    int Pipe1[2];
    int pid, numread;
    char buf;

    pipe(Pipe1);
    pid = fork();

    if(pid == 0){
        close(Pipe1[0]);
        dup2(Pipe1[1], STDOUT_FILENO);
        close(Pipe1[1]);

        execl("/bin/ls", "ls", NULL);
    }
    else{
        close(Pipe1[1]);
        dup2(Pipe1[0], STDIN_FILENO);
        close(Pipe1[0]);

        while(1){
            numread = read(STDIN_FILENO, &buf, 1);
            if(numread > 0)
                fprintf(stderr, "%c", buf);
            else break;
        }

        close(STDOUT_FILENO);
        wait(NULL);
    }
}

This is the expected output:

a.out    tk-quiz-01-ptr-trace.pdf     tk-quiz-02c-prog-image-static.pdf  tk-quiz-04-cpu-schedule.pdf
quiz7.c  tk-quiz-02b-cl-allocate.pdf  tk-quiz-03-unix-process.pdf        tk-quiz-05-cpu-sch-link-list.pdf

This is the actual output:

a.out
quiz7.c
tk-quiz-01-ptr-trace.pdf
tk-quiz-02b-cl-allocate.pdf
tk-quiz-02c-prog-image-static.pdf
tk-quiz-03-unix-process.pdf
tk-quiz-04-cpu-schedule.pdf
tk-quiz-05-cpu-sch-link-list.pdf
cameron
  • 33
  • 4
  • 3
    ls changes its output formatting when it’s writing to a pipe instead of a terminal. You’ll see the same result with `ls | cat`. – Ry- Mar 01 '20 at 19:55
  • Thank you so much! Is there anyway to trick the process into thinking it is writing to stdout? This way it could work for similar processes. – cameron Mar 01 '20 at 20:07
  • 2
    Yes, you can use a [pseudoterminal](https://stackoverflow.com/q/26659595/132382). – pilcrow Mar 01 '20 at 20:19
  • 1
    Much simpler than using a pseudo-tty is to tell `ls` to produce multi-columnar output; `ls -C`. If required (not in your case), you can demand that `ls` produce a single column output with `ls -1`. All this should be clear from consulting the manual — it shouldn't take you 2 days to think of reading it. – Jonathan Leffler Mar 01 '20 at 21:29

0 Answers0