i need create 2 child processes. 1 child needs run command "ls -al" , redirect output input of next child process, in turn run command "sort -r -n -k 5" on input data. finally, parent process needs read (data sorted) , display in terminal. final result in terminal (when executing program) should same if entered following command directly in shell: "ls -al | sort -r -n -k 5". need use following methods: pipe(), fork(), execlp().
my program compiles, don't desired output terminal. don't know wrong. here code:
#include <sys/types.h> #include <stdio.h> #include <string.h> #include <unistd.h> int main() { int fd[2]; pid_t ls_pid, sort_pid; char buff[1000]; /* create pipe */ if (pipe(fd) == -1) { fprintf(stderr, "pipe failed"); return 1; } /* create child 2 first */ sort_pid = fork(); if (sort_pid < 0) { // error creating child 2 process fprintf(stderr, "\nchild 2 fork failed"); return 1; } else if(sort_pid > 0) { // parent process wait(null); // wait children termination /* create child 1 */ ls_pid = fork(); if (ls_pid < 0) { // error creating child 1 process fprintf(stderr, "\nchild 1 fork failed"); return 1; } else if (ls_pid == 0) { // child 1 process close(1); // close stdout dup2(fd[1], 1); // make stdout same fd[1] close(fd[0]); // don't need end of pipe execlp("bin/ls", "ls", "-al", null);// executes ls command } wait(null); read(fd[0], buff, 1000); // parent reads data printf(buff); // parent prints data terminal } else if (sort_pid == 0) { // child 2 process close(0); // close stdin dup2(fd[0], 0); // make stdin same fd[0] close(fd[1]); // don't need end of pipe execlp("bin/sort", "sort", "-r", "-n", "-k", "5", null); // executes sort operation } return 0; }
your parent process wait
s sort process finish before creating ls process.
the sort process needs read input before can finish. , input coming ls won't started until after wait
. deadlock.
you need create both processes, wait
both of them.
also, file descriptor manipulations aren't quite right. in pair of calls:
close(0); dup2(fd[0], 0);
the close redundant, since dup2 automatically close existing fd 0 if there one. should close(fd[0])
after ther dup2, have 1 file descriptor tied end of pipe. , if want robust, should test wither fd[0]==0
already, , in case skip dup2 , close.
apply of other dup2 also.
then there's issue of parent process holding pipe open. i'd should close both ends of pipe in parent after you've passed them on children, have weird read
fd[0]
after last wait
... i'm not sure why that's there. if ls|sort
pipeline has run correctly, pipe empty afterward, there nothing read. in case, need close fd[1]
in parent, otherwise sort process won't finish because pipe won't indicate eof until writers closed.
after weird read
printf
crash, since read buffer won't '\0'
-terminated.
and point of using execlp
$path
lookup don't have specify /bin/
. first test run failed because sort in /usr/bin/
. why hardcode paths when don't have to?
Comments
Post a Comment