arunaugustine / basic_shell

shell project for his 5k level OS class

Geek Repo:Geek Repo

Github PK Tool:Github PK Tool

Programmer: Arun Augustine

ADVANCED SHELL GOALS:

1. Redirect input or output (or both) of a command. That is, support <, > and >> similar
   to bash
2. Connect several commands using piping, i.e., support |

HOw IT'S DONE
--------------

- For redirection, if the command contains any of the special characters <, > or >>
  a FD pointing to the file specified is opened and using dup2, duplicated as STDIN 
  or STDOUT

- For connecting several commands using pipe, we consider that each command may have
  a left pipe ( a pipe to read from) or a right pipe (a pipe to write to). Using dup2
  we appropriately duplicates STDIN or STDOUT to the write/read end of these pipes. 
  The right pipe of a command becomes the left pipe of the command following it. Special
  care is taken, to close the appropriate file/pipe descriptors both in the parent and 
  child process. Also the pipe is created before forking so that both parent and child 
  inherits the pipe.

DESIGN CHOICES
--------------

- Earlier parsing was being done using strtok_r function. Since for the current project, 
  we need to support parsing based on space or any of the special characters <. >, >>, |
  a custom my_tokenize function was written to achieve this. It basically takes the input
  sting and converts it into an array of null terminated strings, which can then be parsed
  in a second pass, by appropriate functions.

- Functions to execute input and output redirections are implemented as speprate functions
  for code modularity. An execute_advanced_command calls the appropriate function for subcommands
  parsed using the | as seperator.

- A key issue to solve was to close the appropriate ends of the pipes in both child and parent 
  processes. Especially in the parent, the file descriptors needed to be closed before calling
  waitpid() to wait on the child to execute the sub command.

ARCHIVE:
--------
The readme that was part of the first part of this project is included below for reference.

BASIC_SHELL Project:
Purpose: Construct a simple shell that will execute the user commands.

HOW IT'S DONE
-------------

- In main, an infinite while loop is run, which gets user input using fgets.
- If fgets returns NULL, it means it encountered an EOF (Ctrl-D) character.
  As per requirements, we exit the shell.
- The newline character at the end of the user input is cleaned up by searching
  for it using strchr and putting a null character there instead. This is done
  to avoid complications during the lexing phase.
- strtok_r, the thread safe version of strtok is used for parsing the user input
  into tokens. Briefly for each iteration of the strtok_r the remaining string 
  after removing the current token is passed to strtok_r while checking for NULL
  and boundary condition on number of tokens.
- The exection part of the code is abstracted in execute_command function which
  is passed the array of tokens.
- In the execute_command function fork() is called.
- The parent process waits for it's child to exit
- The child process uses execvp system call to execute the command given by the
  first member of the array of tokens.
- Error cases are handled accordingly.
- To exit the shell user has to enter Ctrl-D which returns '0' since it is the
  desired mode of exit from the shell.


DESIGN CHOICES
--------------

- How to handle Ctrl-D for exiting: After deliberation between using a getchar()
  to read if a Ctrl-D is entered and using fgets(), fgets was opted for a 
  a cleaner code.

- strtok_r vs strtok: strtok_r was chosen since it was thread safe. Also for
  extendability in future.


OTHER NOTES
------------

This code is also hosted on github.com at:

git@github.com:wirelesscharlie/basic_shell.git

Goto http://help.github.com/fork-a-repo/ for finding how to fork from 
this code base.

About

shell project for his 5k level OS class


Languages

Language:C 100.0%