I'm writing a program to pipe one command to another. Inputs will be from the command line:
$ ./a.out ls '|' wc
c2 PID 6804
c1 PID 6803
PARENT PID 6802
$ 2 2 17
Why does the output print after the prompt returns. Is there any way to prevent that?
This is the code I've written:
#include <stdio.h>
#include <string.h>
#include <sys/types.h>
#include <sys/wait.h>
#include <unistd.h>
int main(int argc, char * argv[])
{
if(argc <= 1 )
{
printf("ERROR: No arguments passed\n");
printf("USAGE: ./pipe <command 1> | <command 2>\n");
return 1;
}
char * cmd1[50];
char * cmd2[50];
int cmd1_arg = 0;
int cmd2_arg = 0;
int pipe_num = 0;
for(int cla = 1; cla<argc; cla++)
{
if( !strcmp(argv[cla],"|") )
pipe_num++;
else if(pipe_num == 0)
cmd1[cmd1_arg++] = argv[cla];
else if(pipe_num == 1)
cmd2[cmd2_arg++] = argv[cla];
}
cmd1[cmd1_arg] = (char *)NULL;
cmd2[cmd2_arg] = (char *)NULL;
if(pipe_num != 1)
{
printf("ERROR: Insufficient arguments passed\n");
printf("USAGE: ./pipe <command 1> | <command 2>\n");
return 1;
}
int pipe_fd[2];
pipe(pipe_fd);
pid_t pid = fork();
if(pid == -1)
{
perror("FORK FAILED");
return 1;
}
if(pid != 0)
{
pid_t cmd_pid = fork();
if(cmd_pid == -1)
{
perror("FORK FAILED");
return 1;
}
if(cmd_pid != 0)
{
waitpid(pid,NULL,0);
waitpid(cmd_pid,NULL,WNOHANG);
printf("PARENT PID %d\n",getpid());
}
if(cmd_pid == 0)
{
printf("c2 PID %d\n",getpid());
close(pipe_fd[1]);
int stdin_fd = dup(0);
close(0);
dup(pipe_fd[0]);
if(execvp(cmd2[0],cmd2) == -1 ) perror("CMD2 FAIL");
close(0);
dup(stdin_fd);
}
}
if(pid == 0)
{
printf("c1 PID %d\n",getpid());
close(pipe_fd[0]);
int stdout_fd = dup(1);
close(1);
int test = dup(pipe_fd[1]);
if( execvp(cmd1[0],cmd1) == -1 ) perror("CMD1 FAIL");
close(1);
dup(stdout_fd);
}
return 0;
}