Skip to content
Projects
Groups
Snippets
Help
Loading...
Help
Support
Keyboard shortcuts
?
Submit feedback
Contribute to GitLab
Sign in
Toggle navigation
U
uva
Project overview
Project overview
Details
Activity
Releases
Repository
Repository
Files
Commits
Branches
Tags
Contributors
Graph
Compare
Issues
0
Issues
0
List
Boards
Labels
Milestones
Merge Requests
0
Merge Requests
0
CI / CD
CI / CD
Pipelines
Jobs
Schedules
Analytics
Analytics
CI / CD
Repository
Value Stream
Wiki
Wiki
Members
Members
Collapse sidebar
Close sidebar
Activity
Graph
Create a new issue
Jobs
Commits
Issue Boards
Open sidebar
Taddeüs Kroes
uva
Commits
92f3c076
Commit
92f3c076
authored
Jan 09, 2011
by
Sander Mathijs van Veen
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
OS: Finish shell assignment.
parent
99356bfe
Changes
3
Show whitespace changes
Inline
Side-by-side
Showing
3 changed files
with
175 additions
and
11 deletions
+175
-11
os/extra/src/input.y
os/extra/src/input.y
+4
-7
os/extra/src/main.c
os/extra/src/main.c
+46
-4
os/extra/src/report/report.tex
os/extra/src/report/report.tex
+125
-0
No files found.
os/extra/src/input.y
View file @
92f3c076
...
@@ -39,21 +39,18 @@ void yyerror(const char *str) {
...
@@ -39,21 +39,18 @@ void yyerror(const char *str) {
%%
%%
Start: Commands
Start: Commands
{ shell_exec(shell_pop_args()); }
;
;
Commands: Command
Commands: Command
| Commands EOL Command
| Commands EOL
{ shell_exec(shell_pop_args()); }
Command
| Commands '|' { shell_pipe(); } Command
| Commands '|' { shell_pipe();
shell_exec(shell_pop_args());
} Command
;
;
Command: /* Empty */
Command: /* Empty */
| Builtin
| Builtin
| IDENTIFIER { shell_push_args($1); }
| IDENTIFIER { shell_push_args($1); }
{ shell_exec(shell_pop_args()); }
| IDENTIFIER { shell_push_args($1); } Arguments;
| IDENTIFIER { shell_push_args($1); }
Arguments { shell_exec(shell_pop_args()); }
;
Builtin: EXIT { shell_exit(); }
Builtin: EXIT { shell_exit(); }
| HELP { shell_help(); }
| HELP { shell_help(); }
...
...
os/extra/src/main.c
View file @
92f3c076
...
@@ -137,16 +137,27 @@ void shell_append_args(const char *value) {
...
@@ -137,16 +137,27 @@ void shell_append_args(const char *value) {
}
}
shell_args
*
shell_pop_args
()
{
shell_args
*
shell_pop_args
()
{
if
(
!
last_arg
)
return
NULL
;
assert
(
cmd_args
&&
last_arg
!=
NULL
);
assert
(
cmd_args
&&
last_arg
!=
NULL
);
shell_args
*
args
=
cmd_args
;
shell_args
*
args
=
cmd_args
;
cmd_args
=
last_arg
=
NULL
;
cmd_args
=
last_arg
=
NULL
;
return
args
;
return
args
;
}
}
int
command_has_pipe
=
0
;
void
shell_pipe
()
{
shell_debug
(
"start pipe"
);
command_has_pipe
=
1
;
}
/*
/*
* Execute the binary and its parsed arguments.
* Execute the binary and its parsed arguments.
*/
*/
void
shell_exec
(
shell_args
*
args
)
{
void
shell_exec
(
shell_args
*
args
)
{
if
(
!
args
)
return
;
assert
(
args
&&
args
->
arg
);
assert
(
args
&&
args
->
arg
);
shell_debug
(
"exec `%s'"
,
args
->
arg
);
shell_debug
(
"exec `%s'"
,
args
->
arg
);
...
@@ -157,6 +168,17 @@ void shell_exec(shell_args *args) {
...
@@ -157,6 +168,17 @@ void shell_exec(shell_args *args) {
cur
=
cur
->
next
;
cur
=
cur
->
next
;
}
}
int
pipes
[
2
];
int
has_pipe
=
0
;
if
(
command_has_pipe
)
{
pipe
(
pipes
);
has_pipe
=
1
;
}
// Disable pipe flag
command_has_pipe
=
0
;
// Fork the process and handle forking error.
// Fork the process and handle forking error.
pid_t
pid
=
fork
();
pid_t
pid
=
fork
();
switch
(
pid
)
{
switch
(
pid
)
{
...
@@ -165,10 +187,26 @@ void shell_exec(shell_args *args) {
...
@@ -165,10 +187,26 @@ void shell_exec(shell_args *args) {
exit
(
EXIT_FAILURE
);
exit
(
EXIT_FAILURE
);
case
0
:
case
0
:
shell_debug
(
"Child process #%d is ready."
,
getpid
());
shell_debug
(
"Child process #%d is ready."
,
getpid
());
if
(
has_pipe
)
{
if
(
dup2
(
pipes
[
1
],
1
)
!=
1
)
perror
(
"Pipe redirection output error"
);
close
(
pipes
[
0
]);
close
(
pipes
[
1
]);
}
shell_exec_process
(
args
);
shell_exec_process
(
args
);
break
;
break
;
default:
default:
shell_debug
(
"Parent launched child process #%d."
,
pid
);
shell_debug
(
"Parent launched child process #%d."
,
pid
);
if
(
has_pipe
)
{
if
(
dup2
(
pipes
[
0
],
0
)
!=
0
)
perror
(
"Pipe redirection input error"
);
close
(
pipes
[
0
]);
close
(
pipes
[
1
]);
waitpid
(
pid
,
NULL
,
0
);
}
shell_history_append
(
FN_EXEC
,
args
);
shell_history_append
(
FN_EXEC
,
args
);
}
}
}
}
...
@@ -280,10 +318,6 @@ void shell_exec_process(shell_args *args) {
...
@@ -280,10 +318,6 @@ void shell_exec_process(shell_args *args) {
}
}
}
}
void
shell_pipe
()
{
shell_debug
(
"start pipe"
);
}
/*
/*
* Gracefully exit the shell.
* Gracefully exit the shell.
*/
*/
...
@@ -374,6 +408,9 @@ void shell_entry() {
...
@@ -374,6 +408,9 @@ void shell_entry() {
fflush
(
stdout
);
fflush
(
stdout
);
}
}
/*
* Doubly linked list containing the command history of this shell.
*/
shell_history_log
*
shell_history
=
NULL
;
shell_history_log
*
shell_history
=
NULL
;
int
shell_history_count
=
0
;
int
shell_history_count
=
0
;
...
@@ -429,6 +466,9 @@ void shell_history_append(shell_func type, shell_args *args) {
...
@@ -429,6 +466,9 @@ void shell_history_append(shell_func type, shell_args *args) {
shell_history_add
(
cmd
);
shell_history_add
(
cmd
);
}
}
/*
* Implementation of the repeat builtin shell command.
*/
void
shell_repeat
(
int
prev
)
{
void
shell_repeat
(
int
prev
)
{
shell_debug
(
"repeat %d"
,
prev
);
shell_debug
(
"repeat %d"
,
prev
);
...
@@ -441,6 +481,8 @@ void shell_repeat(int prev) {
...
@@ -441,6 +481,8 @@ void shell_repeat(int prev) {
return
;
return
;
}
}
// TODO: execute `cmd'
shell_history_add
(
cmd
);
shell_history_add
(
cmd
);
}
}
...
...
os/extra/src/report/report.tex
0 → 100644
View file @
92f3c076
\documentclass
[10pt,a4paper]
{
article
}
\usepackage
[utf8]
{
inputenc
}
\usepackage
{
enumerate
}
\usepackage
{
listings
}
\usepackage
{
url
}
\usepackage
{
float
}
\usepackage
[toc,page]
{
appendix
}
\usepackage
[dutch]
{
babel
}
\usepackage
{
listings
}
\title
{
Operating systems opdracht extra: Shell
}
\author
{
Sander van Veen
\&
Tadde
\"
us Kroes
\\
6167969
\&
6054129
\\
\url
{
sandervv@gmail.com
}
\&
\url
{
taddeuskroes@hotmail.com
}
}
\begin{document}
\maketitle
\tableofcontents
\pagebreak
\section
{
Parser van de command shell
}
Voor het bouwen van deze command shell hebben we Flex en Bison gebruikt. Dit
zijn tools voor het maken van lexer resp. een parser. Bison gebruikt een
\texttt
{
.y
}
-bestand waar context vrije grammatica (in BNF-vorm) in staat en dat
maakt het mogelijk om de parser van de main code te scheiden. Het gebruik van
deze tools neemt een deel van het schrijven van de parser uit handen. Het is
minder foutgevoeling dan de parser volledig in C schrijven, mede doordat een
Bison-bestand overzichtelijker en gemakkelijker te onderhouden is. Flex
gebruikt het bestand
\texttt
{
input.l
}
om een lexer te bouwen. Als de
\texttt
{
main()
}
van de shell wordt uitgevoerd, dan roepen we
\texttt
{
yyparse()
}
aan. Dat start de parser van de shell input (en in feite dus ook de lexer).
\section
{
Werkende deel
}
Door de projectweek is het niet meer gelukt om de complete shell af te krijgen.
Op dit moment werkt het parsen van de invoer, het veranderen van working
directory (
\texttt
{
cd PATH
}
) en het sluiten van een shell (
\texttt
{
exit
}
).
Daarnaast kunnen commando's worden uitgevoerd (
\texttt
{
pwd
}
), maar er is een
fout in de signal handler, waardoor de shell termineert na het uitvoeren van het
commando. Er wordt een SIGCHLD naar het ``parent process'' van het geforkte
process gestuurd en dan termineert de shell doordat de lexer niet meer van stdin
kan lezen.
De parser zet de commando's om in een singly linked list van strings. Dus het
commando
\texttt
{
cat input.l
}
wordt opgesplitst in twee strings en opgeslagen
als een list. Deze list wordt na het uitvoeren van het commmando aan
\texttt
{
shell
\_
history
}
toegevoegd. Dit maakt het mogelijk om via
\texttt
{
!!
}
en
\texttt
{
!N
}
(met
$
N
$
een geheel getal, groter dan nul) een commando te
herhalen. Met de huidige parser en lexer is het ook erg gemakkelijk om een
\texttt
{
.
}
of
\texttt
{
source
}
builtin te implementeren. Flex werkt kan meerdere
bestanden openen en elke keer dat een bestand wordt geopend de stack met input
bestanden eentje ophogen. Door deze input stack is recursie mogelijk. Een
voorbeeld van een
\texttt
{
input.l
}
bestand met
\texttt
{
source
}
zou dan zijn:
\begin{verbatim}
/* "incl" state is used for picking up the name of an include file */
%x incl
%{
#define MAX
_
INCLUDE
_
DEPTH 10
YY
_
BUFFER
_
STATE include
_
stack[MAX
_
INCLUDE
_
DEPTH];
int include
_
stack
_
ptr = 0;
%}
%%
\.
|source BEGIN(incl);
[a-z]+ ECHO;
[
^
a-z
\n
]*
\n
? ECHO;
<incl>[
\t
]* /* eat the whitespace */
<incl>[
^
\t\n
]+
{
/* got the include file name */
if( include
_
stack
_
ptr >= MAX
_
INCLUDE
_
DEPTH )
{
fprintf( stderr, "Includes nested too deeply" );
exit( 1 );
}
include
_
stack[include
_
stack
_
ptr++] =
YY
_
CURRENT
_
BUFFER;
yyin = fopen( yytext, "r" );
if ( ! yyin )
error( ... );
yy
_
switch
_
to
_
buffer(
yy
_
create
_
buffer(yyin, YY
_
BUF
_
SIZE ));
BEGIN(INITIAL);
}
<<EOF>>
{
if( --include
_
stack
_
ptr )
{
yy
_
delete
_
buffer(YY
_
CURRENT
_
BUFFER);
yy
_
switch
_
to
_
buffer(include
_
stack[include
_
stack
_
ptr]);
}
else
yyterminate();
}
\end{verbatim}
Het detecteren van de pipe (om aan te geven dat twee commando's aan elkaar
moeten wordne gekoppeld) werkt, maar doordat de shell termineert door de lexer,
blijft er weinig nut over van de pipe.
\section
{
Conclusie
}
% {{{
\label
{
sec:Conclusie
}
Na 900 regels code is het niet gelukt om de gehele shell af te maken. De shell
is wel gestructureerd opgezet waardoor het gemakkelijk is om door anderen te
gebruiken als basis voor een eigen shell. Naast het bouwen van de shell hebben
we onze C vaardigheden verbeterd door een eigen printf te maken
(
\texttt
{
shell
\_
debug
}
). Dit is een variadic function, wat wil zeggen dat het
een variable aantal argumenten gebruikt. Wij hebben het aantal arguments
afgeleid uit het aantal
\texttt
{
\%
}
van het eerste argument.
% }}}
\end{document}
Write
Preview
Markdown
is supported
0%
Try again
or
attach a new file
Attach a file
Cancel
You are about to add
0
people
to the discussion. Proceed with caution.
Finish editing this message first!
Cancel
Please
register
or
sign in
to comment