1 rizwank 1.1 /*--------------------------------------------------------------------------
2 Trivial virtual file system for cabinet conformance test.
|
3 rizwank 1.2 (C) 2005 Dan Kegel and Rizwan Kassim
4 LGPL License
|
5 rizwank 1.1 --------------------------------------------------------------------------*/
6
7 #include "tvfs.h"
8 #include <string.h>
9
10 /* This is extremely cheezy. Everything is preallocated per file. */
11
12 #define MAXFILES 10
13 #define MAXHANDLES 10
14 #define MAXFNAME 255
15 #define MAXFLEN 65536
16
|
17 rizwank 1.2 #define TVFS_MAIN
18
19 #ifdef TVFS_MAIN
20 #include "cabinet_files.h"
21 #include <fcntl.h>
22 #endif
23
|
24 rizwank 1.1 struct tvfs_file {
25 char fname[MAXFNAME];
26 int bytes_used;
27 char buf[MAXFLEN];
28 };
29 static struct tvfs_file *files[MAXFILES];
30 int nfiles = 0;
31
32 struct tvfs_fcb {
33 int pos;
34 int inode;
35 };
36 static struct tvfs_fcb *handles[MAXHANDLES];
37 int nhandles = 0;
38
|
39 rizwank 1.2 /* tvfs_create does NOT correspond to _creat - it is an internal function
40 use to put a file directly into our virtual filesystem. */
41
|
42 rizwank 1.1 int tvfs_create(const char *fname, const char *buf, int len)
43 {
|
44 rizwank 1.2 int inode;
|
45 rizwank 1.1 struct tvfs_file *f;
46 if (nfiles >= MAXFILES)
47 return -1;
48 inode = nfiles++;
|
49 rizwank 1.2 /* calloc didn't work here, while malloc did */
50 f = malloc(sizeof(struct tvfs_file));
|
51 rizwank 1.1 strcpy(f->fname, fname);
|
52 rizwank 1.2 f->bytes_used = len;
|
53 rizwank 1.1 if (buf)
54 memcpy(f->buf, buf, len);
55 files[inode] = f;
56 return inode;
57 }
58
59 int tvfs_open(const char *fname, int flags, int mode)
60 {
|
61 rizwank 1.2
62 /* mode and flags are not handled */
|
63 rizwank 1.1 int h;
64 int inode;
65 /* Existing file? */
66 for (inode=0; inode<nfiles; inode++) {
67 if (!files[inode])
68 continue;
|
69 rizwank 1.2 if (!strcmp(files[inode]->fname, fname))
70 break; }
|
71 rizwank 1.1 if (inode == nfiles) {
72 /* File did not exist */
73 if ((flags & O_CREAT) == 0) {
74 /* ENOENT */
75 return -1;
76 }
77 inode = tvfs_create(fname, 0, 0);
78 }
|
79 rizwank 1.2 struct tvfs_fcb *handler;
80 handler = malloc(sizeof(struct tvfs_fcb));
81 handler->inode = inode;
82 handler->pos=0;
83 h = nfiles++;
84 handles[h] = handler;
85 return h;
|
86 rizwank 1.1 }
|
87 rizwank 1.2
|
88 rizwank 1.1 unsigned int tvfs_read(int h, void *buf, unsigned int len)
89 {
|
90 rizwank 1.2 int inode = handles[h]->inode;
91 int pos = handles[h]->pos;
92 int size = files[inode]->bytes_used;
|
93 rizwank 1.1
94 /* FIXME: handle edge cases */
|
95 rizwank 1.2 /* Edge Case 1 : Request beyond boundary of file */
96 if (pos + len > size) {
97 len = size-pos;
98 }
99
100 memcpy(buf, files[inode]->buf+pos, len);
101 handles[h]->pos += len;
|
102 rizwank 1.1
103 return len;
104 }
|
105 rizwank 1.2
106 void tvfs_free(){
107 int inode;
108 for (inode=0; inode<nfiles; inode++) {
109 if (!files[inode])
110 continue;
111 free(files[inode]);
112 }
113 }
114
115
116
117
118 #ifdef TVFS_MAIN
119 static char file_test_txt[] = "This is a test. Don't Panic!";
120 static int szfile_test_txt = sizeof(file_test_txt);
121
122 main(){
123 int result;
124 int active_handler;
125
126 rizwank 1.2 char *filebuf;
127
128 char test_filename[] = "test.txt";
129 char dummy_filename[] = "dummy.txt";
130 char bad_filename[] = "chicken.txt";
131
132 filebuf = malloc(MAXFLEN);
133
134 printf("Testing TVFS implementation, creating %s\n",test_filename);
135 result = tvfs_create( dummy_filename, file_test_txt, szfile_test_txt );
136 result = tvfs_create( test_filename, file_test_txt, szfile_test_txt );
137 printf("Created virtual file with inode %d\n",result);
138
139 /* This test failes because strcmp returns 0 incorrectly! */
140 printf("Attempting to open non-existant file\n");
141 result = tvfs_open(bad_filename, _O_BINARY, 0 );
142 printf("Result code %d\n",result);
143 printf("Attempting to open existant file\n");
144 result = tvfs_open(test_filename, _O_BINARY, 0 );
145 printf("Result code %d\n",result);
146
147 rizwank 1.2 active_handler = result;
148
149 memset (filebuf,0,MAXFLEN);
150
151 printf("Testing reading from file %s\n",test_filename);
152 result = tvfs_read(active_handler, filebuf, 9);
153 printf("Read _%s_\n", filebuf);
154 if ( strcmp(filebuf,"This is a")) {
155 printf("File read check failed!\n");
156 }
157
158 printf("Testing sequential reading from file %s\n",test_filename);
159 result = tvfs_read(active_handler, filebuf, 12);
160 printf("Read _%s_\n", filebuf);
161 if ( strcmp(filebuf," test. Don't")) {
162 printf("File read check failed!\n");
163 }
164
165 printf("Testing edge reading from file %s\n",test_filename);
166 result = tvfs_read(active_handler, filebuf, 20);
167 printf("Read %d bytes - _%s_\n", result, filebuf);
168 rizwank 1.2 if ( result != 8 ) {
169 printf("File read check failed!\n");
170 }
171
172
173
174
175
176 tvfs_free();
177 free(filebuf);
178
179 }
180
181 #endif
|