I did already posted this question before, I did get the answer but i am not satisfied with the answer
i did the code as a solution not the description as my solution, so i am reposting this question again. Please send me the code as my solution not the description
In this project, build a simple Unix shell. The shell is the heart of the command-line interface, and thus is central to the Unix/C programming environment. Mastering use of the shell is necessary to become proficient in this world; knowing how the shell itself is built is the focus of this project. There are three specific objectives to this assignment:
Program Specification:
Basic Shell: grsh
Your basic shell, called grsh (short for Golden Ram Shell), is
basically an interactive loop: it repeatedly prints a prompt
grsh>
(note the space after the greater-than sign), parses the
input, executes the command specified on that line of input, and
waits for the command to finish. This is repeated until the user
types exit. The name of your source code should be grsh.c.
The shell can be invoked with either no arguments or a single argument; anything else is an error. Here is the no-argument way:
prompt> ./grsh
grsh>
At this point, grsh is running, and ready to accept commands. Type away!
The mode above is called interactive mode, and allows the user to type commands directly. The shell also supports a batch mode, which instead reads input from a batch file and executes commands from therein. Here is how you run the shell with a batch file named batch.txt:
prompt> ./grsh batch.txt
One difference between batch and interactive modes: in interactive mode, a prompt is printed (grsh> ). In batch mode, no prompt should be printed. You should structure your shell such that it creates a process for each new command (the exception are built-in commands, discussed below). Your basic shell should be able to parse a command and run the program corresponding to the command. For example, if the user types ls -la /tmp, your shell should run the program /bin/ls with the given arguments -la and /tmp (how does the shell know to run /bin/ls? It's something called the shell path; more on this below).
Structure
Basic Shell
Paths
Built-in Commands
Redirection
Parallel Commands
grsh> cmd1 & cmd2 args1 args2 & cmd3 args1
Program Errors
char error_message[30] = "An error has occurred\n";
write(STDERR_FILENO, error_message, strlen(error_message));
Miscellaneous Hints
Programming References:
// C Program to design a shell in Linux
#include<stdio.h>
#include<string.h>
#include<stdlib.h>
#include<unistd.h>
#include<sys/types.h>
#include<sys/wait.h>
#include<readline/readline.h>
#include<readline/history.h>
#define MAXCOM 1000 // max number of letters to be
supported
#define MAXLIST 100 // max number of commands to be supported
// Clearing the shell using escape sequences
#define clear() printf("\033[H\033[J")
// Greeting shell during startup
void init_shell()
{
clear();
printf("\n\n\n\n******************"
"************************");
printf("\n\n\n\t****MY SHELL****");
printf("\n\n\t-USE AT YOUR OWN RISK-");
printf("\n\n\n\n*******************"
"***********************");
char* username = getenv("USER");
printf("\n\n\nUSER is: @%s", username);
printf("\n");
sleep(1);
clear();
}
// Function to take input
int takeInput(char* str)
{
char* buf;
buf = readline("\n>>> ");
if (strlen(buf) != 0) {
add_history(buf);
strcpy(str, buf);
return 0;
} else {
return 1;
}
}
// Function to print Current Directory.
void printDir()
{
char cwd[1024];
getcwd(cwd, sizeof(cwd));
printf("\nDir: %s", cwd);
}
// Function where the system command is executed
void execArgs(char** parsed)
{
// Forking a child
pid_t pid = fork();
if (pid == -1) {
printf("\nFailed forking
child..");
return;
} else if (pid == 0) {
if (execvp(parsed[0], parsed) <
0) {
printf("\nCould
not execute command..");
}
exit(0);
} else {
// waiting for child to
terminate
wait(NULL);
return;
}
}
// Function where the piped system commands is executed
void execArgsPiped(char** parsed, char** parsedpipe)
{
// 0 is read end, 1 is write end
int pipefd[2];
pid_t p1, p2;
if (pipe(pipefd) < 0) {
printf("\nPipe could not be
initialized");
return;
}
p1 = fork();
if (p1 < 0) {
printf("\nCould not fork");
return;
}
if (p1 == 0) {
// Child 1 executing..
// It only needs to write at the
write end
close(pipefd[0]);
dup2(pipefd[1],
STDOUT_FILENO);
close(pipefd[1]);
if (execvp(parsed[0], parsed)
< 0) {
printf("\nCould
not execute command 1..");
exit(0);
}
} else {
// Parent executing
p2 = fork();
if (p2 < 0) {
printf("\nCould
not fork");
return;
}
// Child 2 executing..
// It only needs to read at the
read end
if (p2 == 0) {
close(pipefd[1]);
dup2(pipefd[0],
STDIN_FILENO);
close(pipefd[0]);
if
(execvp(parsedpipe[0], parsedpipe) < 0) {
printf("\nCould not execute command 2..");
exit(0);
}
} else {
// parent
executing, waiting for two children
wait(NULL);
wait(NULL);
}
}
}
// Help command builtin
void openHelp()
{
puts("\n***WELCOME TO MY SHELL HELP***"
"\nCopyright @ Suprotik Dey"
"\n-Use the shell at your own
risk..."
"\nList of Commands
supported:"
"\n>cd"
"\n>ls"
"\n>exit"
"\n>all other general commands
available in UNIX shell"
"\n>pipe handling"
"\n>improper space
handling");
return;
}
// Function to execute builtin commands
int ownCmdHandler(char** parsed)
{
int NoOfOwnCmds = 4, i, switchOwnArg = 0;
char* ListOfOwnCmds[NoOfOwnCmds];
char* username;
ListOfOwnCmds[0] = "exit";
ListOfOwnCmds[1] = "cd";
ListOfOwnCmds[2] = "help";
ListOfOwnCmds[3] = "hello";
for (i = 0; i < NoOfOwnCmds; i++) {
if (strcmp(parsed[0],
ListOfOwnCmds[i]) == 0) {
switchOwnArg = i
+ 1;
break;
}
}
switch (switchOwnArg) {
case 1:
printf("\nGoodbye\n");
exit(0);
case 2:
chdir(parsed[1]);
return 1;
case 3:
openHelp();
return 1;
case 4:
username = getenv("USER");
printf("\nHello %s.\nMind that this
is "
"not a place to
play around."
"\nUse help to
know more..\n",
username);
return 1;
default:
break;
}
return 0;
}
// function for finding pipe
int parsePipe(char* str, char** strpiped)
{
int i;
for (i = 0; i < 2; i++) {
strpiped[i] = strsep(&str,
"|");
if (strpiped[i] == NULL)
break;
}
if (strpiped[1] == NULL)
return 0; // returns zero if no
pipe is found.
else {
return 1;
}
}
// function for parsing command words
void parseSpace(char* str, char** parsed)
{
int i;
for (i = 0; i < MAXLIST; i++) {
parsed[i] = strsep(&str, "
");
if (parsed[i] == NULL)
break;
if (strlen(parsed[i]) == 0)
i--;
}
}
int processString(char* str, char** parsed, char**
parsedpipe)
{
char* strpiped[2];
int piped = 0;
piped = parsePipe(str, strpiped);
if (piped) {
parseSpace(strpiped[0],
parsed);
parseSpace(strpiped[1],
parsedpipe);
} else {
parseSpace(str, parsed);
}
if (ownCmdHandler(parsed))
return 0;
else
return 1 + piped;
}
int main()
{
char inputString[MAXCOM], *parsedArgs[MAXLIST];
char* parsedArgsPiped[MAXLIST];
int execFlag = 0;
init_shell();
while (1) {
// print shell line
printDir();
// take input
if (takeInput(inputString))
continue;
// process
execFlag =
processString(inputString,
parsedArgs, parsedArgsPiped);
// execflag returns zero if there
is no command
// or it is a builtin
command,
// 1 if it is a simple
command
// 2 if it is including a pipe.
// execute
if (execFlag == 1)
execArgs(parsedArgs);
if (execFlag == 2)
execArgsPiped(parsedArgs, parsedArgsPiped);
}
return 0;
}
Get Answers For Free
Most questions answered within 1 hours.