The page fault handler does not tell you directly. What you need to do is look at the existing permissions on the page, and conclude that the fault is due to the missing permission. If the page has no permissions, you should add the PROT_READ permissions and return. If the page has PROT_READ, then you should add PROT_WRITE and continue. (PROT_EXEC shouldn't happen in this assignment.)
Just make the "disk" object a global variable, and call disk_read and disk_write from the page replacement handler.
Call page_table_get_entry(page,&frame,&bits). If the given page has non-zero permission bits, then it resides in the indicated frame number. If the permission bits are zero, then it is not in memory, and the frame number is irrelevant.
Yes, you should create a frame table that keeps track of the state of each frame. That will make it easy to find a free frame for replacement.
No, if you use the same random number generator, it will throw off the reproducibility of the results. Use lrand48() to generate random numbers for your page fault handler, and do not call srand or rand at all.
In a real operating system, the contents of a page should initially be all zeroes. As it turns out, it does not matter for this project, since each program fills in each page with its own data before attempting to read it.
There was a bug in the original version of focus: the total variable was not initialized to zero. Download a new version of program.c, and all will be well.