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

A double pipe is used to execute the command “ls -ltr | grep 3340 | wc –l”. Howe

ID: 3681977 • Letter: A

Question

A double pipe is used to execute the command “ls -ltr | grep 3340 | wc –l”. However, our program is static: it means that code need to be modified and rebuilt if we want to change the commands to execute. In this part, we make our program dynamic instead of static. The following requirements should be implemented:

1- Source file will be called Dynamic.cpp, executable called dynamic.

2- The piped commands to execute need to be passed as arguments to dynamic,and not hardcoded.

3- The max number of arguments should not exceed 5, and not less than 2 (otherwise print an error message)

4- Each argument should be a unix/linux command with its parameters.

The first argument will be the first to execute, followed by the second one, etc.. We will assume that only valid commands can be used, for simplicity Example: the followings are possible command executions

The Program is

#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 pipe 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);

}

Program execution Shell equivalent dynamic “ls –ltr” “grep 3340” ls –ltr |grep 3340 dynamic “ls –ltr” “grep 3340” “grep hi” wc -l ls –ltr |grep 3340| grep hi| wc-l dynamic “ls –ltr” error

Explanation / Answer

#include <libgen.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <sys/wait.h>
#include <unistd.h>
void read_all(int src, int dst) {
char buf[BUFSIZ];
ssize_t bytes_read, bytes_written;
while ((bytes_read = read(src, buf, BUFSIZ)) > 0) {
bytes_written = 0;
while (bytes_written < bytes_read)
bytes_written += write(dst,
buf + bytes_written,
bytes_read - bytes_written);
}
}
int main(int argc, char** argv) {
if (argc < 2) {
printf("usage: %s <program> [<arg> ...] ", basename(argv[0]));
return EXIT_FAILURE;
}
// create pipes for standard input, output, and error
int stdin_pipe[2];
int stdout_pipe[2];
int stderr_pipe[2];
pipe(stdin_pipe);
pipe(stdout_pipe);
pipe(stderr_pipe);
if (fork() == 0) {
// child process
// close write end of stdin and read ends of stdout and stderr
close(stdin_pipe[1]);
close(stdout_pipe[0]);
close(stderr_pipe[0]);
// change child's stdin, stdout, and stderr to use pipes
dup2(stdin_pipe[0], STDIN_FILENO);
dup2(stdout_pipe[1], STDOUT_FILENO);
dup2(stderr_pipe[1], STDERR_FILENO);
// exec the given program
if (execvp(argv[1], argv+1) == -1) {
perror("failed to start subprocess");
return EXIT_FAILURE;
}
}
// parent process
// close read end of stdin and write ends of stdout and stderr
close(stdin_pipe[0]);
close(stdout_pipe[1]);
close(stderr_pipe[1]);
// pass input to the child process
read_all(STDIN_FILENO, stdin_pipe[1]);
close(stdin_pipe[1]);
// wait for child to finish
wait(NULL);
// read child's stdout and stderr
puts(" child's stdout:");
fflush(stdout);
read_all(stdout_pipe[0], STDOUT_FILENO);
close(stdout_pipe[0]);
puts(" child's stderr:");
fflush(stdout);
read_all(stderr_pipe[0], STDOUT_FILENO);
close(stderr_pipe[0]);
return EXIT_SUCCESS;
}

Hire Me For All Your Tutoring Needs
Integrity-first tutoring: clear explanations, guidance, and feedback.
Drop an Email at
drjack9650@gmail.com
Chat Now And Get Quote