-
Notifications
You must be signed in to change notification settings - Fork 2
Expand file tree
/
Copy pathREADME
More file actions
225 lines (170 loc) · 6.17 KB
/
README
File metadata and controls
225 lines (170 loc) · 6.17 KB
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
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
created by zen
http://zeng.photography
OVERVIEW
An experimental Unix shell as the assignment of Operating System Fall 2014, supporting basic shell commands and job control. The main code is written using C, while using Lex as the lexical analyzer, and lemon as the parser.
INSTALL
to launch the program:
./shell
to compile the program from sources:
make
other commands avalable for make:
make clean
GRAMMAR
The program supports basic shell commands.
accept := command ( < argument ) ( PIPE"|" command )* ( > argument ) ( & )
accept := command > argument < argument ( & )
command := ( argument )+
argument := ( ^ \t \n \r \< \> \" \' )+
The program supports some basic shell build-in command;
However the usage and function may differ from those in standard shells. They are:
cd
jobs
fg
bg
exit
quit
The program also responses to control signals. When launched foreground as a terminal-shell, the program ignore most of the signal calls, except:
ctrl+C as SIGIN
throw current input and start waiting a new command
ctrl+D as SIGQUIT
exit the program
JOB CONTROL
The program supports basic job control.
The command jobs is used to diplay all non-terminated jobs, running or stopped. The arguments to this command may be the indicator of job id.
shell: job
return a list of all current non-terminated jobs
[id] group_id Current_state(Running or stopped)
[id] group_id Current_state(Running or stopped)
...
shell: job x y ... z
return a list of non-terminated jobs with indicator x, y ... z
[x] group_id Current_state(Running or stopped)
[y] group_id Current_state(Running or stopped)
...
The command fg is used to resume stopped job and take it to the foreground.
The argument to this command may be the indicator of job id.
shell: fg
resume the last-lauched stopped job
shell: fg x y ... z
resume the stopped job with indicator x, y .. z
The command bg does the same as fg, except it puts jobs to the background.
PRGRAM STRUCTURE
the main program is structured as the following:
/* the program */
int main()
{
/* init parameters & variables */
init();
while(/* no QUIT or EOF signal recieved */)
{
/* parse the commands from input, build the data of jobs and process to launch */
parser();
/* run the command by launching jobs and process */
launch_jobs();
/* collect and inform user information of launched jobs; take completed jobs offline */
notifications();
}
/* destroy resources used; collect information left by completed processes */
exit_program();
}
the detailed approach of initial the shell is the following:
init()
{
if(/* the shell is interactive */)
{
if(/* if the shell is run by another shell and in background */)
{
/* stop itself in case of error job control */
stop();
}
/* ignore most of control signals, except deal with special case of ctrl+C, and let go termination calls */
signal(SIGIN, another_line);
signal(SIGHLD, DFT);
signal(OTHER, IGN);
/* Grab control of the terminal */
get_to_stdin();
}
}
the detailed approach of launch a job is the following:
launch_job (job j)
{
/* open the redirected file and pase the descriptor to the following function */
file();
for (/* every process pi in the pipline */)
{
/* for every two adjacent processes in the pipline, create a pipe */
pipe();
/* fork before each non-build in command (process) is executed */
fork();
/* launch each process, set each process the same group id */
launch_process (process pi, id group_id, process_std_input, process_std_output);
/* wait for the process to complete, method depending on if it runs foreground */
wait();
}
}
the detailed approach of launch a process is the following:
/* the function is called in the forked child process */
launch_process (process pi, id group_id, process_std_input, process_std_output)
{
/* set child process signal handling to default */
signal();
/* handle file redirection */
dup();
/* launch the process */
exec(process);
}
the detailed approach of collect information from processes is the following:
notification()
{
/* collect information from completed processed since last time */
wait();
update_states(active_job_list);
/* inform the user when some job is finished */
inform();
/* remove jobs already complete from active list and free memory used for storing the command data */
update(active_job_list);
clean();
}
the detailed approach of exit is the following:
exit_program()
{
/* collect return information of all terminated child process since last time */
wait();
/* destroy data */
free();
}
DATA STRUCTURE
/* A process is a single process. */
typedef struct process
{
struct process *next; /* next process in pipeline */
char **argv; /* for exec */
pid_t pid; /* process ID */
char completed; /* true if process has completed */
char stopped; /* true if process has stopped */
int status; /* reported status value */
} process;
/* A job is a pipeline of processes. */
typedef struct job
{
struct job *next; /* next active job */
int id; /* id of the process; 0 if is build in */
int valid; /* true if the job is valid to launch */
process *first_process; /* list of processes in this job */
pid_t pgid; /* process group ID */
char notified; /* true if user told about stopped job */
struct termios tmodes; /* saved terminal modes */
char* infile; /* redirected input file name */
char* outfile; /* redirected output file name */
int stdin, stdout, stderr; /* standard i/o channels */
int foreground; /* true if the job runs foreground */
} job;
REFERENCE
[ The GNU C Library ]: http://www.gnu.org/software/libc/manual/html_node/
[ Lex ]: http://dinosaur.compilertools.net/lex/
[ Lemon ]: http://www.hwaci.com/sw/lemon/
[ Assiment Page ]: https://202.120.38.39/~jzhou/courses/F14.OS/hw1-shell.html
[ Github Page ]: https://github.com/ImaginationZ/Shell
LICENSE
GNU GENERAL PUBLIC LICENSE v2.0
feel free to copy or modify codes