-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathREADME
91 lines (69 loc) · 3.73 KB
/
README
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
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:
[email protected]:wirelesscharlie/basic_shell.git
Goto http://help.github.com/fork-a-repo/ for finding how to fork from
this code base.