Use the cover sheet in /usr/local/courses/cs3733/spring2000/cover1.ps as the first sheet when handing in your assignment. Make sure you include your makefile and lint output. Use separate directories for Parts 1 and 2 of this assignment so that you can keep the Part 1 source code while you are testing Part 2. Keep all source code created for this course until you have received your final grade for the course. is over.
Part 1. Safe readln
One of the majors causes of security problems on Unix systems is buffer
overrun. This problem occurs when a finite size buffer is allocated for
input, the input is too large for the buffer, and this condition is not
tested for. It can cause parts of the program to be overwritten, sometimes
allowing a malicious user to execute arbitrary code.
Write a function:
char *readln(int fd)
which takes an open file descriptor as a parameter and reads in a
line from that file descriptor. It returns the line read as a string
which will
normally have the newline as the last character. If an end-of-file is
reached before any characters have been read, or if a memory
allocation error occurs, a NULL is returned.
Otherwise, if an end-of-file is reached the string returned will not
have a newline as the last character.
The readln function allocates space needed for the string. You may not make any assumptions about the length of the line. One solution is to malloc a certain amount of space and do a larger malloc if the original one was too small. The initial buffer size should be a symbolic constant. Test your program will small values of the buffer size to make sure it is working correctly. Your functions should not have any memory leaks.
Write a main function (in a separate file called testread.c) to test your readln. The main program will call readln repeatedly for standard input until a NULL is returned, and output the results to standard output. The main program should free the space generated by readln. The main program should also identify the programmer with a line sent to standard error. All other output should go to standard output. Test your program by redirecting the input to come from a file and redirecting the output to go to a file. Use diff to check that the input and output are identical.
Part 2.
Part 1 assumes that there are no 0 bytes in the input stream.
Modify your readln so that it ignores zero bytes in the input stream.
Add static variables to your readln file to keep track of the number
of lines read, the length of the longest
line read, the maximum number of memory allocations
needed to process a line, and the size of the largest input buffer used.
The length of the line should include the newline at the end.
Add functions to this file to return these values and the initial buffer
size. Modify your main program so that it reports to standard error
these values with descriptive phrases. For example, running the main
program should produce output like the following:
testread < infile > outfile This program was written by Steven Robbins Initial buffer size: 10, largest buffer size: 160 Maximum number of mallocs: 5 Number of lines: 58, longest line: 80Test your program with the infile available in /usr/local/courses/cs3733/spring2000/infile and hand in the output generated. Run diff on the infile and outfile to show that they are identical.