Assignment 5, due Sept. 30
Part of
the homework for 22C:112, Fall 2013
|
On all assignments, your name must be legible as it appears on your University ID card! Assignments are due at the start of class on the day indicated (usually Friday). Exceptions will be by advance arrangement unless there is what lawyers call "an act of God" (something outside your control). Homework must be turned in on paper, either in class or in the teaching assistant's mailbox. Never push late work under someone's door!
A problem In what order do the above steps happen? (The first and final steps above are given in the correct order.) (0.5 points)
#define COM1DATA 0x3F8 #define COM1LSR 0x3FD #define RxRD (1 << 0) #define RxOE (1 << 1) /* overrun error */ #define RxPE (1 << 2) /* parity error */ #define RxFE (1 << 3) /* framing error */ #define RxBR (1 << 4) /* break */ #define TxDE (1 << 5) #define TxID (1 << 6)
Overrun error indicates that new data arrived before the previous data was read. The old data is lost, but the received data in COM1DATA is valid. In the case of parity and framing errors, the data in COM1DATA is not valid. parity and framing errors, the data in COM1DATA is not valid. The break condition does not itself represent an error, but is an auxilary indicator indicating that an overrun error was very long.
As in the notes, assume that you can use inp(r) to read data from device register r and outp(r,d) to output the data d to device registerr.
a) Write getcom1(), a routine to directly implement a read from com1, ignoring the possibility of error. Keep it simple! Minimize your code. Few or no comments are needed. (0.5 points)
b) Revise your solution to part a) so that, in the event that the COM1DATA is invalid because of an error, the invalid value is ignored. That is, in the event of such an error, getcom1() should continue to wait for valid input. (0.5 points)
typedef struct file { int fd; int count; int size; char * buf; } FILE; #define putc(ch,f) ( \ buf[ f->count++ ] = ch \ f->count >= f->size?( \ write( f->fd, f->buf, f->size ), \ f->count = 0 \ ):( \ 0 \ ), \ ) #define putchar(ch) (putc( ch, stdout )) void fputc( char ch, FILE * f ) { putc( ch, f ); }
In C, source lines ending with backslash (\) are concatenated to the following line. This allows a #define to span multiple lines. In C, expressons of the form (a?b:c) are conditional; if In C, expressons of the form a is true, the value is b, otherwise, the value is c. In C, x->y refers to the field named y of the structure pointed to by the pointer x.
a) When a file f is opened for output, what is the correct initial value for f->count? (0.5 points).
b) Why not use a constant size for the buffer? That is, why would it be useful to wait until the file is opened to decide what size buffer to allocate? (0.5 points).
c) Give an appropriate implementation of fflush() for this implementation of files. (Ignore the special behavior defined for a null parameter.)
You will have to modify a version of mush.c as modified by the requirements of mp2. If you have not solved mp2 yourself, you should do so even if you end up using the MP2 solution distributed to the class.
Modify mush.c so support the following features:
You may need to look up and understand the man page for each routine you use. Your solution should conform, as much as is reasonable, to the manual of style. Your solution must be in a file named mp3.c and you should submit it using the coursework submission tools, as for mp1 and mp2 but in the mp3 directory for the course.
Here are some comments in response to questions I received after class:
The syntax of your shell command should be setenv VAR value (with no additional arguments, and certainly not an "overwrite" argument). Do not worry about the complex behavior of setenv with no arguments. Your concern is using it to set the value of environment variables.
Note that after using the shell command setenv VAR value, echo $VAR should output value. After setenv VAR, with no value given, then $VAR is replaced with an empty string. This is not the same as $VAR being undefined.
Play with the existing shell? What does it do with echo $WHOZZIT (where the shell variable WHOZZIT is an example of an undefined variable). Your shell should do something similar.
How does it work for blank lines? They are ignored by the standard Unix shells, and the solution distributed for MP2 also ignores them (more by accident than by design). Your solution should continue to ignore them, but this may take an added line of code, since the string comparison to test for built-in commands is likely to need the first pointer in argv to be non-null.
The strings package (the one containing strcat() and strlen() also contains strcmp() for comparing strings. strcmp(a,b) returns zero (false) if the strings are identical and nonzero (true) if they are not identical.