Files
uiuc-ece391-mp3/student-distrib/fs/unified_fs.c

174 lines
6.9 KiB
C

#include "unified_fs.h"
#include "ece391fs.h"
#include "../devices/keyboard.h"
#include "../devices/rtc.h"
#include "../devices/tux.h"
#include "../devices/cpuid.h"
#include "../devices/sb16.h"
#include "../devices/cmos.h"
#include "../devices/rng.h"
#include "../devices/mouse.h"
/* int32_t unified_init(fd_array_t* fd_array)
* @input: fd_array - pointer to a file descriptor array
* @output: ret val - SUCCESS / FAIL
* fd_array - initialized with stdin and stdout created
* @description: Initialize file descriptor array.
*/
int32_t unified_init(fd_array_t* fd_array) {
if(fd_array == NULL) return FAIL;
// Initialize array to prevent page fault
int i = 0;
for(i = 0; i < MAX_OPEN_FILES; i++) {
fd_array[i].interface = NULL;
fd_array[i].inode = 0;
fd_array[i].pos = 0;
fd_array[i].flags = 0;
}
fd_array[FD_STDIN].interface = &terminal_stdin_if;
fd_array[FD_STDOUT].interface = &terminal_stdout_if;
return SUCCESS;
}
/* int32_t unified_open(fd_array_t* fd_array, const char* filename)
* @input: fd_array - file descriptor array
* filename - file to be opened
* @output: ret val - FAIL / file descriptor id
* fd_array[fd] - FS interface set, pos set to 0
* @description: Uses correct FS driver to open a file, generate a file descriptor,
* write the descriptor into fd_array, and returns the descriptor.
* If filename is "tux", it will open the Tux Controller.
* If filename is "stdin", it will open STDIN (typically not needed).
* If filename is "stdout", it will open STDOUT (typically not needed).
* Otherwise it depends on file type in ECE391FS, file/folder/RTC.
*/
int32_t unified_open(fd_array_t* fd_array, const char* filename) {
if(NULL == fd_array) return FAIL;
if(NULL == filename) return FAIL;
// Try to allocate index in file descriptor array
int fd = 0;
while(fd < MAX_OPEN_FILES && fd_array[fd].interface != NULL) fd++;
if(fd >= MAX_OPEN_FILES) return FAIL;
ece391fs_file_info_t finfo;
if(NULL == filename) {
return FAIL;
} else if(0 == strlen(filename)) {
return FAIL;
} else if(0 == strncmp("tux", filename, 4)) {
// Trying to open Tux Controller
fd_array[fd].interface = &tux_if;
} else if(0 == strncmp("stdin", filename, 6)) {
// Trying to open STDIN
fd_array[fd].interface = &terminal_stdin_if;
} else if(0 == strncmp("stdout", filename, 7)) {
// Trying to open STDOUT
fd_array[fd].interface = &terminal_stdout_if;
} else if(0 == strncmp("cpuid", filename, 6)) {
// Trying to open CPUID
fd_array[fd].interface = &cpuid_if;
} else if(0 == strncmp("cpuinfo", filename, 8)) {
// Trying to open CPUID
fd_array[fd].interface = &cpuid_if;
} else if(0 == strncmp("aux", filename, 4)) {
// Trying to open Sound Blaster 16
fd_array[fd].interface = &sb16_if;
} else if(0 == strncmp("date", filename, 5)) {
// Trying to open CMOS
fd_array[fd].interface = &cmos_if;
} else if(0 == strncmp("rng", filename, 4)) {
// Trying to open CMOS
fd_array[fd].interface = &rng_if;
} else if(0 == strncmp("mouse", filename, 6)) {
// Trying to open CMOS
fd_array[fd].interface = &mouse_if;
} else if(SUCCESS == read_dentry_by_name((char*) filename, &finfo)) {
// File exists in ECE391FS
switch(finfo.type) {
case ECE391FS_FILE_TYPE_FILE:
fd_array[fd].interface = &ece391fs_file_if;
break;
case ECE391FS_FILE_TYPE_FOLDER:
fd_array[fd].interface = &ece391fs_dir_if;
break;
case ECE391FS_FILE_TYPE_RTC:
fd_array[fd].interface = &rtc_if;
}
} else {
return FAIL;
}
if(NULL == fd_array[fd].interface->open) return FAIL;
if(FAIL == (*fd_array[fd].interface->open) (&fd_array[fd].inode, (char*) filename)) {
fd_array[fd].interface = NULL;
return FAIL;
}
fd_array[fd].pos = 0;
return fd;
}
/* int32_t unified_read(fd_array_t* fd_array, int32_t fd, void* buf, int32_t nbytes)
* @input: fd_array - file descriptor array
* fd - file descriptor id
* buf - buffer to be written with file content
* nbytes - number of bytes to be read from file
* @output: ret val - SUCCESS / FAIL
* buf - written with file content
* @description: Unified read function, calls corresponding FS function to do the actual reading.
*/
int32_t unified_read(fd_array_t* fd_array, int32_t fd, void* buf, int32_t nbytes) {
if(NULL == fd_array) return FAIL;
if(fd < 0 || fd >= MAX_OPEN_FILES) return FAIL;
if(fd_array[fd].interface == NULL) return FAIL;
if(NULL == fd_array[fd].interface->read) return FAIL;
return (*fd_array[fd].interface->read) (&fd_array[fd].inode, &fd_array[fd].pos, (char*) buf, nbytes);
}
/* int32_t unified_write(fd_array_t* fd_array, int32_t fd, void* buf, int32_t nbytes)
* @input: fd_array - file descriptor array
* fd - file descriptor id
* buf - buffer to be read from for data to be written
* nbytes - number of bytes to be write to file
* @output: ret val - SUCCESS / FAIL
* file written with data from buf
* @description: Unified write function, calls corresponding FS function to do the actual writing.
*/
int32_t unified_write(fd_array_t* fd_array, int32_t fd, const void* buf, int32_t nbytes) {
if(NULL == fd_array) return FAIL;
if(fd < 0 || fd >= MAX_OPEN_FILES) return FAIL;
if(fd_array[fd].interface == NULL) return FAIL;
if(NULL == fd_array[fd].interface->write) return FAIL;
return (*fd_array[fd].interface->write) (&fd_array[fd].inode, &fd_array[fd].pos, (const char*) buf, nbytes);
}
/* int32_t unified_ioctl(fd_array_t* fd_array, int32_t fd, int32_t op)
* @input: fd_array - file descriptor array
* fd - file descriptor id
* op - operation id
* @output: runs ioctl handler for the file
* @description: Runs ioctl handler for a file.
*/
int32_t unified_ioctl(fd_array_t* fd_array, int32_t fd, int32_t op) {
if(NULL == fd_array) return FAIL;
if(fd < 0 || fd >= MAX_OPEN_FILES) return FAIL;
if(fd_array[fd].interface == NULL) return FAIL;
if(NULL == fd_array[fd].interface->ioctl) return FAIL;
return (*fd_array[fd].interface->ioctl) (&fd_array[fd].inode, &fd_array[fd].pos, op);
}
/* int32_t unified_close(fd_array_t* fd_array, int32_t fd)
* @input: fd_array - file descriptor array
* fd - file descriptor id
* @output: fd_array[fd] interface removed
* @description: Closes a file.
*/
int32_t unified_close(fd_array_t* fd_array, int32_t fd) {
if(NULL == fd_array) return FAIL;
if(fd < 0 || fd >= MAX_OPEN_FILES) return FAIL;
if(fd_array[fd].interface == NULL) return FAIL;
if(NULL == fd_array[fd].interface->close) return FAIL;
if(FAIL == (*fd_array[fd].interface->close) (&fd_array[fd].inode)) return FAIL;
fd_array[fd].interface = NULL;
return SUCCESS;
}