Reputation: 45
I'm trying to execute the Linux command "ls -l | tail -n 2" with a simple pipe in a c code.
I added your tips and now this works but the output isn't exactly as it should be. It prints the output in a single line instead of two and waits for a user input to close. here is the new code:
#include "stdio.h"
#include "unistd.h"
#include "stdlib.h"
#include "sys/wait.h"
#include <sys/types.h>
#include <sys/stat.h>
#include <fcntl.h>
void main()
{
char line[100];
pid_t pid;
int fd[2];
int status;
char* ls_arguments[] = {"ls", "-l", NULL};
char* tail_arguments[] = {"tail", "-n", "2", NULL};
pipe(fd);
pid = fork();
if(pid == 0)//ls client
{
close(1);
dup(fd[1]);
close(fd[0]);
execvp("ls", ls_arguments);
}
pid = fork();
if(pid == 0)//tail client
{
close(0);
close(fd[1]);
dup(fd[0]);
execvp("tail", tail_arguments);
}
wait(pid, 0, WNOHANG);
close(fd[0]);
close(fd[1]);
}
this should run the "ls -l" command and output to the pipe and the next "tail" client would get it as input and run the "tail -n 2" command and print out the final output but the terminal prints nothing. Any help?
Upvotes: 0
Views: 1873
Reputation: 973
First of all, there is not such wait
function, here is what the man
says:
#include <sys/types.h>
#include <sys/wait.h>
pid_t wait(int *status);
pid_t waitpid(pid_t pid, int *status, int options);
I think you meant to use waitpid
.
Then, you child process doesn't finish because the pipe is still opened somewhere: in the parent. Indeed you should first close the descriptors and then wait for your childs process. I would write:
close(fd[0]);
close(fd[1]);
wait(NULL); // Wait for the first child to finish
wait(NULL); // Wait fot the second one
return 0;
}
Instead of:
wait(pid, 0, WNOHANG);
close(fd[0]);
close(fd[1]);
}
Upvotes: 1