COP4610: Operating Systems &
Concurrent Programming |
up
↑ |
Programming Assignment #3
API-level Process Management
Deadline:
See course calendar.
Educational Objectives:
This assignment is intended to familiarize you with using the
C API to the operating system, and more specifically with the
API view of process management. In essence, you will repeat
programming assignment P2, but this time you will write a C
program to do the work of the shell subprograms "runtest". The
main effort should be learning to use the necessary Unix API
calls. It will also require learning C string manipulation in
order to set up the parameters. As usual, you will also be
expected to write portable code, which compiles and runs the
same on both Linux and Solaris/SunOS systems.
- Learn too use the Unix/POSIX/Linux C-language API.
- Become familiar with the C API view of process management, including:
process creation, process termination, exit status, signals, resource
limits.
- Become familiar with the C API view of file I/O, including
the distinction between file descriptors and streams,
buffering, and the effects on I/O of concurrent execution and
abnormal program termination.
- Continue the practice of writing portable C code.
Deliverables:
Modified versions of the
provided file runtest.c and modified version of testone.
Tasks:
- Create a new working directory, P3, and copy into it the gzipped
tar-file that you will find at ~baker/opsys/assign/P3/P3.tgz,
which should give you a copy of everything in my P3 directory. Expand the
file, using the command tar xzvpf P3.tgz. Test the installation, by
executing make, then ./testone sol0, and looking at the file
that is created in the subdirectory results.
- Read the C program "runtest.c", including all the advice and instructions
in the comments.
- Modify "runtest.c", so that does approximately the same
thing as the shell subprogram "runtest" in the shell script testone
from your previous assignment P2. That is, your program should execute the
program "sim" from the current working directory, and check the results of
the execution. The bare-bones example, which is given to you, executes the
program "sim", but does not check the results. You will need to add code,
as pointed out by comments within the program, to do the following:
- Check the termination status of the child process, and print out a
message to stderr, telling whether the process terminated normally and
if it did not terminate normally the reason for the termination.
- Capture the stdout and stderr output written by the child process
on temporary files, and copy the first 40 lines of each to the stdout
of your program runtest.c, between the two header lines. This
requires that you add code to create those files and redirect stdout
and stderr to them, between the fork() and the exec(), on the child
process branch. File redirection involves use of the dup2()
system call. Before you try coding this, make certain you understand
file descriptors and the effect of this function.
- Compare those files against the expected (baseline)
output, printing out at least a simple message whether
they matched or not. As in the previous assignments, the
baseline output for purposes of comparison is that
produced by the program in directory sol0, and
so sol0 may be treated as a special case. You do
not need to compare the output of the version
of sol0/sim against itself, and you may retain the
files created by executing tests in sol0/Linux
and sol0/SunOS rather than deleting them after the
comparison. The runall script will always execute
tests in sol0 before testing in other directories,
so that you can assume the baseline output files are
there. However, beware that if you retain the files
produced by sol0/sim with several different sets of
command-line arguments you will have to give them unique
names to prevent over-writing. You should omit the
comparison if the program has been aborted before normal
completion (e.g., segfault, time limit, output limit).
- Using setrlimit, limit the amount of child output to 100K bytes per file,
and the child CPU time to 1 second.
- Modify the script testone to pass the appropriate
command-line arguments to runtest so that it run at
least two different tests on the subject program (the
simulator), including at least one that passes one or more
command-line parameters. In order to do this you will need to
devise a convention for passing the necessary information
to runtest, via command-line arguments. For example,
you might modify runtest.c so that
calling ./runtest -nprocs=100 -miat=3.0 cause it
to execute sim -nprocs=100 -miat=3.0. This is
just by way of illustration. You will probably want
your runtest to have other parameters. For example, it
may help to also have a parameter that identifies the specific
test and can be appended to the names of the temporary files.
You must modify testone as well as runtest.c to
coordinate on these parameters.
- Update the comments in the program to include your name, the date of
last modification, and an explanation of the changes you made (the new
features you added to the program). Remove all of the advice comments at the end,
and the internal advice comments, which generally start with "...". Put in
your own comments explaining the approach you chose in cases where
there is more than one approach mentioned in the advice.
- Check that the new program works, by running it on the examples
(sol0-sol3, and any more that I provide), and debug as
necessary.
- Now switch to the other operating system (to SunOS if you were working
on Linux before, or vice versa) and repeat the testing as above,
correcting any problems that show up. If you make any changes, switch back
to the other operating system and repeat, until you are sure your program
works correctly on both systems.
- Submit your solution using the provided script submitP3.sh.
Further Instructions & Advice:
- There is some partial overlap between the instructions and
advice here and that contained as comments within the
bare-bones. If you find any inconsistencies please send
e-mail to the instructor so that we can correct them.
- The P3 directory that I provide includes a
subdirectory results.sample containing output created by
executing testall with my testone and a fleshed-out
version or runtest.c. These are provided to give you an
idea of what kind of output I'm looking for, but you do not need
to match them exactly.
- Do not use the "testone" script that you produced for
assignment P2. Use the "testone" that is provided in
"P3.tgz".
Beware that Linux has a utility programs
named runtest, so you will have to execute your program
using the notation "./runtest" rather than just "runtest".
- File redirection is not complicated, but must be done
exactly right. After creating the files and opening them for
reading and/or writing (as appropriate) with function open(), use the
function dup2() to do the redirection. Make certain
you understand this function and how file descriptors work,
before you start writing code for this. I have notes and examples
on the use of open(), dup2() and other I/O calls
in my
notes on Unix file concepts,
- This assignment is a simplified application of some of the
same system calls that were used in the first programming
assignment for the past two offerings of this course, which
was to write a shell program. You may find the instructions
on some system calls from that assignment, including file
redirection, to be useful if you can keep in mind that you are
not writing a shell program this year. The assignment description from
last year is posted at
http://www.cs.fsu.edu/~cop4610p/spring14/assignments/project1/.
- Look at the man page for getrlimit and setrlimit. You
should use those interfaces, in the child process, after the fork
but before the exec, to set a CPU time limit and a file size limit
for the child process. (Please do not use ulimit for this assignment.)
- You may assume that the directory where the program executes (e.g., sol1/Linux) contains
no files with names of the form "tempfile*", so that you can use names of that form
for temporary files.
- Note that there are two reasonable ways of doing the file comparison:
- Use execve() with one of the standard system
utilities, like cmp or diff. Unlike the example
of execve() in the bare-bones version, you should cause the
parent process to block (wait) until the other program returns,
rather than using a time-out mechanism like sleep. Read the
Xopen/POSIX man-page for waitpid() to understand how
the WNOHANG parameter is involved.
- Write your own code to do a byte-by-byte comparison of the two
files. This will require opening both files for read access,
and a loop to read from both files and compare the inputs until
the end of one file is reached.
You may choose which way to go. Option #1 gives you more
experience with process creation and management, and so I
would suggest that. However, option #2 gives you more
experience with file I/O, which would also be
educational. In either case, there is no requirement that
you print out where the files mismatch or what
characters/lines mismatch, if they mismatch. All that is needed
is a short summary message stating whether or not they match.
- Don't forget to make appropriate use of functions to structure your
code. The bare-bones program is simple enough that it appears as a single function.
However, as you add complexity it will be easier to write, understand, and debug
if you recognize operations that logically can be broken out into separate
C functions. For examples, you need to compare stderr against stdout,
- Take care to check the return value of every system call, and
take appropriate action if it fails. Points will be deducted for failure to
do so.
- Your program should compile without any error or warning messages.
Points will be deducted for failure to do so.
References:
- You should read the relevant on-line notes from this course, including the programming
examples that relate to this assignment. The files that are relevant, in
order of priority, are:
- SunOS and Linux man-pages, Xopen POSIX base system interface specification.
Delivery Method:
First read the Study Guide section on Submitting Assignments, for
general instructions.
-
Log into shell.cs.fsu.edu.
-
cd to the directory where you have your working solution,
and make certain the version of the deliverable files
you want to submit are in that directory.
-
Execute the shell script submitp3.sh. If it works correctly,
you should see a message indicating that the files were sent, and receive
the usual two confirmation e-mails a bit later.
Assessment:
Start by reading the Grading
Criteria for Programming Assignments section of the Study Guide for
general grading criteria.
Grading will be according to the following performance rubric, applied to
the results of testing on both operating systems. However, the number of
points shown on each line is a maximum; you can expect to have your score
reduced if the code that implements that feature does not adhere to the
instructions given in this file, or only compiles on one of the two operating
systems.
Criterion |
Points |
Checks termination of child process and prints out correct
informative messages for the reason, sufficient for a reader to
differentiate between success, time-out,
segfault, and other causes of failure. |
20 |
Redirects stdout and stderr to temporary files,
copies the first 40 lines of each to the report in the
required positions, and cleans up temporary files under all
conditions (except for sol0 as explained above). |
30 |
Compares the output against the sol0 output, and
prints a summary message indicating whether they match. |
20 |
Enforces a file size of 100K bytes per file, and a CPU
time limit of 1 second, using setrlimit(). |
10 |
Modified shell script testone runs runtest
at least twice, with different command-line arguments. |
5 |
Appropriate comments and coding style |
10 |
Everything compiles and works correctly on SunOS as well as Linux |
5 |
Up to 10 points extra credit may be awarded at the discretion
of the grader, but not to exceed a total of 100 points for the
entire assignment, for programs that go beyond the minimum
requirements in the above areas, including correct use of a
signal generated by an alarm or timer request to handle tested
programs that hang. If you do this, please set the limit quite
short, so as not to "hog" the processor when testing.
Submissions that come in past the deadline will have 5 points deducted
for each day they are late. No submissions will be accepted after grading has started.