version 1.7, 2005/02/27 05:21:08
|
version 1.8, 2005/02/27 09:37:56
|
|
|
#include "tvfs.h" | #include "tvfs.h" |
#include <string.h> | #include <string.h> |
| |
/* This is extremely cheezy. Everything is preallocated per file. */ |
|
|
|
#define MAXFILES 10 | #define MAXFILES 10 |
#define MAXHANDLES 10 | #define MAXHANDLES 10 |
#define MAXFNAME 255 | #define MAXFNAME 255 |
#define MAXFLEN 65536 | #define MAXFLEN 65536 |
| |
/* |
|
#define TVFS_MAIN |
|
*/ |
|
#include <fcntl.h> | #include <fcntl.h> |
#include <stdlib.h> | #include <stdlib.h> |
#include <stdio.h> | #include <stdio.h> |
#include <malloc.h> | #include <malloc.h> |
|
#include <stdio.h> |
|
#include <stdarg.h> |
|
|
/* | /* |
#define DEBUG |
#define TVFS_MAIN |
|
#define TVFS_DEBUG |
*/ | */ |
|
|
#define SEEK_SET 0 | #define SEEK_SET 0 |
#define SEEK_CUR 1 | #define SEEK_CUR 1 |
#define SEEK_END 2 | #define SEEK_END 2 |
| |
|
#ifndef _O_BINARY |
|
#define _O_BINARY 0 |
|
#endif |
|
|
|
#ifndef STANDALONE |
|
#else |
|
static void trace(const char *s, ...) |
|
{ |
|
va_list elipsis; |
|
va_start (elipsis, s); |
|
vprintf(s, elipsis); |
|
va_end(elipsis); |
|
} |
|
#endif |
|
|
struct tvfs_file { | struct tvfs_file { |
char fname[MAXFNAME]; | char fname[MAXFNAME]; |
int bytes_used; | int bytes_used; |
char buf[MAXFLEN]; | char buf[MAXFLEN]; |
}; | }; |
static struct tvfs_file *files[MAXFILES]; | static struct tvfs_file *files[MAXFILES]; |
int nfiles = 0; |
|
| |
struct tvfs_fcb { | struct tvfs_fcb { |
int pos; | int pos; |
int inode; | int inode; |
}; | }; |
static struct tvfs_fcb *handles[MAXHANDLES]; | static struct tvfs_fcb *handles[MAXHANDLES]; |
|
|
int nhandles = 0; | int nhandles = 0; |
|
int nfiles = 0; |
| |
/* tvfs_create does NOT correspond to _creat - it is an internal function | /* tvfs_create does NOT correspond to _creat - it is an internal function |
use to put a file directly into our virtual filesystem. */ | use to put a file directly into our virtual filesystem. */ |
|
|
int inode; | int inode; |
struct tvfs_file *f; | struct tvfs_file *f; |
| |
#ifdef DEBUG |
#ifdef TVFS_DEBUG |
printf("tvfs_create called with %s, %d, %d\n", fname, buf, len); |
trace("tvfs_create called with %s, %d, %d\n", fname, buf, len); |
#endif | #endif |
| |
if (nfiles >= MAXFILES) | if (nfiles >= MAXFILES) |
return -1; | return -1; |
inode = nfiles++; | inode = nfiles++; |
/* calloc didn't work here, while malloc did */ |
|
f = malloc(sizeof(struct tvfs_file)); | f = malloc(sizeof(struct tvfs_file)); |
strcpy(f->fname, fname); | strcpy(f->fname, fname); |
f->bytes_used = 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; |
return inode; | return inode; |
} | } |
|
|
int inode; | int inode; |
struct tvfs_fcb *handler; | struct tvfs_fcb *handler; |
| |
#ifdef DEBUG |
#ifdef TVFS_DEBUG |
printf("tvfs_open called with %s, %d, %d\n", fname, flags, mode); |
trace("tvfs_open called with %s, %d, %d\n", fname, flags, mode); |
#endif | #endif |
| |
/* Existing file? */ | /* Existing file? */ |
|
|
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) { |
/* ENOENT */ | /* ENOENT */ |
#ifdef DEBUG |
#ifdef TVFS_DEBUG |
printf("tvfs_open returning -1\n"); |
trace("tvfs_open returning -1\n"); |
#endif | #endif |
return -1; | return -1; |
} | } |
|
|
inode = tvfs_create(fname, 0, 0); | inode = tvfs_create(fname, 0, 0); |
} | } |
|
|
handler = malloc(sizeof(struct tvfs_fcb)); | handler = malloc(sizeof(struct tvfs_fcb)); |
handler->inode = inode; | handler->inode = inode; |
handler->pos=0; | handler->pos=0; |
h = nfiles++; | h = nfiles++; |
handles[h] = handler; | handles[h] = handler; |
#ifdef DEBUG |
|
printf("tvfs_open returning with %d\n", h); |
#ifdef TVFS_DEBUG |
|
trace("tvfs_open returning with %d\n", h); |
#endif | #endif |
| |
return h; | return h; |
|
|
int pos = handles[h]->pos; | int pos = handles[h]->pos; |
int size = files[inode]->bytes_used; | int size = files[inode]->bytes_used; |
| |
#ifdef DEBUG |
#ifdef TVFS_DEBUG |
printf("tvfs_read called with %d, %d, %d\n", h, buf, len); |
trace("tvfs_read called with %d, %d, %d\n", h, buf, len); |
#endif | #endif |
| |
/* FIXME: handle edge cases */ |
|
/* Edge Case 1 : Request beyond boundary of file */ | /* Edge Case 1 : Request beyond boundary of file */ |
if (pos + len > size) { | if (pos + len > size) { |
len = size-pos; | len = size-pos; |
|
|
return len; | return len; |
} | } |
| |
void tvfs_free(){ |
void tvfs_free() |
|
{ |
| |
int inode; | int inode; |
| |
#ifdef DEBUG |
#ifdef TVFS_DEBUG |
printf("tvfs_free\n"); |
trace("tvfs_free\n"); |
#endif | #endif |
| |
nfiles=0; | nfiles=0; |
|
|
} | } |
| |
/* Compare given file with given contents, return 0 on equal, else nonzero */ | /* Compare given file with given contents, return 0 on equal, else nonzero */ |
int tvfs_compare(const char *fname, const char *buf, int len){ |
int tvfs_compare(const char *fname, const char *buf, int len) |
|
{ |
| |
int inode; | int inode; |
| |
#ifdef DEBUG |
#ifdef TVFS_DEBUG |
printf("tvfs_compare called with %s, %d, %d\n", fname, buf, len); |
trace("tvfs_compare called with %s, %d, %d\n", fname, buf, len); |
#endif | #endif |
| |
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 */ |
#ifdef DEBUG |
#ifdef TVFS_DEBUG |
printf("tvfs_compare returning -1 (FAILURE)\n"); |
trace("tvfs_compare returning -1 (FAILURE)\n"); |
#endif | #endif |
return -1; | return -1; |
} | } |
|
|
/* doesnt check for out of bound */ | /* doesnt check for out of bound */ |
} | } |
| |
long tvfs_lseek(int h, long whence, int whither ){ |
long tvfs_lseek(int h, long whence, int whither ) |
|
{ |
| |
int inode = handles[h]->inode; | int inode = handles[h]->inode; |
int size = files[inode]->bytes_used; | int size = files[inode]->bytes_used; |
#ifdef DEBUG |
#ifdef TVFS_DEBUG |
printf("tvfs_lseek called with %d, %d, %d\n", h, whither, whence); |
trace("tvfs_lseek called with %d, %d, %d\n", h, whither, whence); |
#endif | #endif |
|
|
/* if (whence > size) | /* if (whence > size) |
whence = size;*/ | whence = size;*/ |
/* Legit lseek does NOT do boundry checking */ | /* Legit lseek does NOT do boundry checking */ |
|
|
} | } |
default: | default: |
{ | { |
printf("lseek was called with an invalid whither %d\n",whither); |
trace("lseek was called with an invalid whither %d\n",whither); |
return -1; | return -1; |
} | } |
} | } |
|
|
| |
int tvfs_close(int h){ | int tvfs_close(int h){ |
int inode = handles[h]->inode; | int inode = handles[h]->inode; |
#ifdef DEBUG |
#ifdef TVFS_DEBUG |
printf("tvfs_close called with %d\n", h); |
trace("tvfs_close called with %d\n", h); |
#endif | #endif |
if (!files[inode]){ | if (!files[inode]){ |
return -1; | return -1; |
|
|
| |
int inode = handles[h]->inode; | int inode = handles[h]->inode; |
int pos = handles[h]->pos; | int pos = handles[h]->pos; |
|
#ifdef TVFS_DEBUG |
printf("tvfs_write called with %d, %d, %d\n", h, buf, len); |
trace("tvfs_write called with %d, %d, %d\n", h, buf, len); |
|
#endif |
memcpy(files[inode]->buf+pos, buf, len); | memcpy(files[inode]->buf+pos, buf, len); |
files[inode]->bytes_used += len; | files[inode]->bytes_used += len; |
| |
|
|
result = tvfs_create( name_test_txt, file_test_txt,size_test_txt); | result = tvfs_create( name_test_txt, file_test_txt,size_test_txt); |
printf("Created virtual file with inode %d\n",result); | 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"); | printf("Attempting to open non-existant file\n"); |
result = tvfs_open(bad_filename, _O_BINARY, 0 ); | result = tvfs_open(bad_filename, _O_BINARY, 0 ); |
printf("Result code %d\n",result); | printf("Result code %d\n",result); |