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 lab 09 exercises, week of 12 July 2022

[solutions are available (requires teach.cs authentication)]

Attendance

As usual, please either run /u/csc209h/summer/present on the console of a lab workstation, or get the TA to record your attendance. Please do this first so that you don't forget.

Remember that you can check that your attendance has been recorded properly at https://wwwcgi.teach.cs.toronto.edu/~ajr/cgi-bin/auth/present


1. fork exercise

Write a program which creates five child processes, numbered 0 through 4. Each child process computes the sum of the integers 5i through 5i+4, where i is its index number. It then returns this value as the process exit status. The parent then waits for them all and outputs the total of the exit statuses, which will be the sum of the integers from 0 to 24 inclusive.

This is an abuse of process exit status, but I think it's fun and a good exercise.

sample solution — please don't look at the sample solution until you've spent some time on this problem!

2. more serious fork (for credit)

a) Read a line from the standard input with fgets(), then fork, then have the child execute the line as a command with "sh −c", and have the parent wait for the child and print its exit status. [reminder about execl and sh −c]

(note: in case you're not clear what this is supposed to do, you can find a compiled sample solution at /u/csc209h/summer/pub/lab/09/q2a )

b) What happens if you give your program an immediate EOF? (E.g. redirect its input from /dev/null.) Fix it if necessary.

c) Make this program into a loop, including printing a '$' prompt. Exit upon EOF (when fgets() returns NULL).

(note: in case you're not clear what this is supposed to do, you can find a compiled sample solution at /u/csc209h/summer/pub/lab/09/q2c )

Call your program q2.c and submit it for credit (the version with the loop).

3. signals exercise (for credit)

Signals are a fairly blunt form of interprocess communication, like a grunt or a beep. But you can still encode arbitrary data this way.

For this part of the lab you will work on two programs which communicate an arbitrary byte via signals. The "transmit" program will signal the eight bits of this byte, which is supplied on the command-line; and the "receive" program will receive these eight bits and output the single byte (plus a newline) to its standard output.

To begin, the receive program will output its process ID number (using getpid()), as part of an explanatory line of text. This makes it easier for you then to run the transmit program in another window: the transmit program takes the receive program's process ID number in argv[1], and the character to transmit in argv[2].

The transmit program will then transmit those eight bits one at a time. To transmit a zero, it signals the receive program with the signal "SIGUSR1" as defined in signal.h. To transmit a one, it signals the receive program with signal "SIGUSR2". (These two signal numbers are reserved for user-defined purposes.) To make sure that the signals arrive in order and are not combined, sleep for a tenth of a second inbetween each transmission using usleep(100000). These signals are sent using the kill() system call.

A compiled version of each of receive and transmit is supplied in /u/csc209h/summer/pub/lab/09 . You can run these programs against each other, and you can test them against your own.

To assemble the eight bits in receive.c, you can start with a value of zero and keep left-shifting it by one bit, adding 1 when there's a 1 bit and not doing anything extra when there's a 0 bit (only the left-shift).

For example bit-manipulation code which disassembles the bits for use in transmit.c, see /u/csc209h/summer/pub/lab/09/disassemble.c .
For an example program which waits for signals, see /u/csc209h/summer/pub/lab/09/receive-hint.c .
Both of these programs are also compiled for your use, in /u/csc209h/summer/pub/lab/09 .

You might prefer to focus on only one of receive.c and transmit.c. A correct implementation of either one will get the mark for this part of this lab.

4. fork and i/o redirection (additional exercise, not for credit)

Alternately prompt for a command and for a file name to redirect its output to. Execute the command (in the child process) with stdout redirected. Example:
        bigcomplicatedprompt$ ./a.out
        $ ls
        File to output to: foo
        exit status 0
        $
It's fine that the command has a newline at the end of it since you're passing it to sh to be executed (the shell skips white space as applicable), but for the file name, you'll need to remove the newline with something like
        if ((p = strchr(filename, '\n')))
            *p = '\0';
Remember that the second argument to open() for opening a file for write in the normal way is O_WRONLY|O_CREAT|O_TRUNC and the third argument is 0666. Make sure that you see your prompt after the execution of the redirected command (if not, you're doing the redirection in the parent rather than only in the child).

To submit

First of all, you must run "/u/csc209h/summer/present", during the tutorial time, on the console of a tutorial lab workstation, or get the TA to mark you as present.

Then, by the end of Friday July 15, submit q2.c, and submit either receive.c, transmit.c, or both, using the usual 'submit' command, with "assignment" name "lab09".

Your grade for the second half of this lab will be the max of the two grades assigned for receive.c and transmit.c.

Programs which yield error or warning messages when compiled with "gcc −Wall" on the teach.cs machines get zero.

Note that the supplied compiled receive and transmit are reference implementations. Your programs must work with them to get the mark; implementations which use different signals or send them in a different order are not going to be considered solutions to this lab assignment.