Lab overview
Lab 01
Lab 02
Lab 03
Lab 04
Lab 05
Lab 06
Lab 07
Lab 08
Lab 09
Lab 10
Lab 11
Lab 12
Lab 13
Review

[Course home page]

CSC 209 exam review exercises, exam period

This lab does not correspond to a tutorial, and isn't graded, so attendance is not being taken, so you don't need to run the 'present' command.

Here are some problems from former exams. You can work on them by yourself or in groups of any size, as this lab is not graded.

If you write your programs on the computer, your goal should be that they compile without errors (with gcc −Wall, and no "warnings" either), except perhaps for typos; and work perfectly, on the first attempt; as you would not have the opportunity to run and "debug" them in exam conditions. (Of course, the extent to which you fail in this task just shows that you will probably not get 100% on the final exam, which you might have suspected anyway. But the ideal is first-time perfection. Actually, that's a good goal for all computer programming — take your time and write programs which work.)

These questions are mostly from different exams. They are roughly in the order in which I suggest you try them; I don't expect everyone to attempt them all. The first question was labelled "trick question" on the exam, because it is a bit quirky. But I put it first here because it encompasses a very important point.

Skipping ahead to the solutions defeats the point of this web page. Put your best effort into completing the questions, and only after you think you are done or you are absolutely stuck should you look at the sample solution.


1. [4 marks] (trick question)

a) How does the following function in C find the size of the array parameter?

void f(int *p)
{
    ...
}

b) Under what circumstances would the answer to part (a) be different if the parameter were of type "char *"?

[solutions]


2. [10 marks]

Which of the quotation marks in this shell script are unnecessary?

foo &
foopid="$!"
while kill -0 "$foopid"
do
    message="`foostatus`"
    if test "$message" = "Terminated"
    then
        exit 0
    else
        echo foo status: $message
    fi
done
exit 0

A few notes:

For each set of quotation marks, either explain why it is necessary (for example by giving a situation in which they would prevent an error), or explain (also very tersely) why they are not necessary.

a) "$!"

b) "$foopid"

c) "`foostatus`"

d) "$message"

e) "Terminated"

[solutions]


3. [6 marks]

Here are some "software tools" principles. For each, give an example of a unix program which obeys the rule, and state what it does or avoids doing so as to comply; and also give an example of a unix program which violates the rule, state how it violates the rule, and explain why you think it is or is not justified in doing so.

a) "Write small programs that do one thing well."

b) "Expect the output of every program to become the input to another, as yet unknown, program." (For example, don't clutter output with extraneous information such as headers.)

c) "Make programs' input formats easy to generate or type." (Example: Avoid stringently columnar or binary input formats. Another example: Supply good defaults: It should be common to say simply "command" with no command-line arguments.)

[some discussion of solutions]


4. [7 marks]

Sketch the inode and directory information involved in the following output from an "ls −liR" of the directory which is inode number 10. That is, list the inode numbers and what data you know is in those inodes; and state the contents of the directories involved.

total 8
12 drwxr-xr-x  3 ajr  users 4096 Feb 27 10:05 bar
13 drwxr-xr-x  3 ajr  users 4096 Feb 27 10:05 baz

./bar:
total 8
14 -rw-r--r--  1 ajr  users   20 Feb 27 10:06 gar

./baz:
total 8
15 -rw-r--r--  1 ajr  users   50 Feb 27 10:06 gaz

[solution]


5. [5 marks]

Here are some commands which use the "expr" tool to output the sum, difference, product, and quotient of the same two numbers:

expr 2 + 3
expr 2 - 3
expr 2 \* 3
expr 2 / 3

Why is the multiplication invocation different?

[solution]


6. [15 marks]

What is the output (on stdout) from the following commands? If you can't tell from the information given, state what additional information you would need.

a) test x = x

b) expr 2 + 3 | wc -l

c) echo hi | wc -c

d) (echo hi; echo bye) | sort

e) echo hi; echo bye | wc -l

f) expr 2 * 3

[solutions]


