I am trying to do ls -la | wc
#include<stdio.h>
#include<stdlib.h>
#include<sys/types.h>
#include<sys/wait.h>
#include<unistd.h>
int main(int argc, char **argv)
{
int pipes=3;
char *ls[] = {"ls","-la",NULL};
char *wc[] = {"wc",NULL};
char *base64[] = {"base64","-w0",NULL};
//char **commands[] = {ls,wc,base64};
int fds[pipes][2];
for(int i=0;i<pipes;i++)
{
int err = pipe(fds[i]);
if(err == -1)
{
perror("Pipe failed.\n");
}
}
int status;
pid_t childPid;
//Child 1.
if((childPid = fork()) == 0)
{
dup2(fds[0][1],1);
for(int i=0;i<pipes;i++)
{
close(fds[i][0]);
close(fds[i][1]);
}
execvp(ls[0],ls);
exit(0);
}
else if(childPid == -1)
{
perror("Child 1 failed.\n");
}
// Second child.
if((childPid = fork()) == 0)
{
dup2(fds[0][0],0);
for(int i=0;i<pipes;i++)
{
close(fds[i][0]);
close(fds[i][1]);
}
execvp(wc[0],wc);
}
else if(childPid == -1)
{
perror("Child 2 failed.\n");
}
for(int i=0;i<pipes;i++)
{
close(fds[i][0]);
close(fds[i][1]);
}
waitpid(childPid,&status,WUNTRACED|WNOHANG);
return 0;
}
out expect:
root@danial#gcc -o pip pip.c
root@danial#./pip
10 83 436
output I am getting:
root@danial#./pip
root@danial# 10 83 436
cursor stays here until I press enter key.
I tried doing this without pipes just wrote a simple program:
#include<stdio.h>
#include<stdlib.h>
#include<sys/types.h>
#include<unistd.h>
#include<sys/wait.h>
int main(int argc, char **argv)
{
if(fork() == 0)
{
execlp("ls","ls","-la",NULL);
exit(0);
}
return 0;
}
and samething happend:
root@danial#./test
root@danial#total 84
drwxr-xr-x 3 root root 4096 Mar 30 06:49 .
drwxr-xr-x 9 root root 4096 Mar 29 09:33 ..
-rwxr-xr-x 1 root root 16960 Mar 30 06:49 pip
-rw-r--r-- 1 root root 1310 Mar 30 06:48 pip.c
The problem is this
waitpid(childPid,&status,WUNTRACED|WNOHANG);
With the WNOHANG
you tell waitpid
to poll the status, and then return immediately withoput actually waiting.
When the waitpid
call returns, you exit the parent process, leaving your two child-processes orphaned.
And what happens when the parent process exiting is that its parent process (the shell) taking over and printing the prompt. Then your child-processes prints their output. The Enter key you press to "clear" the output is simply empty input for the shell.
You need to wait for both your child processes.