Question
Pipelined Commands In this portion of the recitation, you will be given nearly complete C code that implements a pipeline (i.e., multiple pipes). Specifically, your
Pipelined Commands In this portion of the recitation, you will be given nearly complete C code that implements a pipeline (i.e., multiple pipes). Specifically, your code will implement functionality executed by the following command: cat input_file | grep text_pattern | cut -b 1-10
This cut command simply selects the first 10 bytes (i.e., characters) from the resulting text.
Your program is invoked with the following: ./a.out input_file text_pattern
All that is missing are 18 system calls (dont worry, most of them are the close() system call) for you to add beneath the applicable comments in the code. Follow the comment instructions to add the needed code, paying special attention to which file descriptor is being closed or duplicated.
SAMPLE OUTPUT: $ more input1.txt This life, which had been the tomb of his virtue and of his honour, is but a walking shadow; a poor player, that struts and frets his hour upon the stage, and then is heard no more: it is a tale told by an idiot, full of sound and fury, signifying nothing. -- William Shakespeare $ cat input1.txt | grep his | cut -b 1-10 This life, tomb of hi struts and $ ./a.out input1.txt his This life, tomb of hi struts and
Here's the code:
/*
* usage: ./a.out input_file text_pattern
* Executes the command "cat input_file | grep text_pattern | cut -b 1-10".
* Note only minimal error checking is done for simplicity/shortness of code.
*/
#include
#include
#include
#include
#include
int main(int argc, char **argv)
{
int status;
int i;
if (argc == 3)
{
// arguments for commands
char *cat_args[] = {"cat", argv[1], NULL};
char *grep_args[] = {"grep", argv[2], NULL};
char *cut_args[] = {"cut", "-b", "1-10", NULL};
// file descriptors for 2 pipes: fd1 for cat-to-grep, fd2 for grep-to-cut
int fd1[2], fd2[2];
// make pipe for cat to grep
// fd1[0] = read end of cat->grep pipe (read by grep)
// fd1[1] = write end of cat->grep pipe (written by cat)
// make pipe for grep to cut
// fd2[0] = read end of grep->cut pipe (read by cut)
// fd2[1] = write end of grep->cut pipe (written by grep)
// fork the first child (to execute cat)
if (fork() == 0)
{
// duplicate write end of cat->grep pipe to stdout
// close both ends of all created fd# pipes (very important!)
execvp(*cat_args, cat_args);
}
else // parent (assume no error)
{
// fork second child (to execute grep)
if (fork() == 0)
{
// duplicate read end of cat->grep pipe to stdin (of grep)
// duplicate write end of grep->cut pipe to stdout (of grep)
// close both ends of all created fd# pipes (very important!)
execvp(*grep_args, grep_args);
}
else // parent (assume no error)
{
// fork third child (to execute cut)
if (fork() == 0)
{
// duplicate read end of grep->cut pipe to stadin (of cut)
// close both ends of all created fd# pipes (very important!)
execvp(*cut_args, cut_args);
}
}
}
// only the parent gets here, close all pipes and wait for 3 children to finish
close(fd1[0]);
close(fd1[1]);
close(fd2[0]);
close(fd2[1]);
for (i = 0; i < 3; i++)
{
wait(&status);
}
}
else
{
printf("usage: %s input_file text_pattern ", argv[0]);
}
return 0;
}
Step by Step Solution
There are 3 Steps involved in it
Step: 1
Get Instant Access to Expert-Tailored Solutions
See step-by-step solutions with expert insights and AI powered tools for academic success
Step: 2
Step: 3
Ace Your Homework with AI
Get the answers you need in no time with our AI-driven, step-by-step assistance
Get Started