Introduction
Announcements

Schedule
Labs
Assignments
TA office hours

Tests, exam

Topic videos
Some course notes
Extra problems
Lecture recordings

Discussion board

Grades so far

University of Toronto Mississauga
April 2010 Final Examination
CSC 209H5S
Software Tools and Systems Programming
Instructor: Alan Rosenthal
Duration: 3 hours
Aids allowed: Any books and papers.
No electronic aids allowed: No calculators, cell phones, computers, ...

Make sure you have all 11 pages (including this page).
(Don't panic about the page count -- there's lots of extra space for answers.)

Answer all questions. Answer questions in the space provided. Answers not in the correct space will not be graded unless a note in the correct space says "see page ..." and the answer on that page is clearly labelled with the question number.

In general, in the C programming questions you can omit the #includes, and you can omit comments unless you need to explain something unclear about the functioning of your code.


1. [8 marks]
In csh (not the shell we used for programming in this course), i/o redirection of stdin and stdout using '<' and '>' works the same as in sh, but redirection of stderr is different. To redirect stdout and stderr to a file, you use the two-character sequence '>&'. Example:

	lynx -dump $url >& /dev/null

a) There is no explicit syntax for redirecting stdout and stderr to different places, but you can accomplish this by redirecting stdout, then parenthesizing that command, then redirecting the parenthesized command's stderr with '>&'. Use this technique to write a csh command to redirect the stdout from the command "foo" to the file "one", and the stderr to the file "two".

b) Give an example i/o redirection in sh which cannot be expressed in csh with the above tools.

c) Nevertheless you can always run sh itself from your csh script. Write a command, to be executed in csh, which uses sh to accomplish the redirection you listed above for part (b).

[Sample solutions]


2. [5 marks]
What is the difference between

	cat $x
and
	cat '$x'
and
	cat "$x"
?

[Solution]


3. [7 marks]
Consider the following portion of a unix filesystem hierarchy:

The '.' and '..' entries are not indicated, of course; otherwise, all of the files below "a2" are shown. a2.pdf, splitexpr.c, wfold.c, and wfold.1 are plain files; a2, handout, starter, soln, and splitexpr are directories.

a) Indicate the link count for each of these files:

handout:

starter:

soln:

wfold.c:

b) Suppose the user is cd'd to the handout directory and types:

	ln a2.pdf example.pdf
Which file(s) will change their link count, and what will the link count(s) be now?

c) Suppose the user is cd'd to the soln directory and types:

	mkdir new
Which file(s) will change their link count, and what will the link count(s) be now?

[Solutions]


4. [10 marks]
Recall Euclid's greatest common divisor algorithm:

	while (y > 0) {
	    int t = x;
	    x = y;
	    y = t % y;
	}

Write a shell script to perform this algorithm. The two input values will appear on the command line. You can assume that they are integers (if present -- you still have to check the argument count). Note that the "expr" command has a '%' operator.

Sample interaction, where '$' is the shell prompt:

	$ sh gcd 12 15
	3
	$ sh gcd 12 15 26
	usage: gcd x y
	$ 

[Sample solution]


5. [10 marks]
Write a shell script in the sh programming language to play a guessing game as follows, where the user's number is between 0 and 100 inclusive. Your shell script does a binary search by keeping track of a "low" and a "high" value such that the user's number, x, is always such that low<=x<high. On each iteration, the guess is (low+high)/2, and this new number will be assigned either to low or high in accordance with the user's response.

	$ sh guess
	Is your number >=50 or <50?  Enter 'g' or 'l'.
	l
	Is your number >=25 or <25?  Enter 'g' or 'l'.
	g
	Is your number >=37 or <37?  Enter 'g' or 'l'.
	l
	Is your number >=31 or <31?  Enter 'g' or 'l'.
	g
	Is your number >=34 or <34?  Enter 'g' or 'l'.
	l
	Is your number >=32 or <32?  Enter 'g' or 'l'.
	g
	Is your number >=33 or <33?  Enter 'g' or 'l'.
	g
	Your number must be 33.
	$ 

(You don't have to worry about invalid user input.)
(Once low==high-1, you exit the loop and conclude that the user's number must be low.)

[Sample solution]


6. [10 marks]
Write a C program which is like an extremely-limited version of "test". It expects to be run with two command-line arguments (otherwise it emits a usage message in the usual way). Both command-line arguments should be integers. Your program will exit with exit status 0, 1, or 2 in accordance with whether the first argument is less than, equal to, or greater than the second. You can assume that the strings are valid integers (if they exist -- i.e. you still have to test the argument count).

[Sample solution]


7. [20 marks]
Write a C program which listens on port number 1234 and receives a series of connections. It will handle only one connection at a time. Once a user connects, it will run a "chat" between the user connecting over the network (e.g. with "telnet") and the user running the program (and with access to its stdin and stdout). When the remote user disconnects, your program will wait for the next user, until it is killed.

You do not need to worry about the network newline convention. You can omit the #includes, and you can cite course web pages rather than copying out bits of code if you can do so unambiguously.

[Sample solution]


8. [30 marks]
Write a program in C which interactively builds up a list of i/o redirections in accordance with the user's instructions, then executes a command with those i/o redirections in place, then loops around and repeats. Sample interaction:

	Which file descriptor do you want to redirect?  -1 to end the list.
	1
	Where do you want to redirect file descriptor 1 to/from?
	blahblah
	Is blahblah to be opened for read or write?  ('r' or 'w')
	w
	Which file descriptor do you want to redirect?  -1 to end the list.
	0
	Where do you want to redirect file descriptor 0 to/from?
	/dev/null
	Is /dev/null to be opened for read or write?  ('r' or 'w')
	r
	Which file descriptor do you want to redirect?  -1 to end the list.
	-1
	What program do you want to execute?
	ls something
	Executing:
	something: No such file or directory
	exit status 1
	Which file descriptor do you want to redirect?  -1 to end the list.
	38
	Where do you want to redirect file descriptor 38 to/from?
	^D

The user typed the lines in bold. At the end, the user pressed ^D signalling end-of-file, and in response the program exited. This can happen at any time.

I recommend using fgets() to read the user input (in all cases). You can use atoi() to convert the string into an integer. You can use strsave() from assignment three if you like. You can assume that all user inputs are correct.

Your program will ignore argv (and need not declare argc or argv in main's parameter list).

Since the user can type any number of redirections, you will use a linked list to store them all. Then after the fork(), the child will implement them all in a loop, and the parent will free all of the malloc'd memory before looping around to solicit the next command setup.

To open a file for read, the second argument of open() should be O_RDONLY. To open a file for write, the second argument of open() should be O_WRONLY|O_CREAT|O_TRUNC.

You can execute the user's command by passing it to "sh -c" as system() does.

This is basically three exam questions. Grading will be divided roughly as follows:
8a [10 marks] user interaction
8b [10 marks] build the linked list of redirections; free it afterwards
8c [10 marks] fork/exec/wait and i/o redirections

[Sample solution]


End of exam. Total marks: 100. Total pages: 11.