Answered You can hire a professional tutor to get the answer.
Simple Shell Background In this project, you will implement a command line interpreter or shell in C language . The shell should operate in this...
Need help to with my initial code below:
Simple Shell
Background
In this project, you will implement a command line interpreter or shell in C language. The shell should operate
in this basic way: when you type in a command (in response to its prompt), the shell creates a
child process that executes the command you entered and then prompts for more user input when
it has finished.
The shell you implement will be similar to, but much simpler than, the one you run every day in
Unix. You can find out which shell you are running by typing echo $SHELL at a prompt. You
may then wish to look at the man pages for the shell you are running (most likely bash) to learn
more about its functionalities. For this project, you need to implement only some as specified
below.
Part 1: The Simple Shell
1. Your shell executable should be named mysh. Your shell source code should be in
mysh.c,
2. The shell should run continuously, and display a prompt when waiting for input.
The prompt should be EXACTLY '$'. No spaces, no extra characters. Example with a
command:
$/bin/ls -l
3. Your shell should read a line from stdin one at a time. This line should be parsed out
into a command and all its arguments. In other words, tokenize it.
o You may assume that the only supported delimiter is the whitespace character
(ASCII character number 32).
o You do not need to handle "special" characters. Do not worry about handling
quotation marks, backslashes, and tab characters. This means your shell will be
unable to support arguments with spaces in them. For example, your shell will not
support file paths with spaces in them.
o You may set a reasonable maximum on the number of command line arguments,
but your shell should handle input lines of any length.
4. After parsing the command, your shell should execute it. A command can either be a
reference to an executable OR a built-in shell command (see Part 2). For Part 1, just focus
on running executables, and not on built-in commands.
o Executing commands that are not shell built-ins and are just the executable name
(and not a full path to the executable) is done by invoking fork() and then
invoking exec().
o You may NOT use the system() function, as it just invokes the /bin/sh shell to
do all the work.
Part 2: Implement Built-in Commands: exit, cd, history
• exit - Simply exits your shell after performing any necessary clean up.
• cd [dir] - Short for "change directory", and will be used to change the current working
directory of your shell. Do not worry about implementing the command line options that
the real cd command has in Bash. Just implement cd such that it takes a single command
line parameter: The directory to change to.
• history [-c] [offset] - Similar to the Bash built-in history command, but much
simpler.
o history (without arguments) displays the last 100 commands the user ran, with
an offset next to each command. The offset is the index of the command in the
list, and valid values are 0 to 99, inclusive. 0 is the oldest command. Do not worry
about persisting this list to a file; just store it in memory. Once more than 100
commands are executed, remove the oldest entry from the list to make room for
the newer commands. Note that history is also a command itself and therefore
should also appear in the list of commands. If the user ran invalid commands,
those should also appear in the list.
o history -c clears the entire history, removing all entries. For example, running
history immediately after history -c should show history as the sole entry in
the list.
o history [offset] executes the command in history at the given offset. Print an
error message of your choosing if the offset is not valid.
o Example output for built-in history:
o $cd /home/w4118
o $/bin/ls
o my_file.txt
o $history
o 0 cd /home/w4118
o 1 /bin/ls
o 2 history
o $history 1
o my_file.txt
o $history
o 0 cd /home/w4118
o 1 /bin/ls
o 2 history
o 3 history 1
o 4 history
o $history -c
o $history
o 0 history
$
Part 3: Pipes
• Augment your shell to be capable of executing a sequence of programs that communicate
through a pipe. For example, if the user types /bin/ls | /usr/bin/wc, your program
should fork the two programs, which together will calculate the number of files in the
directory. For this you will need to replace stdin and stdout with pipe file descriptors
using dup2.
• While this example shows two processes communicating through a pipe, your shell
should support pipes between multiple processes, not just two.
• You need not support built-in commands to work with pipes.
Other Requirements
Error handling is an important concept in operating systems: an OS can't simply fail when it
encounters an error; it must check all parameters before it trusts them. In general, there should be
no circumstances in which your C program will core dump, hang indefinitely, or prematurely
terminate. Therefore, your program must respond to all input in a reasonable manner; by
"reasonable", we mean print an understandable error message and either continue processing or
exit, depending upon the situation.
So, check the input for errors. Check the return values of function calls. Display appropriate error
messages..
HERE is MY INITIAL CODE:
-------------------------------------------------------------------------------------------------------------------------------
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <errno.h>
#include <unistd.h>
#include <sys/types.h>
#include <sys/wait.h>
#define MAX 1024
#define DELIMS " trn"
int main(int argc, char *argv[]) {
char *cmd;
char cmd_line[MAX];
while (1) {
printf("$");
if (!fgets(cmd_line, MAX, stdin)) break;
argv[0] = cmd_line;
if ((cmd = strtok(cmd_line, DELIMS))) { //exicution of command
errno = 0;
if(fork() == 0) {
if (strcmp(cmd, "cd") == 0) {
char *arg = strtok(0, DELIMS);
if (!arg)
fprintf(stderr, "cd missing argument.n");
else
chdir(arg);
} else if (strcmp(cmd, "exit") == 0) { //if exit break loop and come out
exit(0); //exit fork
break;
}
else {
execvp(argv[0],argv); //exicute command
}
exit(0); //exit child
}
else
{
wait(0); //wait until child complite it exicution
}
if (errno) //if there is error print command faild
perror("Command failed");
}
}
return 0;
}