360 Project HELP
READ Chapter 11.9.2 - 11.9.3
HOW TO open_close_lseek
------------------------ in type.h file -------------------------------------
typedef struct proc{ | typedef struct oft{ // OpenFileTable
struct proc *next; | int mode; // R|W|RW|APP
int pid; | int shareCount;
int ppid; | MINODE *minodeptr;
int uid, gid; | int offset;
MINODE *cwd; | }OFT;
| OFT oft[32]; // oft structs
OFT *fd[NFD]; ==============> opened oft's of this process
}PROC; |
----------------------------------------------------------------------------
| GLOBAL in main.c file: OFT oft[32];
// Initialization: fd[] of every PROC = 0; // no opened file yet
// shareCount of every oft = 0; // FREE
Open File Data Structures:
running
|
| ||******************
PROC[ ] OFT[32] MINODE[64] || Disk dev
=========== |---> ============ ---> ============= || ===============
|nextPtr | | |mode | | | INODE | || | INODE
|pid, ppid| | |shareCount| | | ------- | || ===============
|uid, gid | | |minodeptr |--> | dev,ino | ||
|cwd | | |offset | | cacheCount| ||******************
| | | ====|======= | shareCount|
|fd[10] | | | | modified |
| ------ | | | | id |
0 | ----->|->| | =============
| ------ | |
1 | | |
| ------ | --------------------------------
2 | | |0123456.............
| ------ | --------------------------------
=========== logical view of file: a sequence of bytes
int open_file()
{
1. ASSUME open pathname mode # mode = 0|1|2|3 for R|W|RW|APPEND
2. get pathname's minode pointer:
MINODE *mip = path2inode(pathname);
3. if (!mip){ // pathname does not exist:
if (mode==0) // READ: file must exist
return -1;
// mode=R|RW|APPEND: creat file first
creat_file(); // make sure YOUR creat_file() use pathname
mip = pathn2inode(pathname);
// print mip's [dev, ino]
}
4. check mip->INODE.i_mode to verify it's a REGULAR file
Check whether the file is ALREADY opened with INCOMPATIBLE mode:
If it's already opened for W, RW, APPEND : reject.
that is, only multiple READs of the SAME file are OK
4. allocate a FREE OpenFileTable (OFT) and fill in values:
oftp->mode = mode; // mode = 0|1|2|3 for R|W|RW|APPEND
oftp->shareCount = 1;
oftp->minodeptr = mip; // point at the file's minode[]
5. Depending on the open mode 0|1|2|3, set the OFT's offset accordingly:
switch(mode){
case 0 : oftp->offset = 0; // R: offset = 0
break;
case 1 : truncate(mip); // W: truncate file to 0 size
oftp->offset = 0;
break;
case 2 : oftp->offset = 0; // RW: do NOT truncate file
break;
case 3 : oftp->offset = mip->INODE.i_size; // APPEND mode
break;
default: printf("invalid mode\n");
return(-1);
}
7. find the SMALLEST index i in running PROC's fd[ ] such that fd[i] is NULL
Let running->fd[i] point at the OFT entry
8. update INODE's time field
for R: touch atime.
for W|RW|APPEND mode : touch atime and mtime
mark Minode[ ] MODIFIED
9. return i as the file descriptor
}
NOTE that the mip of an opened file is NOT iput().
It will be iput() when the file descriptor is closed
int truncate(MINODE *mip)
{
1. release mip->INODE's data blocks; // SAME as print data blocks in LAB6
a file may have 12 direct blocks,
256 indirect blocks and
256*256 double indirect data blocks.
release them all.
2. update INODE's time fields
3. set INODE's size to 0 and mark minode MODIFIED
}
int close_file(int fd)
{
1. verify fd is within range.
2. verify running->fd[fd] is pointing at a OFT entry
3. The following code segments should be obvious:
oftp = running->fd[fd];
running->fd[fd] = 0;
oftp->shareCount--;
if (oftp->shareCount > 0)
return 0;
// last user of this OFT entry ==> dispose of its minode
mip = oftp->inodeptr;
iput(mip);
return 0;
}
int lseek(int fd, int position)
{
From fd, find the OFT entry.
change OFT entry's offset to position but make sure NOT to over run either end
of the file.
return originalPosition
}
int pfd()
{
This function displays the currently opened files as follows:
fd mode offset INODE
---- ---- ------ --------
0 READ 1234 [dev, ino]
1 WRITE 0 [dev, ino]
--------------------------------------
to help the user know what files has been opened.
}
====================================================================
Other Simple FILE DESCRIPTOR operations:
dup(int fd):
{
verify fd is an opened descriptor;
duplicates (copy) fd[fd] into FIRST empty fd[ ] slot;
increment OFT's shareCount by 1;
}
dup2(int fd, int gd):
{
CLOSE gd fisrt if it's already opened;
duplicates fd[fd] into fd[gd];
increment OFT's shareCount by 1;
}
As you already know, these are needed for I/O redirections