Assignment 5, due Feb. 17

Part of the homework for 22C:112, Spring 2012
by Douglas W. Jones
THE UNIVERSITY OF IOWA Department of Computer Science

On every assignment, write your name legibly as it appears on your University ID and on the class list! Assignments are due at the start of class on the day indicated (usually Friday). Exceptions will be by advance arrangement unless there is what insurance companies call "an act of God" (something outside your control). Homework must be turned in on paper, either in class or in the instructor's mailbox. Never push late work under someone's door!

  1. Background: In Unix-derived systems, files may be marked as "close on exec", but if they are not marked as such, they remain open when one program uses execve() (or any other flavor of exec) to launch another program. This is how access to standard input and standard output are passed to new programs.

    When a program uses fork(), the parent and child share the same open files, but when the child used open() or close(), this has no effect on the parent.

    Kernel files in Unix are opened by open(), closed by close() and read and written by read() and write(). The standard stream model of languages like C and Java is implemented by user-level library code. At the kernel interface level, open() returns an integer that is used as the file handle, and the other operations on files take this integer as a parameter in order to know what file to operate on. stdin (standard input) uses the integer file handle 0, stdout (standard output) uses the integer file handle 1, and stderr (standard error) uses the integer file handle 2. When you open a new file, by definition, the integer used as a file handle will be the lowest integer not currently associated with an open file. If the system permits you to have at most 32 open files, the file numbers will always be in the range 0 to 31, as a result.

    Note, for further information on these kernel calls, use man 2 xxx (the 2 prevents the man command from telling you about shell commands with the same name).

    a) Why does close(1);open(f); reliably reset stdout to file f. (0.6 points)

    b) In the C (and C++) stream model, the analogs of open() and close() are fopen() and fclose(), but the designers of the stream abstraction added freopen(). Is there something about the stream abstraction that forced this (really sensible) addition, or was it added just for aesthetic reasons. (0.6 points)

  2. Background: In a bounded buffer, enqueue and dequeue can be coded as follows:
    enqueue(ch){
       tail = (tail + 1) % bufsize;
       buffer[tail] = ch;
    }
    dequeue(){
       head = (head + 1) % bufsize;
       return buffer[head];
    }
    

    a) With this buffer implementation when head and tail are equal, either the buffer is full, or it is empty. Briefly give two alternative ways to distinguish the full and empty conditions, and discuss their relative merits. One or both solution may require adding code to the enqueue() and dequeue() routines, but you need not write out the code if you can describe it compactly.. (0.6 points)

    b) Consider the limiting case where the buffer size is exactly one. Give concise code for enqueue(), dequeue() full(), and empty() in this case. The total code required is very small. (0.6 points)

  3. Background: If we take an object oriented perspective on I/O, the natural thing to do is define a class "stream" with methods "put" and "get", and then define a subclass for each type of stream device, a keyboard stream, a mouse stream, an asynch comm port stream, a parallel port stream, and so on. Some of these devices don't fit the stream model very well. The comm port, for example, needs methods added for changing the baud rate and data format.

    The Unix system, which is decidedly non object-oriented, handles this problem with some very odd extra I/O kernel calls such as ioctl() and fcntl().

    Background: How should these device specific operations be handled in a purely object-oriented world? (0.6 points)

Machine Problem III

Due Monday, Feb. 27.

Modify the mush.c Minimally Usable SHell so that it supports I/O redirection. The occurance of either the > or < symbols terminates the list of arguments to the current command and indicates a file name for I/O redirection. > preceeds the name of the new output file, and < preceeds the name of the new input file. Blanks may preceed or follow file names. You may start with your solution to MP2 so long as it still works with command names that are absolute path names, or you may revert to the original.

To implement this, your modified version of mush will need to extend the parsing of the command line to identify the redirection file names, if they are present. Inside launch(), before execing the indicated command, you must try to open the redirected files (if present). If either file name is present and cannot be opened, an error message should be output to standard error and the command should not be execed.

To do this, it will have to concatenate each component with a / character, and the value of argv[0]. The strncat() or strcat() library routine can be used for this does this. Note that these concatenation routines do not allocate a new buffer, so if you want to concatenate, you must first make sure that you have a buffer big enough to hold the result.

Note that your solution will be graded on two different issues:

You are not responsible for improving the (awful) quality of the parts of mush you have been given, but you must make sure that all of the code you add is written very well. The programming guidelines in the Manual of style for C programmers should be followed in all code you add, and in modifying the program header to reflect changes you have made.

Submit your solution using the coursework submission tools documented at:

-- http://www.divms.uiowa.edu/help/msstart/submit.html

In short, you will type the shell command submit, with no arguments, and when it prompts for a file name, you will type mush.c, and then an extra carriage return to indicate that there is only one file in your submission. When it prompts for a course, type c_112 and finally, when it prompts for an assignment directory, enter mp3.