Basic OS Infrastructure


Project Due Date: Tuesday, February 5 by 11:59 PM


Objective
The basic purpose of this assignment is to familiarize you with the basics of C programming. This will include syntax as well as pointers. To accomplish this goal, you will be required to construct and manage a sorted linked list. Another major objective of this project is for you to create the basic infrastructure for a mock operating system that you will use throughout the rest of the semester to test and program various operating system functions. Much of the code you create here will be used for all of your other projects, so a thorough design should be developed before any coding begins. This will help to insure good integration into future projects.

Project Description
You will actually be required to write two separate programs. One is to provide requests and the other is to sort these requests. The names of these two programs should be process.c and os.c. While these names do not necessarily apply to the purpose of these programs at this time, the reason for the names should become clear in future assignments.

The first program, process.c, should read integers from a file and communicate them to the second program, os.c. This communication will be done by means of interprocess communication. The means of facilitating this communication will be discussed in detail in the next section. The data being extracted from the file by process.c should be checked for correctness. Any invalid data should simply be ignored. No error messages should be printed and the program should not terminate. The program should most definitely not crash from the introduction of such invalid data. The program should just go on to the next line of data as if nothing had happened. A sample data file is provided here. When the last piece of data has been read by process.c, the program should send an END message to os.c indicating no more data is to be expected.

The os.c program should accept the integers communicated from process.c and place them into a linked list data structure in ascending order. It should also record the time at which each integer was received. The timer should not start until the first message is received. In other words, the first message received will always be at time zero. All the other times will be relative to this. Times should be given in milliseconds. Upon receipt of the END message, os.c should print out the following information to the standard output:

A sample of the output is provided here. This output file is for the data file shown previously. The times are completely made up and should not be considered indicative of your program.

You should NOT hard code the name of the FIFO file into your code (for more information on what this means, read the next section). Rather, both programs should accept the name of the FIFO file to communicate through as one of the command line options. This will allow us to create any arbitrary FIFO file and make your program communicate through it.

Additionally, the process.c program should accept the name of the file to read data from. The following are the sample usages for both of the programs you right. Your program executables should both be named exactly as shown here: process fifoFile dataFile
os fifoFile

Interprocess Communication (IPC)
Before describing one way to do IPC, it should be made clear that if you have a preferred method for communicating between processes (pipes, sockets, etc.), feel free to use that method. The method that will be presented in this section is named pipes. This is often referred to as FIFO communication.

Basic Idea
A named pipe is really just a special kind of file (a FIFO file) on the local hard drive. Unlike a regular file, a FIFO file does not contain any user information. Instead, it allows two or more processes to communicate with each other by reading/writing to/from this file.

Creating a FIFO File
The easiest way to create a FIFO file is to use the mkfifo command. This command is part of the standard Linux utilities and can simply be typed at the command prompt of your shell. You may also use the mknod command to accomplish the same thing. This command requires an additional argument but otherwise it works pretty much the same. To learn more about these commands check out the man pages on them (just type man mkfifo or man mknod at the shell command prompt). The following example shows one way to use the mkfifo command:

prompt> mkfifo /tmp/myFIFO

That's it! It's pretty simple to set a file up for FIFO. There is also a system call that allows you to do this so you can put it in a program. You can read about that on your own if you would like.

Using a FIFO File
Using a FIFO file is slightly more difficult than creating one but not much - once you get familiar with how to make system calls. Because this named pipe looks like a file, you can use all the system calls associated with files to interact with it. In particular, you can use the open, read, write, and close system calls. The following are prototypes for each of these calls as you will need to use them.

To understand better what each of the return values and parameters are for, check each of these system calls out by looking at their respective man pages. Be sure to use the 2nd level of the man pages (type man 2 open, for example); otherwise, you may see something quite different than what you expect.

To give you an idea of how all of these can work together, here is a breif snippet showing how a sender might set up a connection and send a message.

#include <sys/types.h>
#include <sys/stat.h>
#include <unistd.h>
#include <fcntl.h>
#include <stdio.h>
#include <stdlib.h>
#include <errno.h>

#define MAX_LINE 80

int main(int argc, char** argv) {
   char line[MAX_LINE];
   int pipe;

   // open a named pipe
   pipe = open("/tmp/myFIFO", O_WRONLY);

   // get a line to send
   printf("Enter line: ");
   fgets(line, MAX_LINE, stdin);

   // actually write out the data and close the pipe
   write(pipe, line, strlen(line));

	// close the pipe
   close(pipe);
   return 0;
}

Reading from the pipe is very similar. You need to open it up, use the read call to read information, and then close the pipe when everything is finished. More details on this process can be found on-line or by browsing various man pages.

Error Checking
Part of your overall grade will be based on your programs' robustness. This means error checking and handling. The checking of valid data in the input file presented to process has already been discussed. Besides this, your program should make sure to validate the command line presented by the user. If an error is detected, a message displaying the proper usage should be printed and the program terminated. All system calls should also be checked for a valid return value. If an error is detected, it should be handled appropriately. For example, if the user enters a FIFO file that does not exist, your program should indicate this error and terminate. Obviously the sample code provided above does not do this. Your code should.

Grading
No late assignments will be accepted. This project is due at 11:59 PM on February 5.

This assignment will be graded based on correctness of implementation as well as robustness. To this end, we will not just be looking at the output of your program, but also the code. You will also be deducted points if all the proper files are not submitted. In this case, the mininum files will be process.c, os.c, a Makefile, and a README file describing your program.

Handing in Your Project
The directory for handing in your program can be found at:

/p/course/cs537-mattmcc/public/section2/username/p1

Obviously, you should submit all *.c and *.h files that are needed to compile your program. You should also include a README file and a Makefile for this project. Your README file should contain information about how to run your program, any known bugs it may have, and any other information that is important to your project. Your make file should successfully compile the program and create the process and os executables.

Also, be sure to comment your code well so that it can be easily browsed to see what is going on. Code that is excessively difficult to read will be penalized.