Operating systems 1 -- 2009-2010 -- info.uvt.ro/Project 1

From Wikiversity

Quick links:


Important! The official project description should also be read from profesor Florin Fortiş. Please also consult the references at the end of this page.

Implement a C application that implements a basic shell that presents a prompter to the user and allows him to enter certain commands (the commands with their syntax and semantics are described in the next section);

The shell should implement the following basic loop:

  • write the prompter to the user;
  • reads the user command;
  • parses and validates the user command;
    • in case there is a syntax or semantic error a meaningfull message should be printed to the user;
  • executes the user command;
  • writes a meaningfull success or failure message for the user;
  • the loop should terminate when:
    • the user enters exit command; (this is the normal way to close the shell);
    • there is an error while reading from stdin (this should be treated as an error, and a meaningfull message should be printed);
    • there is an end-of-file encountered in stdin (this should be treated as a warning, but acceptable);



  • each command should be written on its own line:
    • commands cannot span multiple lines;
    • multiple commands cannot be written on the same line;
  • each command is composed of one or more tokens separated by one or more space or tab characters;
  • each token is:
    • either a sequence of one or more characters except space or tab;
    • either a sequence of one or more characters (including space or tab), but enclosed inside double or single quotes; (the quotes are not part of the token, and the quotes character used cannot appear inside the token);
  • a line whose first non-space (or tab) character is # should be treated as a comment and ignored;


  • comment lines:
# this is a comment line
   # this is another comment line
##### again a comment line
  • simple command without quoted tokens (observe how the whitespace does not matter):
mkdir /tmp/test-folder
   rmdir    /tmp/test-folder
echo test
  • a command with quoted tokens:
# the text enclosed in single quotes is one token (including those double quote characters)
echo ' aaa bb c """"" '


List of commands[edit]

generic commands flags points
help R
version R
exit R
file commands flags points man page
cat -b, -E, -n, -s 3 cat.1
tac -b -s 3 tac.1
head -c, -n, -q, -v 3 head.1
tail -c, -n, -q, -v 3 tail.1
sort -i, -r, -d 4 sort.1
uniq -i, -d, -u 4 uniq.1
nl -s -d 2 nl.1
wc -c, -w, -l, -L 3 wc.1
expand -t, -i 3 expand.1
unexpand -t, -i, -a 3 unexpand.1
tee -a 3 tee.1
file system commands flags points man page
cd 2 bash.1 (see cd comamnd)
pwd 1 bash.1 (see pwd comamnd)
cp -i, -R, -t, -v 5 cp.1
mv -i, -t, -s 4 mv.1
rm -i, -R -v 4 rm.1
mkdir -m, -p, -v 2 mkdir.1
rmdir -p, -v 2 rmdir.1
ls -l, -s, -a, -F 5 ls.1
dir 3 dir.1
chmod -v, -R 5 chmod.1
chown -v, -R 5 chown.1
chgrp -v, -R 5 chgrp.1
dirname 2 dirname.1
basename 2 basename.1
environment commands flags points man page
printenv 2 printenv.1
env -u 3 env.1
miscellaneous commands flags points man page
yes 1 yes.1
date -d, -f, -s, +<format> 4 date.1

Generic requirements[edit]

  • each command shall have understand the -h (help flag) -U (user flag) that should provide a short description and usage about the command (-h), or the implementor (-U);

help and version[edit]

  • the help command shall provide a list of available commands and a short description for each one;
  • the version command shall print the version, author and other informations about the implementation;


  • should cause the shell to stop asking for new commands and exit;
  • example:


  • should accept any number of arguments (including none), and display them separated by space;
  • example:
echo 'a bb cc' cc d "ee ff"
    • output:
a bb cc cc d ee ff


  • should take only one argument that represents the name of an environment variable, and print it to standard output:
  • example:
echoenv USER
    • output:
  • example in case of undefined variable:
    • output (to standard error):
[ee] the environment variable `NO_SUCH_VARIABLE` is undefined;

cd, and pwd[edit]

  • cd should be used to change the current directory to the one pointed by the single argument given;
  • pwd should print the current working directory;
  • example 1 (both command (prefixed by $, and output (no prefix)):
$ pwd
  • example 2 (both command and output):
$ cd /tmp
$ pwd

mkdir, and rmdir[edit]

  • both take any number of arguments (at least one) and either create or remove the designated folder (rmdir should work only in case of empty directories);
  • examples:
$ mkdir /tmp
[ee] the folder `/tmp` already exists;
$ mkdir /tmp/a /tmp/b /tmp/c
$ rmdir /tmp/a /tmp/b
$ rmdir /tmp/c
$ rmdir /tmp/x
[ee] the folder `/tmp/x` does not exist;

touch, link, and unlink[edit]

  • touch creates the designated file in case it does not exist (it accepts more arguments, at least one);
  • link takes two arguments (the source and destination) and makes a hard link of the source to destination;
  • unlink takes any number of arguments (at least one) and deletes them;
  • examples:
$ touch /tmp/a /tmp/b
$ link /tmp/b /tmp/c
$ unlink /tmp/c

cat, head and tail[edit]

  • cat takes at least one argument and displays the content of each file one after another;
  • head takes only one argument and displays the first 10 lines from it;
  • tail is like head but displays only the last 10 lines;
  • examples:
$ cat /etc/fstab /etc/services
... the content of /etc/fstab
... the content of /etc/services
  • head and tail could also accept the -n option, followed by a number and should display that many first or last lines;
  • examples:
$ head -n 20 /etc/services
... the first 20 lines from /etc/services


  • takes exactly one argument, the name of a folder, and should display the files found inside; (by default the folders ., .., and any file / folder starting . should not be displayed;)
  • as modifiers (flags) we have:
    • -a -- should display even files starting with . (except the . and .. folders);
    • -l -- should display after each file the type, owner (uid), group (gid) and size;
  • the contents should be sorted alphabeticaly;
  • examples:
$ ls /
$ ls -a /home/ciprian
$ ls -l /boot
grub folder 0 0 4096
vmlinuz file 0 0 13341253

cp, and mv[edit]

  • cp takes exactly two arguments: the source and destination, and it should copy the content of the source file as the content of the destination file;
  • if the destination file already exists it should be treated as an error;
  • if -f flag is present the copy is forced (even if the destination already exists);
  • mv is the same as cp, but instead of copying it moves the file;
  • mv should not be implemented by using the rename POSIX function (or by link and unlink); instead a new file must be created, filled with the contents of the old one; and then the old file should be deleted;


Mandatory observations:

  • all messages that are meant for the user to see (informations, warnings, errors, etc.) should be printed to stderr;
  • all text that is part of the command actual output (like in the case of ls) should be printed to stdout;
  • stdin should be only used to read user commands;

Optional observations:

  • in case of messages for the users it would be nice to prefix the text with an indicator of the nature / gravity of the message; for example for informative messages (like success) you could prepend one of the following prefixes: INFO:, or [ii], etc. (a space would be nice between the prefix and the actual output);


[parse the farse 1]Submission[edit]

Please consult the repository page.
Cite error: <ref> tags exist for a group named "parse the farse", but no corresponding <references group="parse the farse"/> tag was found