CS 3733 Operating Systems, Spring 2004 Assignment 1


Due Thursday, February 5, 2003

Assignment 1 has 11 parts, but most of them are short.

The purpose of this assignment is to test your programming skills and to prepare you for future assignments.

Each time you start a new even numbered part of this assignment, create a new directory. When you are finished, you should have an assign1 directory with subdirectories part0, part2, part4, part6, part8 and part10. When creating one of these directories, start by copying into it the contents of the previous directory.

Obtaining help
You are to do this assignment on your own, but you may ask me for help at any time. The earlier you start the assignment, the more help will be available. You may obtain help from me before or after class, by coming to my office, or by email.

Read through the entire assignment and look at the cover sheet before writing any code. You will be graded not only on the correctness of your programs, but their clarity and the methods you used for testing.


Part 0:
The following describes what is meant by a valid program description line.

Notice that a valid program description line is not a string. It does not have to be terminated by a null character.

Also, when accessing a program description line, you may not access the character before the start of the line or any characters after the newline.

Write a function:
int valid_program_line(char *s)
That returns 1 if s points to the start of a valid program description line and returns 0 otherwise. This function should have no side effects. It may not modify the array pointed to by s and it may not perform any I/O.
Put the function in a file called program_utility.c.

Write the function in such a way that it is easy to understand what it does.

Part 1:
Create a file called program_utility.h that contains prototypes for the public functions in program_utility.c. As you add functions to program_utility.c, update program_utility.h.

Write a main program to test valid_program_line and test it as well as you can. The main program should be in its own file called test_valid_program_line.c. Use a makefile with separate compilation to compile and link test_valid_program_line.c and program_utility.c. Both program_utility.c and test_valid_program_line.c should include program_utility.h.

As part of your testing, you should always run lint on your programs. Perform one lint on all modules that are compiled together. For each of the test programs you write for this part and the following parts save the lint output as you will need to turn it in with your assignment. The following lint warnings are usually OK:
function returns value which is always ignored
function returns value which is sometimes ignored
For all other lint warnings, write a brief statement on your lint output page about what you think the lint warning means.

Part 2
Write a function:
int get_program_number(char *s)
that takes a valid program description line as a parameter and return the program number. The function will not modify the program description line.

Part 3:
Write a main program to test get_program_number and test it as well as you can. The main program should be in its own file called test_get_program_number.c. Modify the makefile from Part 1 to also use separate compilation to compile and link test_get_program_number.c and program_utility.c.

Part 4
Write a function:
int get_filename_length(char *s)
that takes a valid program description line as a parameter and returns the number of characters in the program filename. This program should have no side effects.

Part 5:
Write a main program to test get_filename_length and test it as well as you can. The main program should be in its own file called test_get_filename_length.c. Modify the makefile to also use separate compilation to compile and link test_get_filename_length.c and program_utility.c.

Part 6
Write a function:
int copy_filename(char *filename, int filenamesize, char *s)
that takes three parameters. The first is a pointer to a buffer for storing a string representing a file name, the second is the size of this buffer, and the last is a valid program description line. If the filename of the program description line will fit in the filename buffer (as a string) it is copied into the buffer along with a string terminator. In this case the function returns 0 indicating success. Otherwise, -1 is returned and errno is set to EINVAL. In either case the program description line is not changed.

Part 7:
Write a main program to test copy_filename and test it as well as you can. The main program should be in its own file called test_copy_filename.c. Modify the makefile to also use separate compilation to compile and link test_copy_filename.c and program_utility.c.

Part 8:
Write a function:
int read_file(char *filename, char *buf, int bufsize)
that reads the file filename into the buffer buf which has size bufsize. The function should first determine the size of the file using the get_filesize function from Recitation 1 and make sure that it will fit in the buffer. If get_filesize fails, return -1 with errno set by get_filesize. If the file will not fit in the buffer, return -1 with errno set to EINVAL. Open the file and return -1 with errno appropriately set if this fails. Read the entire file into buf using read. If read returns -1, return -1 with errno set appropriately. Otherwise, return the size of the file.

Part 9:
Write a main program to test read_file and test it as well as you can. Put get_filesize in program_utility.c. The main program should be in its own file called test_read_file.c. Modify the makefile to also use separate compilation to compile and link test_read_file.c and program_utility.c

Part 10:
Write a main program called show_programs.c that takes one command line argument. The command line argument is interpreted as a file name. The file will contain program description lines. All output generated by this program other than the contents of the file in item 7 goes to standard error. The file is sent to standard output. The program does the following:

  1. Print a message to standard error showing your name, something like:
    This program was written by ...
  2. Check to make sure the program has exactly one command line argument and print a usage message and exit if it does not.
  3. Determine the size of the file, allocate space and read in the file. Print an appropriate error message and exit it an error occurs.
  4. Check to see that the file ends in a newline. If not, print an appropriate error message and exit.
  5. Check to see that all lines of the file are valid program description lines. If a line is found that is not valid, print an appropriate error message, display the line that is invalid, and exit the program.
  6. Print the contents of the file.
  7. Prompt for and read an integer from standard input. Use something like:
    scanf("%d",&val);
    If the value corresponds to one of the program numbers, print a confirming message, read in the corresponding file and print it to standard output. Otherwise, display an appropriate message.
  8. Exit the program.
The program should not make any assumptions about the maximum length of a file name or the maximum size of a file, other than that these can be stored in an int. You should check for errors any time an error can occur (for example when you call malloc) and take the appropriate action. If the main program detects an error, the appropriate action is usually to display an error message and exit. When another function detects an error, tha appropriate action is usually to return an error code to the calling program without displaying an error message.

Describe how you tested this function.


Handing in your program:
Use this cover sheet. Consecutively number all of the other pages you turn in. Each page that contains your work should have a number on it. Turn this in at the beginning of lecture on the due date.