Skip to content

Commit de4c98b

Browse files
committed
Added details to the assignment file.
1 parent bbea83e commit de4c98b

File tree

1 file changed

+135
-32
lines changed

1 file changed

+135
-32
lines changed

docs/class-assignments/labs-assignment-2018.txt

Lines changed: 135 additions & 32 deletions
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,11 @@ Labs Assignment for 2018 - Simple Shell
22
=======================================
33
Write a simple Unix/Linux shell.
44

5+
Updates:
6+
7+
- [Nov 12, 2018] added redirection and pipe details, new paragraph
8+
"PROHIBITED FUNCTIONS", and limiting the language to C (i.e. no C++).
9+
510
When you are done, we prefer to get a link to you github project but you
611
can send it to us via email (a single tar file) as well. Your project
712
must provide a Makefile so that running the "make" command does build
@@ -20,43 +25,68 @@ The deadlines are hard requirements, please stick to the schedule.
2025
Obviously, you can send us the whole thing in one step before the first
2126
deadline, no need to separate the project in two parts.
2227

23-
If in doubt, please ask a question.
28+
If in doubt, please ask a question, and we strongly prefer you send it
29+
to the class mailing list, nswi015-l@mff.cuni.cz, so that others may
30+
benefit from the answers as well.
2431

2532
C Style
2633
-------
2734
Please choose a good C style, for example http://mff.devnull.cz/cstyle/,
2835
or pick another existing cstyle (e.g. https://man.openbsd.org/style).
2936
Please do not invent your own C style.
3037

38+
This class is about Unix/Linux programming in C, so we only accept the C
39+
language, not C++.
40+
3141
Implementation notes
3242
--------------------
3343
We are interested in you dealing with the Unix/Linux stuff you learn in
3444
the class, so please do not spend time writing a linked list
3545
implementation or a command line parser (the latter is much harder that
3646
one might think).
3747

38-
For getting the input line, we recommend the readline library, see "man
39-
readline". You should find it on any Linux, *BSD, MacOS, or Solaris
40-
machine. By using readline, you get line editing, history, completion,
41-
etc. for free. Another alternative is libtecla.
48+
For getting the input line, we recommend the "readline" library, see
49+
"man readline". You should find it on any Linux, *BSD, MacOS, or
50+
Solaris machine. By using readline, you get line editing, history,
51+
completion, etc. for free. Another alternative is libtecla.
4252

4353
For tokenizing and parsing the command line, we suggest you to use
4454
GNU flex(1) and bison(1). They are easy to use and you should also find
4555
it virtually everywhere, already installed. We recommend O'Reilly's
46-
book "flex & bison", having read through the first 30 pages should be
47-
all you need for this project. I believe you can find the book online.
56+
book "flex & bison". Having read through the first 30 pages of the book
57+
should be all you need for this project. I believe you can find the
58+
book online.
4859

49-
You will probably need a linked list implementation. We suggest you to
50-
use macros from <queue.h>. See "man queue" for more information.
51-
STAIL_* macros should be all you need.
60+
You will probably need a linked list implementation as using fixed sized
61+
arrays would not suffice. We suggest you to use macros from <queue.h>.
62+
See "man queue" for more information. STAIL_* and TAIL_* macros should
63+
be all you need.
5264

5365
FYI, our implementation of the complete 1st phase is 560 lines long,
5466
including flex and bison source files, and using the usual C style from
5567
http://mff.devnull.cz/cstyle/.
5668

57-
It goes without saying it is an individual, not a team project. Do not
58-
use code written by other fellow students. The idea is you learn by
59-
coding your own project.
69+
IT GOES WITHOUT SAYING IT IS AN INDIVIDUAL, NOT A TEAM PROJECT. DO NOT
70+
USE CODE WRITTEN BY OTHER FELLOW STUDENTS. THE IDEA IS YOU LEARN BY
71+
CODING YOUR OWN PROJECT.
72+
73+
PROHIBITED FUNCTIONS
74+
--------------------
75+
Family of fopen() functions et al are prohibited. Instead use functions
76+
from the printf(3) family, read(2), write(2), etc.
77+
78+
popen(3), system(3), and similar functions that fork() INSIDE are
79+
strictly prohibited. The only way to create a new process for you is to
80+
use fork(2).
81+
82+
You must NOT exec any shell from your code. I.e. if you have a pipeline
83+
"cat /etc/passwd | wc -l", the solution is not the following:
84+
85+
if (fork() == 0)
86+
execl("/bin/sh", "sh", "-c", "cat /etc/passwd | wc -l");
87+
88+
You really have to fork a new process for each command in a pipeline,
89+
and connect them together with pipes.
6090

6191
Test scenario
6292
-------------
@@ -290,46 +320,119 @@ you start your shell from.
290320

291321
Phase 2
292322
-------
293-
- pipes
294-
295-
- redirections
296-
- "file >"
297-
- "file <"
298-
- ">> file"
299-
- no need to implement ">&N" etc.
300-
- whitespace is not significant (e.g. ">file", "> file" and
301-
"> file" are all syntactically correct and equivalent)
323+
- implement pipes
324+
- implement the three basic redirections
302325

303-
- background execution via &
326+
Pipelines
327+
~~~~~~~~~
328+
The number of pipes in a pipeline is only limited by the machine
329+
resources. That means no static array for pipelines.
304330

305-
Specific examples will be provided by the end of November but it must
306-
work in the usual fashion. For example, this works in any normal
307-
Unix/Linux shell, i.e. the redirection does not have to be at the end:
331+
So, for example, the following prints output of date(1):
308332

309-
mysh$ > output date
310-
mysh$ cat output
311-
Wednesday, October 10, 2018 at 10:12:53 AM CEST
333+
mysh$ date | cat | cat | cat | cat | cat | cat | sort -n | uniq
312334

313-
And pipelines may be separated by a semicolon, i.e. it's an extension of
314-
the 1st phase:
335+
Pipelines may be separated by a semicolon, i.e. it's an extension of the
336+
1st phase:
315337

316338
mysh$ cat /etc/passwd | wc -l; echo X | grep X
317339
26
318340
X
319341

342+
Note that the shell needs to wait for all commands in the pipeline to
343+
finish before printing out the next prompt. So you need to create the
344+
pipeline HORIZONTALLY, meaning the shell it a parent of ALL processes in
345+
the pipeline (remember, wait(2) only works on direct children). For
346+
example, the following will hang for 10 seconds before your shell
347+
returns a new prompt:
348+
349+
mysh$ date | sleep 10 | cat
350+
351+
If you only waited for the last command (cat(1) in this case), the shell
352+
would offer the next prompt right away which is NOT correct.
353+
354+
Note that sleep(1) does not read from its input, and does not write
355+
anything to STDOUT, so the cat(1) command finds no writer on the pipe
356+
and exits right away.
357+
358+
Redirections
359+
~~~~~~~~~~~~
360+
Implement the three basic redirections:
361+
362+
- "> file"
363+
- "< file"
364+
- ">> file"
365+
366+
Note: there is no need to implement "2>xxx", ">&N" etc.
367+
368+
Whitespace is not significant (e.g. ">file", "> file" and "> file"
369+
are all syntactically correct and equivalent)
370+
371+
You may assume redirection operators always come at the end, if it helps
372+
you simplify the parsing, i.e.:
373+
374+
mysh$ cat /etc/passwd > output
375+
mysh$ cat < output >output2
376+
377+
You do NOT need to implement:
378+
379+
mysh$ >output cat /etc/passwd
380+
mysh$ cat >output /etc/passwd
381+
382+
The last redirection counts, ie. the following will append the output to
383+
"output3":
384+
385+
mysh$ date >output >output2 >>output3
386+
387+
And the following will print /etc/passwd ONLY:
388+
389+
mysh$ cat </etc/group </etc/passwd
390+
391+
And the following will write /etc/group to output3, truncating it if it
392+
existed beforehand:
393+
394+
mysh$ cat </etc/passwd </etc/group >output >>output2 >output3
395+
396+
Normal shells always create all files with ">" and ">>" but you do not
397+
need to do that. It's OK only to create the last one only.
398+
399+
Note that redirection comes after connecting the individual commands in
400+
the pipeline with pipes, so the following copies /etc/passwd to file
401+
"output", puts date's output to file "output2", and the last cat(1)
402+
finds no writer on the pipeline (since date(1) is printing to "output2"
403+
instead) and just exits finding STDIN empty:
404+
405+
$ cat /etc/passwd > output | date > output2 | cat
406+
320407
Anything not listed above is NOT required
321408
-----------------------------------------
322409
I.e. we do NOT require any of these below:
323410

411+
- background execution via &
412+
324413
- Variable support (i.e. "echo $HOME" nor "XXX=value ./a.out")
414+
325415
- The "export" internal command.
326-
- Job control.
416+
417+
- Job control. That also means there is no need to create a new process
418+
group for each pipeline (that's what a normal shell does). However,
419+
if you do, you will need to solve how background processes the control
420+
terminal as that was out of scope of our class.
421+
327422
- Support for $? etc.
423+
328424
- Strings, i.e. the following is not required:
329425

330426
$ echo "xxx yy"
331427
xxx yy
428+
332429
- `` and $( ... )
333430

431+
- no complex commands like "if", "while", "for", "switch", etc.
432+
433+
- no line continuation with '\'
434+
435+
If unsure, either ask on our class mailing list or check what bash does.
436+
334437
vim:tw=72
335438
vim:ft=conf

0 commit comments

Comments
 (0)