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 rizwank 1.3 const static char name_test_txt[] = "test.txt";
120 const static char file_test_txt[] = "This is a test. Don't Panic!";
|
121 rizwank 1.2
122 main(){
123 int result;
124 int active_handler;
125
126 char *filebuf;
127
128 char dummy_filename[] = "dummy.txt";
129 char bad_filename[] = "chicken.txt";
130
131 filebuf = malloc(MAXFLEN);
132
|
133 rizwank 1.3 printf("Testing TVFS implementation, creating %s\n",name_test_txt);
134 result = tvfs_create( dummy_filename, file_test_txt, sizeof(file_test_txt));
135 result = tvfs_create( name_test_txt, file_test_txt,sizeof(file_test_txt));
|
136 rizwank 1.2 printf("Created virtual file with inode %d\n",result);
137
138 /* This test failes because strcmp returns 0 incorrectly! */
139 printf("Attempting to open non-existant file\n");
140 result = tvfs_open(bad_filename, _O_BINARY, 0 );
141 printf("Result code %d\n",result);
142 printf("Attempting to open existant file\n");
|
143 rizwank 1.3 result = tvfs_open(name_test_txt, _O_BINARY, 0 );
|
144 rizwank 1.2 printf("Result code %d\n",result);
145
146 active_handler = result;
147
148 memset (filebuf,0,MAXFLEN);
149
|
150 rizwank 1.3 printf("Testing reading from file %s\n",name_test_txt);
|
151 rizwank 1.2 result = tvfs_read(active_handler, filebuf, 9);
152 printf("Read _%s_\n", filebuf);
153 if ( strcmp(filebuf,"This is a")) {
154 printf("File read check failed!\n");
155 }
156
|
157 rizwank 1.3 printf("Testing sequential reading from file %s\n",name_test_txt);
|
158 rizwank 1.2 result = tvfs_read(active_handler, filebuf, 12);
159 printf("Read _%s_\n", filebuf);
160 if ( strcmp(filebuf," test. Don't")) {
161 printf("File read check failed!\n");
162 }
163
|
164 rizwank 1.3 printf("Testing edge reading from file %s\n",name_test_txt);
|
165 rizwank 1.2 result = tvfs_read(active_handler, filebuf, 20);
166 printf("Read %d bytes - _%s_\n", result, filebuf);
167 if ( result != 8 ) {
168 printf("File read check failed!\n");
169 }
170
171
172
173
174
175 tvfs_free();
176 free(filebuf);
177
178 }
179
180 #endif
|