7. [10 marks]

The "cal" command has output like this:

	      May 2015
	Su Mo Tu We Th Fr Sa
	                1  2
	 3  4  5  6  7  8  9
	10 11 12 13 14 15 16
	17 18 19 20 21 22 23
	24 25 26 27 28 29 30
	31

By default it shows the current month. The above output could also have been produced with the command "cal 5 2015" (since May is the fifth month).

The 'date' command can provide these numbers when given various formats with the '+' option:

        $ date +%m
        05
        $ date +%Y
        2015
        $ 
(and "cal 05 2015" works just as well as "cal 5 2015")

Write a shell script called "cal2" which outputs the calendar for the current month and the following month (you can ignore any command-line arguments). Note that if the current month is number 12, you have to output month #1 for next year (rather than month 13, which does not exist).

[solution]


8. [5 marks]

Write a simplified "expr" command in C. Write the entire C program, except that you can omit the #includes.

Your expr should require there to be three command-line arguments, the middle of which is the string "+", "−", "*", or "/" (integer division). The other two are integers but you do not need to check this; just call atoi() or similar. Diagnose a division by zero appropriately (do not perform the division, as this may cause an "abnormal termination" similar to a segmentation fault).

[solution]


9. [5 marks]

A programmer is writing a function to compute the number of files and directories below a certain point of the filesystem tree, similar to the assignment three program which traversed a filesystem subtree. This programmer knows that "." and ".." should be avoided, but is not very familiar with strcmp() and decides to skip the check, figuring that the results will still be close.

What happens?

[solution]


10. [15 marks]

Write a simplified version of 'tr' in C. Your program can be invoked in one of only two ways:

Like "tr", your program will operate by copying the standard input to the standard output, making appropriate changes. It will never take filename arguments.

Do not use getopt(); just check for "−d" with strcmp(). In particular, "tr − x" changes all minus signs to the letter x, rather than being a usage error.

Diagnose all usage errors appropriately. If something which is supposed to be a single character is not a single character, you can output "tr: argument must be a single character"; for other usage errors, you must output an appropriate usage string in the standard format.

[solution]


11. [15 marks]

Write a version of the "head" command in C. This program takes zero or more file name arguments; if there are zero file name arguments, it processes stdin. By default it copies ten lines of the input to the output, then stops reading that input file. If there are more than one file names on the command-line, output the first ten lines of each in turn. If a file is shorter than ten lines, that's fine, you just output all the data there is.

There is also a '−n' option (not quite the same as the standard 'head' command) which changes the number of lines from ten to some other number. For example, "head -n15 file" shows the first 15 lines. Parse this option using getopt() in the standard way.

[solution]


12. [10 marks]

The C library function "system" executes a command by passing it to the shell. For example, if a C program wants to put you in the 'vi' editor on a file named "file", it could say

        status = system("vi file");
The system() function does not return until the subprocess has exited. It returns the exit status of the command as the return value of system().

To get the shell to parse and execute this command, system() uses the '−c' option to sh. That is, the above system() call will execute the equivalent of

        /bin/sh -c 'vi file'
except, of course, that it does it via fork()/execl()/wait(). (If the fork() fails, system() returns −1.)

Write the system() C library function. You don't have to worry about #includes. (You also don't have to worry about signals for this question — the real system() function does something about signals which you can forget about for this exam question.)

[solution]


13. [15 marks]

The current directory contains files named "1", "2", and "3". Write a program to listen on TCP/IP port 1234, and each time there is a connection, it outputs the contents of one of these files to the connection and then closes the connection. It should output the contents of the file "1" to the first caller, "2" to the second caller, then "3", then back to "1" and continue indefinitely.

The files on disk are in unix text file format, and you have to convert to the network newline convention by outputting an extra '\r' before every '\n'.

[solution]


That's the end of today's lab. Since it's not being graded, there is nothing to submit, and you don't have to run the 'present' command.

In case you're worried, I should reassure you that those questions are not all from the same exam! The exam won't be as long as the above.