Purpose Exercise the fork, exec, pipe and dup system calls. Assignment Write a C
ID: 3567354 • Letter: P
Question
Purpose
Exercise the fork, exec, pipe and dup system calls.
Assignment
Write a C++ program that keeps prompting for 2 UNIX commands that are then executed in a pipe arrangement.
Program
Implement a C++ program that prompts the user for 2 commands. Each input string should be a UNIX command, with
arguments allowed. For example, input 1 could be "ls -l" and input 2 could be "wc -l". The program will then create a
pipe, and two child processes. The first child process will run the command specified in the first input. It will output to the
pipe instead of standard output. The second child process will run the command specified in the second input. It will take
its input from the pipe rather than standard input.
The parent process will wait on its two children to complete, then the whole thing will repeat. Execution will stop when
"quit" is entered as the first command.
Error Checking
Execute the command and its arguments as the user has entered it. Use one of the "exec" library functions to execute it.
Use the "perror" library function to report any error if "exec" fails.
Example Run
% ./z123456.pipe
Enter command 1 (incl. args) or quit: ls
Enter command 2 (incl. args): wc
5 5 63
Enter command 1 (incl. args) or quit: ls -l
Enter command 2 (incl. args): wc -w
47
Enter command 1 (incl. args) or quit: hello
Enter command 2 (incl. args): more
hello: No such file or directory
Enter command 1 (incl. args) or quit: quit
%
Hints
you can assume that user input is less than 80 characters long
you can assume that user will use no more than 5 arguments to a command
make sure to close unused pipe file descriptors
Explanation / Answer
#include <iostream>
#include <cstdio>
#include <cstdlib>
#include <unistd.h>
#include <sys/types.h>
#include <sys/wait.h>
#include <cstring>
#include <stdlib.h>
#include <iostream>
using namespace std;
int main()
{
//Variables
string command1, command2;
char quit[]="quit";
cout << "Enter your first command (including arguments) or quit to exit: ";
cin >> command1;
while(command1!="quit")
{
cout << "Enter your second command (including arguments): ";
cin >> command2;
//Create pipe
int pipefd[2];
int rs=pipe(pipefd);
//error check pipe
if(rs==-1)
{
perror("pipe");
exit(EXIT_FAILURE);
}
//fork into two processes
rs=fork();
//error check fork
if(rs==-1)
{
perror("pipe");
exit(EXIT_FAILURE);
}
//child process
if(rs==0)
{
//close read end of pipe, keep write end open
close(pipefd[0]);
//close standard output
close(1);
//duplicate write end of pipe into standard output
dup(pipefd[1]);
//close write end of pipe
close(pipefd[1]);
//run the first command
rs=execlp(command1.c_str(), command1.c_str(), (char*)NULL);
//error check execlp
if(rs==-1)
{
perror("execlp");
exit(EXIT_FAILURE);
}
}
//parent process
else
{
//close write end of pipe, keep read open
close(pipefd[1]);
//close standard input
close(0);
//duplicate read end of pipe into standard input
dup(pipefd[0]);
//close read end
close(pipefd[0]);
//fork into two processes
rs=fork();
//error check the fork
if(rs==1)
{
perror("pipe");
exit(EXIT_FAILURE);
}
//child process 2
if(rs==0)
{
//run second command
rs=execlp(command2.c_str(), command2.c_str(), (char*)NULL);
//error check execlp
if(rs==-1)
{
perror("execlp");
exit(EXIT_FAILURE);
}
}
//parent process
else
{
wait(NULL);
wait(NULL);
}
}
cout << "Enter your first command (including arguments) or quit to exit: ";
cin >> command1;
}
return 0;
}
Related Questions
drjack9650@gmail.com
Navigate
Integrity-first tutoring: explanations and feedback only — we do not complete graded work. Learn more.