Compile and run a c program for a custom-shell


Shell Program - Write, compile, and run a C program for a custom-shell.

Part 1: Command Parsing (and print its components correctly).

  • Your shell should be able to parse the command from user.
  • Assume my home directory is: /home/richard or you may use.

Examples (You may create your own output format or template to show the command(s) being parsed.)

1. One command with arguments and options. 

For example, ls –la  /home/richard

Command: ls
Options: -la
Arguments: /home/richard

2. Two commands with 1 pipe. 

For example, ls –la  /home/richard

Command: la
Options: -la
Arguments: /home/richard
For example, ls | wc –l should be parsed and display
Command: ls
Pipe
Command: wc –l

3. Two commands with semicolon. For example, ls ;  date

4. One command with IO redirection symbol (<, >, >>)

For example, ls  <  junk.txt  >  output.txt
Command: ls
File Redirection: <
File: junk.txt
File Redirection: >
File: output.txt

5. Three commands or more commands with pipe (and with other symbols). For example

ls –l | grep *.txt | wc –l
ls –l | grep *.txt | wc –l | ls > junk.txt

Part 2: File Redirection. >, <, >> with a single command using fork/exec, dup/dup2, and/or pipe

For example,

ls > output.txt

ls >> output.txt

sort < output.txt

You may use the code segment of the following program(s) for this part.

// For Part2 – simple command shell (for a single command).

// Note: For Part1 you may begin with the following simple shell program.

/*

 * World's simplest shell. Loops, reads input and tries to execute it.

 * Note: no tokenization, can be ^C'd, but does look at PATH not sorted

 * ./simple-shell

 * $$ ls

 * $$ ^C

 */

#include

#include

#include

#include

#include

#include

#include

#include

char *

getinput(char *buffer, size_t buflen) {

printf("$$ ");

return fgets(buffer, buflen, stdin);

}

int

main(int argc, char **argv) {

char buf[1024];

pid_t pid;

int status;

while (getinput(buf, sizeof(buf))) {

            // parent is waiting

buf[strlen(buf) - 1] = '\0';

if((pid=fork()) == -1) { 

fprintf(stderr, "shell: can't fork: %s\n",

continue;

} else if (pid == 0) {  

/* child to run the command */

/* your code to parse the command & set any file redirection as needed */

execlp(buf, buf, (char *)0);

fprintf(stderr, "shell: couldn't exec %s: %s\n", buf,

exit(EX_DATAERR);

}

if ((pid=waitpid(pid, &status, 0)) < 0)

fprintf(stderr, "shell: waitpid error: %s\n",

strerror(errno));

strerror(errno));

strerror(errno));

}

exit(EX_OK);

}
 

/* program code 2 - a sample code for output redirection */

#include

#include

#include

#include

#include

#include

#include

#include

#include

int main(int argc, char **argv)

{

int pid, status;

int fdout;                /* file descriptor for output */

char *command[] = { "ls", "-l", ">", "output.txt" };

if ((fdout = open(command[3], O_CREAT|O_TRUNC|O_WRONLY, 0644)) < 0) {

}

printf("writing output of the command %s to \"%s\"\n", command[0], command[3]);

dup2(fdout, 1);

execlp(command[0], command[0], command[1], (char *)0);

perror(command[0]); /* execvp failed */

exit(1);

}

perror(command[3]); /* open failed */

exit(1);


Part 3: Implement a shell (using fork, pipe, dup/dup2, exec) for a single command (Part 1), two commands, and then

(1) Handle two commands with fork, pipe, dup/dup2.

ls -l | wc -l

Given a command from user, it forks a child process to execute the command while parent waits. When it is done, parent process wakes up and prints prompt for next command.

Syntax: command [options] | command [options]

Test line:  ls -sF | wc -l

You may use the code segment (as an example) from the following sample program.

/* implementing  "/bin/ps -ef | /bin/more" */

#include

#include

#include

#include

int main()

{

  int fds[2];

  int child[2];

  char *argv[3];

  pipe(fds);

  if (fork()== 0)

  {

    close(fds[1]);

    close(STDIN_FILENO); dup(fds[0]);

          /* redirect standard input to fds[0] */

    argv[0] = "/bin/more";

    argv[1] = NULL;          

    execv(argv[0], argv);

    exit(-1);

  }

  if (fork() == 0)

  {

    close(fds[0]);

    close(STDOUT_FILENO); dup(fds[1]); 

    argv[0] = "/bin/ps";

    argv[1] = "-ef"; argv[2] = NULL;

    execv(argv[0], argv);

    exit(-2);

  }

  close(fds[0]); close(fds[1]);

  wait(child);

  wait(child+1);

  return 0;

}

multiple commands

ls -l | wc -l


(2) Handle multiple-commands with pipe
 e.g., ls -l | sort | head

(3) Handle multiple-commands with pipe, and file redirection

e.g., ls -l | sort | head > output.txt

e.g., cat < output.txt | grep ".c" | head > list.txt

Part 4: Send a command via socket program to be run a "ls -l" command, and echo its result back to the sender.

Implement a server to listen port (nnnnn) for any incoming ls command to be run and to output its result back to the sender. The client sends a command (e.g., ls –l) to the server and receive the result to be output to the console. You may modify the sample programs (for echo server/client or time server/client) for your base code to be modified.

Warning and Caution. Your server's listening port must be free (not taken by someone else) and pick one between 40000 and 64000. If it is taken, your server should use another port available, to be connected by your client. Do not use any port being used by someone else for server to bind and for client to connect (to someone's server, not yours).

Request for Solution File

Ask an Expert for Answer!!
C/C++ Programming: Compile and run a c program for a custom-shell
Reference No:- TGS01238301

Expected delivery within 24 Hours