2

Program:

#include<stdio.h>
#include<unistd.h>
#include<stdlib.h>
int main()
{
        int cpid=fork();
        if(cpid==0){
                execl("/bin/ls","ls","-lah","--color",NULL);
        }
        else{
                int status;
                waitpid(cpid,&status,0);
                if(status!=0)
                        printf("Error Occured\n");
        }
return 0;
}

Output:

$ ./a.out 
total 20K
drwxrwxr-x 1 guest guest 4.0K Jan 12 15:21 .
drwxrwxr-x 1 guest guest 4.0K Jan 12 15:21 ..
-rwxrwxr-x 1 guest guest 7.2K Jan 12 15:19 a.out
-rw-rw-r-- 1 guest guest  372 Jan 12 15:20 execl.c
$ 

In the above program, parent create a child and the child execute the ls command. But, my requirement is to save the output of ls in an array in parent. Is there any way to do this.

mohangraj
  • 9,842
  • 19
  • 59
  • 94

2 Answers2

3

exec*() family functions replace the current process's image with new one. So you can't read it directly. You don't need a child process to read the output from an external command. You can use popen() to achieve that.

If you do have to create a child process, then you can use pipe(2) to read from the output from the child process. You can find a simple example on the linked man page.

P.P
  • 117,907
  • 20
  • 175
  • 238
  • *"You don't need a child process to read the output from an external command."* Maybe I'm being pedantic, but what do you think `popen` does under the hood? – Jonathon Reinhart Jan 12 '16 at 10:28
  • Perhaps, you don't need to "create one yourself" may be accurate. But I am going to feed trolls and pedants, I can be here all day. I would expect anyone to have a look at the linked manual page before using it to understand what popen does. – P.P Jan 12 '16 at 10:30
1

To use popen() is one possibility, but if you want to go with fork()/exec*(), you would do this:

Before the fork(), create a pipe and attach it to stdout in the child

int fds[2];
pipe(fds);

After the fork, in the child process close the read fd and attach the write fd to stdout:

close(fds[0]);
dup2(fds[1], 1);
close(fds[1]);

In the parent process, close the write fd and read from the read-fd to get the output:

close(fds[1]);
read(fds[0], buf, sizeof(buf));

If you need buffering, you can call fdopen() on the read-fd in the parent process.

Ctx
  • 18,090
  • 24
  • 36
  • 51