Using C++, you are to design a simple shell which implements a subset of the fun
ID: 3822718 • Letter: U
Question
Using C++, you are to design a simple shell which implements a subset of the
functionality of the Bourne Again Shell (Bash). The requirements for your shell are as
follows:
Continually prompt for textual user input on a command line.
Parse user input according the the provided grammar (see below)
When a user enters a well formed command, execute it in the same way as a shell. You must use the commands fork and exec to accomplish this. You may NOT use
the C++ system() command.
Allow users to pipe the standard output from one command to the input of another
an arbitrary number of times.
Support input redirection from a le and output redirection to a le.
Allow users to specify whether the process will run in the background or foreground
using an '&'. (Commands to run in the foreground do not have an '&', and commands
that run in the background do)
Explanation / Answer
#include <stdio.h>
#include <sys/types.h>
#include <sys/wait.h>
#include <unistd.h>
#include <stdlib.h>
#include <signal.h>
#include <bits/stdc++.h>
void Run_command(char **, int, char **);
void handle_signal(int);
int spliter(char *, char **, char **, int *);
void split(char *);
#define SIZE 80
#define NR 00
#define O_R 11
#define I_R 22
#define PL 33
#define BG 44
#define OUTPUT 55
typedef void (*sighandler_t)(int);
int main(int argc, char *argv[])
{
int i, m = NR, Argc;
size_t len = SIZE;
char *cpt, *input, *Argv[SIZE], *sp = NULL;
input = (char*)malloc(sizeof(char)*SIZE);
char curLoc[100];
while(1)
{
m = NR;
getcwd(curLoc, 100);
printf("%s@%s->", getlogin(),curLoc);
getline( &input, &len, stdin);
if(strcmp(input, "exit ") == 0)
exit(0);
Argc = spliter(input, Argv, &sp, &m);
if(strcmp(*Argv, "cd") == 0)
{
chdir(Argv[1]);
}
else
Run_command(Argv, m, &sp);
}
return 0;
}
int spliter(char *input, char *Argv[], char **sp, int *m)
{
int Argc = 0, stop = 0;
char *src = input;
while(*src != '' && stop == 0)
{
*Argv = src;
Argc++;
while(*src != ' ' && *src != ' ' && *src != '' && *src != ' ' && stop == 0)
{
switch(*src)
{
case '&'://check for background process
*m = BG;
break;
case '>'://redirection
*m = O_R;
*Argv = '';
src++;
if(*src == '>')
{
*m = OUTPUT;
src++;
}
while(*src == ' ' || *src == ' ')
src++;
*sp = src;
split(*sp);
stop = 1;
break;
case '<'://redirection
*m = I_R;
*Argv = '';
src++;
while(*src == ' ' || *src == ' ')
src++;
*sp = src;
split(*sp);
stop = 1;
break;
case '|'://ipie command
*m = PL;
*Argv = '';
src++;
while(*src == ' ' || *src == ' ')
src++;
*sp = src;
stop = 1;
break;
}
src++;
}
while((*src == ' ' || *src == ' ' || *src == ' ') && stop == 0)
{
*src = '';
src++;
}
Argv++;
}
*Argv = '';
return Argc;
}
void split(char *src)
{
while(*src != ' ' && *src != ' ' && *src != ' ')
{
src++;
}
*src = '';
}
void Run_command(char **Argv, int m, char **sp)
{
pid_t pid, pid2;
FILE *fp;
int m2 = NR, Argc, status1, status2;
char *Argv2[SIZE], *sp2 = NULL;
int myp[2];
if(m == PL)
{
if(pipe(myp)) //create pipe
{
fprintf(stderr, " failed!");
exit(-1);
}
spliter(*sp, Argv2, &sp2, &m2);
}
pid = fork();
if( pid < 0)
{
printf("Error");
exit(-1);
}
else if(pid == 0)
{
switch(m)
{
case O_R:
fp = fopen(*sp, "w+");
dup2(fileno(fp), 1);
break;
case OUTPUT:
fp = fopen(*sp, "a");
dup2(fileno(fp), 1);
break;
case I_R:
fp = fopen(*sp, "r");
dup2(fileno(fp), 0);
break;
case PL:
close(myp[0]); //close input of pipe
dup2(myp[1], fileno(stdout));
close(myp[1]);
break;
}
execvp(*Argv, Argv);
}
else
{
if(m == BG)
;
else if(m == PL)
{
waitpid(pid, &status1, 0);
pid2 = fork();
if(pid2 < 0)
{
printf("error ");
exit(-1);
}
else if(pid2 == 0)
{
close(myp[1]); //close output to pipe
dup2(myp[0], fileno(stdin));
close(myp[0]);
execvp(*Argv2, Argv2);
}
else
{
close(myp[0]);
close(myp[1]);
}
}
else
waitpid(pid, &status1, 0);
}
}
===========================================================================
Output:
akshay@akshay-Inspiron-3537:~/Chegg$ g++ shell.cpp
akshay@akshay-Inspiron-3537:~/Chegg$ ./a.out
akshay@/home/akshay/Chegg->ps
PID TTY TIME CMD
3443 pts/0 00:00:00 bash
3568 pts/0 00:00:00 python
7023 pts/0 00:00:00 a.out
7026 pts/0 00:00:00 a.out
7189 pts/0 00:00:00 a.out
7190 pts/0 00:00:00 ps
akshay@/home/akshay/Chegg->exit
===================================================================
Related Questions
drjack9650@gmail.com
Navigate
Integrity-first tutoring: explanations and feedback only — we do not complete graded work. Learn more.