CS 3733 Operating Systems, Spring 1999 Assignment 4


Warning: This is not for the current semester.


Due Friday, April 9, 1999

Note: The next assignment will be given out about a week before this one is due. You should start it early.

Overview

This assignment is in preparation for a later assignment on network communication. You will be writing two functions header_filter and filter. The filter function is used to monitor a bidirectional communication between an upstream host and a downstream host. (The designation of which one is upstream and which is downstream is arbitrary.) The filter method sends anything coming in on file descriptor fdupin to fddownout and anything coming in on fddownin to fdupout. Essentially this means it just connects the upstream and downstream nodes together.

In the process, filter sends all of the incoming data to two monitoring file descriptors, one for the data coming from upstream and one for the data coming from downstream. It does this through the header_filter method which looks at the data and and displays some summary information. For the first three parts of the assignment, header_filter just sends everything without any processing. In Part 4, it preprocesses the information.


Part 1

Write a function,
void header_filter(int fd, char *buf, int len, char *info, int info_len)
which outputs the len bytes of buf to the file descriptor fd. It should take into account the fact that write may output fewer bytes than requested, so it may have to call write more than once. For now, the last parameter will be ignored. The function header_filter should be in its own file.

Part 2

Write a function,
void filter(int fdupin, int fdupout, int fdupmon, int fddownin, int fddownout, int fddownmon)
which takes six open file descriptors as parameters. When the function starts it should send a message to each of fdupmon and fddownmon by calling header_filter with the appropriate file descriptor as the first parameter. The message sent to fdupmon should be "Open upstream\n" and the message sent to fddownmon should be "Open downstream\n".

Input coming from fdupin should be sent to both fddownout and fdupmon. It is sent directly to fddownout, but it is sent to fdupmon with a call to header_filter using fdupmon as a parameter. Input coming from fddownin should be sent both to fdupout and fddownmon. It is sent directly to fdupout, but it is sent to fddownmon with a call to header_filter using fddownmon as a parameter. If an end-of-file is reached on fdupin, then fdupin, fdupout, fddownin, and fddownout should be closed and the message "Close upstream\n" should be sent to fdupmon via header_filter. If an end-of-file is reached on fddownin, then fddownin, fddownout, fdupin, and fdupout should be closed and a message "Close downstream\n" should be sent to fddownmon via header_filter. Do not do any error checking on the close system call. After closing the files the function should return. Do not close the other two file descriptors.

Define two buffers of size 1024, one for the upstream and one for the downstream, and pass these as the info parameter of header_filter. Pass the size of these buffers, 1024, as the last parameter to header_filter. The number 1024 should explicitly appear in your code only once so that it can be easily modified.

Part 3

Write a main program which tests both header_filter and filter. It opens six named pipes for reading and writing: pipe1, pipe2, pipe3, pipe4, pipe5 and pipe6. It then calls filter with the corresponding file descriptors.

In six separate windows, do execute the following commands:

cat > pipe1
cat < pipe2
cat < pipe3
cat > pipe4
cat < pipe5
cat < pipe6
Type into the first window. Anything typed should appear in the third and fifth windows.

Type into the fourth window. Anything typed here should appear in the second and sixth windows.

Part 4

In this part you will modify header_filter so that it processes the data coming in and does not send everything out. Consider the situation in which sometimes ASCII data is transmitted and sometimes binary data is transmitted. We want header_filter to output the ASCII data, but not the binary data.

Simple Solution:Have header_filter separate its data into lines, i.e. blocks delimited by a newline. If a block is small and only contains printing characters (including tabs, carriage returns, form feeds and newlines) then output the line. Otherwise ignore the data in that block. Do not output any very long lines.

Complications:What do you do if there is not a newline at the end of the buffer passed to header_filter. One possibility is to postpone processing that data. This requires having a storage area which is persistent between calls to header_filter and which will not be corrupted by calls to header_filter which are processing a different communication.

Implement this using the storage area passed in the last two parameters to header_filter. You should also ignore all long lines even if they contain only printing characters. You must handle the following situations:

In general, the program should behave as if its buffer space is infinite and lines were not broken up between calls to header_filter.