c - Program stuck on Pipe (exec ls grep sort) -
i'm trying make program executes following commands connecting output of 1 input of next using pipes , taking 2 arguments dir (directory) , arg (filetype, example: jpg).
ls dir -lar | grep arg | sort
here's code:
int main(int argc, char *argv[]) { if (argc != 3) { printf("invalid arguments. <dir> <arg>\n"); exit(1); } int pipe_fd1[2]; int pipe_fd2[2]; pid_t ls_pid, grep_pid; int status; pipe(pipe_fd1); pipe(pipe_fd2); ls_pid = fork(); if (ls_pid == 0) { //first child ls dir -lar dup2(pipe_fd1[1], stdout_fileno); close(pipe_fd1[0]); execlp("ls", "ls", argv[1], "-lar", null); } else if (ls_pid > 0) { grep_pid = fork(); if (grep_pid == 0) { //second child grep arg dup2(pipe_fd1[0], stdin_fileno); dup2(pipe_fd2[1], stdout_fileno); close(pipe_fd1[1]); close(pipe_fd2[0]); waitpid(ls_pid, &status, 0); execlp("grep", "grep", argv[2], null); } else if (grep_pid > 0) { //parent sort dup2(pipe_fd2[0], stdin_fileno); close(pipe_fd2[1]); waitpid(grep_pid, &status, 0); execlp("sort", "sort", null); } } return 0; }
it seems stuck? not sure why?
you never close pipe_fd1
on parent, grep
, sort
doen't know when stop reading input: because pipe read , write ends never closed on parent, reader blocks waiting more input never arrive. need close it.
also, don't need waitpid()
: way pipes work ensures input flows linearly , in order throughout pipe.
here's working version these issues addressed:
#include <stdio.h> #include <stdlib.h> #include <unistd.h> #include <sys/types.h> #include <sys/wait.h> int main(int argc, char *argv[]) { if (argc != 3) { printf("invalid arguments. <dir> <arg>\n"); exit(1); } int pipe_fd1[2]; int pipe_fd2[2]; pid_t ls_pid, grep_pid; pipe(pipe_fd1); ls_pid = fork(); if (ls_pid == 0) { //first child ls dir -lar dup2(pipe_fd1[1], stdout_fileno); close(pipe_fd1[0]); execlp("ls", "ls", argv[1], "-lar", null); } else if (ls_pid > 0) { dup2(pipe_fd1[0], stdin_fileno); close(pipe_fd1[1]); pipe(pipe_fd2); grep_pid = fork(); if (grep_pid == 0) { //second child grep arg dup2(pipe_fd2[1], stdout_fileno); close(pipe_fd2[0]); execlp("grep", "grep", argv[2], null); } else if (grep_pid > 0) { //parent sort dup2(pipe_fd2[0], stdin_fileno); close(pipe_fd2[1]); execlp("sort", "sort", null); } } return 0; }
Comments
Post a Comment