Academic Integrity: tutoring, explanations, and feedback — we don’t complete graded work or submit on a student’s behalf.

uses pipes and fork() call to implement the shell pipe “|”. The code is followin

ID: 3681885 • Letter: U

Question

uses pipes and fork() call to implement the shell pipe “|”. The code is following:

//This program executes "ls -ltr | grep 33340", by dividing the two command among the child and parent process

#include <stdio.h>

#include <stdlib.h>

#include <unistd.h>

#include <fcntl.h>

#include <sys/types.h>

#include <sys/stat.h>

int main(int argc, char **argv) {

int status;

int childpid;

char *cat_args[] = {"ls", "-ltr", NULL};

char *grep_args[] = {"grep", "3340", NULL};

// create one pipe to send the output of "ls" process to "grep" process

int pipes[2]; pipe(pipes);

// fork the first child (to execute cat)

if((childpid = fork()) == -1){

perror("Error creating a child process");

exit(1);

}

if (childpid == 0) {

// replace cat's stdout with write part of 1st pipe

dup2(pipes[1], 1);

// close all pipes (very important!); end we're using was safely copied

close(pipes[0]);

close(pipes[1]);

execvp(*cat_args, cat_args);

exit(0);

}

else {

// replace grep's stdin with read end of 1st pipe

dup2(pipes[0], 0);

close(pipes[0]);

close(pipes[1]);

execvp(*grep_args, grep_args);

}

return(0);

}

Change code to execute the following double pipe command: “ls -ltr | grep 3376 | wc –l”

1- Use one parent and two children to do the work. Call the file TwoPipesTwoChildren.cpp.

2- Write another version where the parent create 3 children, and the children will execute the commands (parent will do nothing, just lay in the sofa ! ). Call the file TwoPipesThreeChildren.cpp

Explanation / Answer

TwoPipesTwoChildren.cpp:

#include <stdio.h>

#include <stdlib.h>

#include <unistd.h>

#include <fcntl.h>

#include <sys/types.h>

#include <sys/stat.h>

int main(int argc, char **argv) {

int status;

char *cat_args[] = {"ls", "-ltr", NULL};

char *grep_args[] = {"grep", "3340", NULL};

char *wc_args[] = {"wc", "-l", NULL};

// create two pipea to send the output of "ls" process to "grep" process and to "wc" process

int pipe_A[2];

int pipe_B[2];

pipe(pipe_A);

pipe(pipe_B);

pid_t pid_A, pid_B;

//first child

if( !(pid_A = fork()) ) {

close(pipe_A[0]);

dup2(pipe_A[1], 1); /* redirect standard output to pipe_A write end */

close(pipe_A[1]);

execvp(*cat_args, cat_args);

exit(0);

}

//second child

else if( !(pid_B = fork()) ) {

close(pipe_A[1]);

dup2(pipe_A[0], 0); /* redirect standard input to pipe_A read end */

close(pipe_A[0]);

close(pipe_B[0]);

dup2(pipe_B[1], 1); /* redirect standard output to pipe_B write end */

close(pipe_B[1]);

execvp(*grep_args, grep_args);

}

//parent

else {

close(pipe_A[1]);

close(pipe_A[0]);

close(pipe_B[1]);

dup2(pipe_B[0], 0); /* redirect standard input to pipe_B read end */

close(pipe_B[0]);

execvp(*wc_args, wc_args);

}

close(pipe_B[1]);

close(pipe_B[0]);

return(0);

}

TwoPipesThreeChildren.cpp:
#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <fcntl.h>
#include <sys/types.h>
#include <sys/stat.h>
int main(int argc, char **argv) {
int status;
char *cat_args[] = {"ls", "-ltr", NULL};
char *grep_args[] = {"grep", "3340", NULL};
char *wc_args[] = {"wc", "-l", NULL};
// create two pipea to send the output of "ls" process to "grep" process and to "wc" process
int pipe_A[2];
int pipe_B[2];

pipe(pipe_A);

pid_t pid_A, pid_B, pid_C;
//first child
if( !(pid_A = fork()) ) {
close(pipe_A[0]);
dup2(pipe_A[1], 1); /* redirect standard output to pipe_A write end */
close(pipe_A[1]);
execvp(*cat_args, cat_args);
exit(0);
}
pipe(pipe_B);
//second child
if( !(pid_B = fork()) ) {
close(pipe_A[1]);
dup2(pipe_A[0], 0); /* redirect standard input to pipe_A read end */
close(pipe_A[0]);
close(pipe_B[0]);
dup2(pipe_B[1], 1); /* redirect standard output to pipe_B write end */
close(pipe_B[1]);
execvp(*grep_args, grep_args);
}
close(pipe_A[1]);
close(pipe_A[0]);
//third child
if( !(pid_C = fork()) ) {
close(pipe_B[1]);
dup2(pipe_B[0], 0); /* redirect standard input to pipe_B read end */
close(pipe_B[0]);
execvp(*wc_args, wc_args);
}
close(pipe_B[1]);
close(pipe_B[0]);
return(0);
}