version 1.1, 2005/02/21 07:24:47
|
version 1.2, 2005/02/25 06:00:58
|
|
|
/*-------------------------------------------------------------------------- | /*-------------------------------------------------------------------------- |
Trivial virtual file system for cabinet conformance test. | Trivial virtual file system for cabinet conformance test. |
|
(C) 2005 Dan Kegel and Rizwan Kassim |
|
LGPL License |
--------------------------------------------------------------------------*/ | --------------------------------------------------------------------------*/ |
| |
#include "tvfs.h" | #include "tvfs.h" |
|
|
#define MAXFNAME 255 | #define MAXFNAME 255 |
#define MAXFLEN 65536 | #define MAXFLEN 65536 |
| |
|
#define TVFS_MAIN |
|
|
|
#ifdef TVFS_MAIN |
|
#include "cabinet_files.h" |
|
#include <fcntl.h> |
|
#endif |
|
|
struct tvfs_file { | struct tvfs_file { |
char fname[MAXFNAME]; | char fname[MAXFNAME]; |
int bytes_used; | int bytes_used; |
|
|
static struct tvfs_fcb *handles[MAXHANDLES]; | static struct tvfs_fcb *handles[MAXHANDLES]; |
int nhandles = 0; | int nhandles = 0; |
| |
|
/* tvfs_create does NOT correspond to _creat - it is an internal function |
|
use to put a file directly into our virtual filesystem. */ |
|
|
int tvfs_create(const char *fname, const char *buf, int len) | int tvfs_create(const char *fname, const char *buf, int len) |
{ | { |
int inode; | int inode; |
struct tvfs_file *f; | struct tvfs_file *f; |
if (nfiles >= MAXFILES) | if (nfiles >= MAXFILES) |
return -1; | return -1; |
|
|
inode = nfiles++; | inode = nfiles++; |
f = calloc(sizeof(struct tvfs_file)); |
/* calloc didn't work here, while malloc did */ |
|
f = malloc(sizeof(struct tvfs_file)); |
strcpy(f->fname, fname); | strcpy(f->fname, fname); |
f->len = len; |
f->bytes_used = len; |
if (buf) | if (buf) |
memcpy(f->buf, buf, len); | memcpy(f->buf, buf, len); |
files[inode] = f; | files[inode] = f; |
|
|
| |
int tvfs_open(const char *fname, int flags, int mode) | int tvfs_open(const char *fname, int flags, int mode) |
{ | { |
|
|
|
/* mode and flags are not handled */ |
int h; | int h; |
int inode; | int inode; |
/* Existing file? */ | /* Existing file? */ |
for (inode=0; inode<nfiles; inode++) { | for (inode=0; inode<nfiles; inode++) { |
if (!files[inode]) | if (!files[inode]) |
continue; | continue; |
if (strcmp(files[inode].fname, fname)) |
if (!strcmp(files[inode]->fname, fname)) |
break; |
break; } |
} |
|
if (inode == nfiles) { | if (inode == nfiles) { |
/* File did not exist */ | /* File did not exist */ |
if ((flags & O_CREAT) == 0) { | if ((flags & O_CREAT) == 0) { |
|
|
} | } |
inode = tvfs_create(fname, 0, 0); | inode = tvfs_create(fname, 0, 0); |
} | } |
h = nhandles++; |
struct tvfs_fcb *handler; |
handles[h].inode = inode; |
handler = malloc(sizeof(struct tvfs_fcb)); |
handles[h].pos = 0; |
handler->inode = inode; |
|
handler->pos=0; |
|
h = nfiles++; |
|
handles[h] = handler; |
return h; | return h; |
} | } |
| |
unsigned int tvfs_read(int h, void *buf, unsigned int len) | unsigned int tvfs_read(int h, void *buf, unsigned int len) |
{ | { |
int inode = handles[h].inode; |
int inode = handles[h]->inode; |
int pos = handles[h].pos; |
int pos = handles[h]->pos; |
|
int size = files[inode]->bytes_used; |
| |
/* FIXME: handle edge cases */ | /* FIXME: handle edge cases */ |
memcpy(buf, files[inode].buf, len); |
/* Edge Case 1 : Request beyond boundary of file */ |
handles[h].pos += len; |
if (pos + len > size) { |
|
len = size-pos; |
|
} |
|
|
|
memcpy(buf, files[inode]->buf+pos, len); |
|
handles[h]->pos += len; |
| |
return len; | return len; |
} | } |
|
|
|
void tvfs_free(){ |
|
int inode; |
|
for (inode=0; inode<nfiles; inode++) { |
|
if (!files[inode]) |
|
continue; |
|
free(files[inode]); |
|
} |
|
} |
|
|
|
|
|
|
|
|
|
#ifdef TVFS_MAIN |
|
static char file_test_txt[] = "This is a test. Don't Panic!"; |
|
static int szfile_test_txt = sizeof(file_test_txt); |
|
|
|
main(){ |
|
int result; |
|
int active_handler; |
|
|
|
char *filebuf; |
|
|
|
char test_filename[] = "test.txt"; |
|
char dummy_filename[] = "dummy.txt"; |
|
char bad_filename[] = "chicken.txt"; |
|
|
|
filebuf = malloc(MAXFLEN); |
|
|
|
printf("Testing TVFS implementation, creating %s\n",test_filename); |
|
result = tvfs_create( dummy_filename, file_test_txt, szfile_test_txt ); |
|
result = tvfs_create( test_filename, file_test_txt, szfile_test_txt ); |
|
printf("Created virtual file with inode %d\n",result); |
|
|
|
/* This test failes because strcmp returns 0 incorrectly! */ |
|
printf("Attempting to open non-existant file\n"); |
|
result = tvfs_open(bad_filename, _O_BINARY, 0 ); |
|
printf("Result code %d\n",result); |
|
printf("Attempting to open existant file\n"); |
|
result = tvfs_open(test_filename, _O_BINARY, 0 ); |
|
printf("Result code %d\n",result); |
|
|
|
active_handler = result; |
|
|
|
memset (filebuf,0,MAXFLEN); |
|
|
|
printf("Testing reading from file %s\n",test_filename); |
|
result = tvfs_read(active_handler, filebuf, 9); |
|
printf("Read _%s_\n", filebuf); |
|
if ( strcmp(filebuf,"This is a")) { |
|
printf("File read check failed!\n"); |
|
} |
|
|
|
printf("Testing sequential reading from file %s\n",test_filename); |
|
result = tvfs_read(active_handler, filebuf, 12); |
|
printf("Read _%s_\n", filebuf); |
|
if ( strcmp(filebuf," test. Don't")) { |
|
printf("File read check failed!\n"); |
|
} |
|
|
|
printf("Testing edge reading from file %s\n",test_filename); |
|
result = tvfs_read(active_handler, filebuf, 20); |
|
printf("Read %d bytes - _%s_\n", result, filebuf); |
|
if ( result != 8 ) { |
|
printf("File read check failed!\n"); |
|
} |
|
|
|
|
|
|
|
|
|
|
|
tvfs_free(); |
|
free(filebuf); |
|
|
|
} |
|
|
|
#endif |