Utilities Unleashed Edit on Github
Learning Objectives
The learning objectives for Utilities Unleashed are:
- Fork, Exec, Wait
- Environment Variables
- Writing a C Program
- Using argv, argc
- Introduction to core utils
Suggested Readings
We suggest you read the following from the
wikibook
before starting Utilities Unleashed:
Overview
In this lab, you will be implementing the following C utilities:
Notes:
- Do not worry about flags or features that we do not mention.
- Do not print any of your debug information out for your final submission.
- All printing (except env vars) should be handled with
format.h
. - A common issue is double printouts. If this happens to you, try flushing stdout before you fork/exec. If this solves your issue, ask yourself why.
format.c and .h
Since this lab requires your programs to print messages to stdout and stderr, we have provided you with format.c
and format.h
. You should not be printing out to stdout and stderr at all, except for the print feature of env
; instead, you should be using the provided functions. You can find documentation for each function in format.h
. This is our way of ensuring that you do not lose points for formatting issues, but it also means that you are responsible for handling any errors mentioned in format.c
and format.h
.
There is no provided format function for printing the environment variables. To do so, you should print each one on its own line (e.g. with printf("%s\n")
).
time
In this lab, you will be implementing time
.
time – run a program and report how long it took
So if a user enters:
./time sleep 2
then time will run sleep
with the argument 2
and print how long it took in seconds:
2.002345 seconds
For more examples, you can play with Linux’s builtin time
command by typing time YOURCOMMAND
(time ls -l
, for example) in your terminal. Be sure to add ./
to the beginning (or use the full path to your time
executable file if you are in another directory), otherwise the builtin time
will be called.
Note that we only care about wall-clock time, and we recommend using clock_gettime
with CLOCK_MONOTONIC
.
Pro tip: 1 second == 1,000,000,000 nanoseconds.
Nota bene:
- You may not use on the existing
time
program. - You must use
fork
,exec
, andwait
(no other solutions will be accepted). - If the child process does not terminate successfully (where its exit status is non-zero), you should exit with status 1 without printing the time.
- We will only run
time
with one program. - The commands we will run can take any number of arguments.
- Do your time computations with double-precision floating pointer numbers (
double
) rather that single-precision (float
). - We have provided functions in
format.h
that we expect you to use wherever appropriate.
Useful Resources
env
In this lab, you will be implementing env
.
env – run a program in a modified environment
When run without arguments, it prints a list of all the current environment variables.
When run with arguments, it will be given at least two, and will be called like so:
./env <var-list> <command-name>
<var-list>
is a comma-separated list of changes that are to be made to environment variables, and<command-name>
is the name of a command that is to be run after making those changes.- Any additional arguments are to be passed as arguments to
<command-name>
. - Each of the environment variable changes in
<var-list>
is of the form<destvar>=<value>
. <destvar>
is the name of the environment variable that is to be changed and<value>
is the new value.<value>
may contain references to environment variables in the form%<srcvar>
.- Each reference to
<srcvar>
should be replaced with the value of<srcvar>
. - The names of the variables
<destvar>
and<srcvar>
will contain only letters, numbers, or underscore characters. - For each environment variable change in
<var-list>
, your program will assign<value>
to<destvar>
in the current environment so when<command-name>
is executed, it will inherit the new value of the<destvar>
variable. - Any invalid input passed to
env
should result in the above usage being printed.
For example, if the user enters:
./env
then you should print out all the environment variables and their values, like the builtin Linux env
command.
If the user enters:
./env TZ=MST7MDT date
then it changes the TZ
environment variable while running the date
command.
And, if the user enters:
./env PATH=%HOME/bin:%PATH,IDIR=/%HOME/include,LIBDIR=/%HOME/lib make -j4
then it changes the PATH
, IDIR
, and LIBDIR
variables while running make
with the j4
option.
env
updates the environment variables sequentially. For example, ./env PATH=%HOME,IDIR=%PATH
will update $PATH
before we start processing $IDIR
, so $IDIR
would be equal to $HOME
.
Again like time
, you can play with Linux’s builtin env
command by typing env <var-list> <command-name>
(env MYVAR=CS241 printenv
, for example) in your terminal. Again, remember to add ./
to the beginning (or the full path to your env
executable file if you are in another directory), otherwise the builtin env
will be called.
In addition, keep in mind that the builtin env
uses $
instead of %
to denote environment variables, and they are separated by spaces in the var list instead of commas.
In practice, it can be very useful to change some environment variables when running certain command.
For example, you may notice people write #!/usr/bin/env python
on the first line of their Python script. This line ensures the Python interpreter used is the first one on user’s environment $PATH
. However, users may want to use another version of Python, and it may not be the first one on $PATH
. Say, your desired location is /usr/local/bin
for instance.
One way to solve this is by exporting $PATH
to the correct position in your terminal, however, this may mess up other commands or executable under the same session.
An alternative and better way is to use our env
, and enter:
./env PATH=/usr/local/bin ./XXX.py
then it runs the script with the desired Python interpreter.
Nota bene:
- You may not use the existing
env
program. - You may not replace
%
with$
or usewordexp(3)
. - You may not use
execvpe
,execve
, orexecle
. - All changes in environment variables and execution must happen only in the child process.
- You must use
fork
/exec
/wait
. - If a variable doesn’t exist, interpret its value as a zero-length string.
- Do not fork bomb the autograder! You will fail if you forkbomb the AG.
Useful Resources
Submission Instructions
Please read details on Academic Integrity fully. These are shared by all assignments in CS 241.
We will be using Subversion as our hand-in system this semester. Our grading system will checkout your most recent (pre-deadline) commit for grading. Therefore, to hand in your code, all you have to do is commit it to your Subversion repository.
To check out the provided code for
utilities_unleashed
from the class repository, go to your cs241 directory (the one you checked out for "know your tools") and run:
svn up
If you run ls
you will now see a
utilities_unleashed
folder, where you can find this assignment!
To commit your changes (send them to us) type:
svn ci -m "utilities_unleashed submission"
Your repository directory can be viewed from a web browser from the following URL: https://subversion.ews.illinois.edu/svn/sp17-cs241/NETID/utilities_unleashed where NETID is your University NetID. It is important to check that the files you expect to be graded are present and up to date in your SVN copy.
Assignment Feedback
We strive to provide the best assignments that we can for this course and would like your feedback on them!
This is the form we will use to evaluate assignments. We appreciate the time you take to give us your honest feedback and we promise to keep iterating on these assignments to make your experience in 241 the best it can be.
https://goo.gl/forms/z06gBY7MocFDrE3S2