Can someon test/read this code if it meets the 3 Partrequirements below.?

if it doesn’t plsss make it so..


#include <stdio.h>

#include <stdlib.h>

#include <string.h>

#include <ctype.h>

#include <unistd.h>

#include <sys/types.h>

#include <sys/wait.h>

/* The array below will hold the arguments: args[0] is thecommand. */

static char* args[512];

pid_t pid;

int command_pipe[2];

#define READ 0

#define WRITE 1


* Handle commands separatly

* input: return value from previous command (useful for pipefile descriptor)

* first: 1 if first command in pipe-sequence (no input fromprevious pipe)

* last: 1 if last command in pipe-sequence (no input fromprevious pipe)


* EXAMPLE: If you type “ls | grep shell | wc” in your shell:

* fd1 = command(0, 1, 0), with args[0] = “ls”

* fd2 = command(fd1, 0, 0), with args[0] = “grep” and args[1] =”shell”

* fd3 = command(fd2, 0, 1), with args[0] = “wc”


* So if ‘command’ returns a file descriptor, the next ‘command’has this

* descriptor as its ‘input’.


static int command(int input, int first, int last)


int pipettes[2];

/* Invoke pipe */

pipe( pipettes );

pid = fork();



STDIN –> O –> O –> O –> STDOUT


if (pid == 0) {

if (first == 1 && last == 0 && input == 0) {

// First command

dup2( pipettes[WRITE], STDOUT_FILENO );

} else if (first == 0 && last == 0 && input !=0) {

// Middle command

dup2(input, STDIN_FILENO);

dup2(pipettes[WRITE], STDOUT_FILENO);

} else {

// Last command

dup2( input, STDIN_FILENO );


if (execvp( args[0], args) == -1)

_exit(EXIT_FAILURE); // If child fails


if (input != 0)


// Nothing more needs to be written


// If it’s the last command, nothing more needs to be read

if (last == 1)


return pipettes[READ];


/* Final cleanup, ‘wait’ for processes to terminate.

* n : Number of times ‘command’ was invoked.


static void cleanup(int n)


int i;

for (i = 0; i < n; ++i)



static int run(char* cmd, int input, int first, int last);

static char line[1024];

static int n = 0; /* number of calls to ‘command’ */

int main()


printf(“SIMPLE SHELL: Type ‘exit’ or send EOF to exit.n”);

while (1) {

/* Print the command prompt */

printf(“$> “);


/* Read a command line */

if (!fgets(line, 1024, stdin))

return 0;

int input = 0;

int first = 1;

char* cmd = line;

char* next = strchr(cmd, ‘|’); /* Find first ‘|’ */

while (next != NULL) {

/* ‘next’ points to ‘|’ */

*next = ‘ ‘;

input = run(cmd, input, first, 0);

cmd = next + 1;

next = strchr(cmd, ‘|’); /* Find next ‘|’ */

first = 0;


input = run(cmd, input, first, 1);


n = 0;


return 0;


static void split(char* cmd);

static int run(char* cmd, int input, int first, int last)



if (args[0] != NULL) {

if (strcmp(args[0], “exit”) == 0)


n += 1;

return command(input, first, last);


return 0;


static char* skipwhite(char* s)


while (isspace(*s)) ++s;

return s;


static void split(char* cmd)


cmd = skipwhite(cmd);

char* next = strchr(cmd, ‘ ‘);

int i = 0;

while(next != NULL) {

next[0] = ‘ ‘;

args[i] = cmd;


cmd = skipwhite(next + 1);

next = strchr(cmd, ‘ ‘);


if (cmd[0] != ‘ ‘) {

args[i] = cmd;

next = strchr(cmd, ‘n’);

next[0] = ‘ ‘;



args[i] = NULL;



Simple Shell
In this project, you will implement a command line interpreter orshell in C language. The shell shouldoperate
in this basic way: when you type in a command (in response to itsprompt), the shell creates a
child process that executes the command you entered and thenprompts 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 arerunning (most likely bash) to learn
more about its functionalities. For this project, you need toimplement only some as specified

Part 1: The Simple Shell
1. Your shell executable should be named mysh.Your shell source code should be in
2. The shell should run continuously, and display a prompt whenwaiting for input.
The prompt should be EXACTLY ‘$’. No spaces, no extra characters.Example with a
$/bin/ls -l
3. Your shell should read a line from stdin one at a time. Thisline should be parsed out
into a command and all its arguments. In other words, tokenizeit.
o You may assume that the only supported delimiter is thewhitespace character
(ASCII character number 32).
o You do not need to handle “special” characters. Do not worryabout handling
quotation marks, backslashes, and tab characters. This means yourshell will be
unable to support arguments with spaces in them. For example, yourshell will not
support file paths with spaces in them.
o You may set a reasonable maximum on the number of command linearguments,
but your shell should handle input lines of any length.
4. After parsing the command, your shell should execute it. Acommand can either be a
reference to an executable OR a built-in shell command (see Part2). 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 theexecutable 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 necessaryclean up.
• cd [dir] – Short for “change directory”, and will be used tochange the current working
directory of your shell. Do not worry about implementing thecommand line options that
the real cd command has in Bash. Just implement cd such that ittakes a single command
line parameter: The directory to change to.
• history [-c] [offset] – Similar to the Bash built-in historycommand, but much
o history (without arguments) displays the last 100 commands theuser ran, with
an offset next to each command. The offset is the index of thecommand in the
list, and valid values are 0 to 99, inclusive. 0 is the oldestcommand. Do not worry
about persisting this list to a file; just store it in memory. Oncemore than 100
commands are executed, remove the oldest entry from the list tomake room for
the newer commands. Note that history is also a command itself andtherefore
should also appear in the list of commands. If the user ran invalidcommands,
those should also appear in the list.
o history -c clears the entire history, removing all entries. Forexample, running
history immediately after history -c should show history as thesole entry in
the list.
o history [offset] executes the command in history at the givenoffset. 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 ofprograms 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 thenumber of files in the
directory. For this you will need to replace stdin and stdout withpipe file descriptors
using dup2.
• While this example shows two processes communicating through apipe, your shell
should support pipes between multiple processes, not justtwo.
• You need not support built-in commands to work with pipes.

Other Requirements
Error handling is an important concept in operating systems: an OScan’t simply fail when it
encounters an error; it must check all parameters before it truststhem. In general, there should be
no circumstances in which your C program will core dump, hangindefinitely, or prematurely
terminate. Therefore, your program must respond to all input in areasonable manner; by
“reasonable”, we mean print an understandable error message andeither continue processing or
exit, depending upon the situation.
So, check the input for errors. Check the return values of functioncalls. Display appropriate error