yaffsfs.c: Fix NULL dereference in yaffs_unmount2_reldev()
[yaffs2.git] / rtems / rtems-y-test / basic-test / yaffs-rtems-basic-test.c
1 /*
2  *  Simple test program -- demonstrating use of IMFS
3  */
4
5 #include <bsp.h>
6
7 #include <fcntl.h>
8 #include <stdio.h>
9 #include <stdlib.h>
10 #include <unistd.h>
11
12 #include <dirent.h>
13
14 #include <rtems/libio.h>
15 #include <yaffs/rtems_yaffs.h>
16
17 void set_uint8_t_buffer(uint8_t *buf, uint32_t n, uint8_t start, uint8_t inc)
18 {
19         while (n) {
20                 *buf = start;
21                 buf++;
22                 start += inc;
23                 n--;
24         }
25 }
26
27 void make_test_file_name(char *out, int out_size, char *root_path, char *dir, char *file, int index)
28 {
29         if (index >= 0)
30                 snprintf(out, out_size, "%s/%s/%s-%d",
31                                         root_path, dir, file, index);
32         else
33                 snprintf(out, out_size, "%s/%s/%s",
34                                         root_path, dir, file);
35 }
36
37 void make_test_dir_name(char *out, int out_size, char *root_path, char *dir)
38 {
39         snprintf(out, out_size, "%s/%s", root_path, dir);
40 }
41
42 void dump_directory_tree_worker(const char *dname,int recursive)
43 {
44         DIR *d;
45         struct dirent *de;
46         struct stat s;
47         char str[1000];
48
49         d = opendir(dname);
50
51         if(!d) {
52                 printf("opendir failed\n");
53         } else {
54                 while((de = readdir(d)) != NULL) {
55                         sprintf(str,"%s/%s",dname,de->d_name);
56
57                         lstat(str,&s);
58
59                         printf("%s inode %d length %d mode 0%o ",
60                                 str, (int)s.st_ino, (int)s.st_size, s.st_mode);
61                         switch(s.st_mode & S_IFMT) {
62                                 case S_IFREG: printf("data file"); break;
63                                 case S_IFDIR: printf("directory"); break;
64                                 case S_IFLNK: printf("symlink -->");
65                                                           if(readlink(str,str,100) < 0)
66                                                                 printf("no alias");
67                                                           else
68                                                                 printf("\"%s\"",str);
69                                                           break;
70                                 default: printf("unknown mode"); break;
71                         }
72
73                         printf("\n");
74
75                         if((s.st_mode & S_IFMT) == S_IFDIR && recursive)
76                                 dump_directory_tree_worker(str,1);
77                 }
78                 closedir(d);
79         }
80 }
81
82 static void dump_directory_tree(const char *dname)
83 {
84         printf("Directory tree of %s\n", dname);
85         dump_directory_tree_worker(dname,1);
86 }
87
88
89 void recursively_delete(char *objname)
90 {
91         struct stat s;
92         DIR *d;
93         struct dirent *de;
94         char str[500];
95
96
97         //printf("deleting %s\n", objname);
98         lstat(objname, &s);
99
100         switch(s.st_mode & S_IFMT) {
101                 case S_IFREG:
102                         printf("delete data file %s returns %d\n",
103                                 objname, unlink(objname));
104                 break;
105                 case S_IFLNK:
106                         printf("delete symlink %s returns %d\n",
107                                 objname, unlink(objname));
108                 break;
109                 case S_IFDIR:
110                         d = opendir(objname);
111                         if(!d) {
112                                 printf("opendir failed\n");
113                         } else {
114                                 while((de = readdir(d)) != NULL) {
115                                         snprintf(str, sizeof(str), "%s/%s",
116                                                 objname, de->d_name);
117                                         recursively_delete(str);
118                                 }
119                                 closedir(d);
120                         }
121                         printf("delete directory %s returns %d\n",
122                                 objname, rmdir(objname));
123                 break;
124         }
125 }
126
127
128
129 void dumpDir(const char *dname)
130 {
131         dump_directory_tree_worker(dname,0);
132 }
133
134 int basic_file_test(char *root_path, char *test_path)
135 {
136         char fname[100];
137         char dname[100];
138         int fd;
139         int ret;
140         uint8_t buf[100];
141         uint8_t buf2[100];
142
143         make_test_dir_name(dname, sizeof(dname), root_path, test_path);
144         make_test_file_name(fname, sizeof(fname), root_path, test_path, "file", -1);
145
146         ret = mkdir(dname, 0777);
147
148         if (ret < 0) {
149                 perror("mkdir");
150                 return ret;
151         }
152
153         fd = open(fname, O_RDWR | O_CREAT | O_TRUNC, 0777);
154         printf("open %s  = %d\n", fname, fd);
155         if (fd < 0) {
156                 perror("opening test file");
157                 return fd;
158         }
159
160         set_uint8_t_buffer(buf, sizeof(buf), 0xAA, 1);
161
162         ret = write(fd, buf, sizeof(buf));
163
164         printf("write returned %d\n", ret);
165
166         if (ret < 0) {
167                 perror("writing file");
168                 return ret;
169         }
170
171         ret = fdatasync(fd);
172
173         if (ret < 0) {
174                 perror("fdatasync problem");
175                 return ret;
176         }
177
178         ret = lseek(fd, 0, SEEK_END);
179
180         printf("lseek end ret = %d\n", ret);
181
182         ret = lseek(fd, 0, SEEK_SET);
183         printf("lseek start ret = %d\n", ret);
184
185         ret = read(fd, buf2, sizeof(buf2));
186
187         printf("reading file ret = %d\n", ret);
188
189         if (ret < 0) {
190                 perror("reading file");
191                 return ret;
192         }
193
194         dump_directory_tree(root_path);
195
196         if (memcmp(buf, buf2, sizeof(buf)) == 0) {
197                 printf("buffers match\n");
198                 return 0;
199         } else {
200                 printf("buffers do not match\n");
201                 return -1;
202         }
203
204         return ret;
205 }
206
207
208 int create_delete_files_pass(char *root_path, char *test_path, int n_files, int del_when_done)
209 {
210         char fname[100];
211         char lname[100];
212         char dname[100];
213         int *fds = NULL;
214         int ret;
215         int i;
216         uint8_t buf[100];
217         uint8_t buf2[100];
218
219         fds = malloc(n_files * sizeof (int));
220
221         if (!fds) {
222                 printf("Failed to malloc\n");
223                 ret = -1;
224                 goto err;
225         }
226
227         make_test_dir_name(dname, sizeof(dname), root_path, test_path);
228
229         recursively_delete(dname);
230
231         ret = access(dname, F_OK);
232         printf("access of non-existing expects -1 returned %d\n", ret);
233
234         if (ret != -1) {
235                 printf("access should have been -1, was %d\n", ret);
236                 ret = -1;
237                 goto err;
238         }
239
240         ret = mkdir(dname, 0777);
241
242         if (ret < 0) {
243                 perror("mkdir");
244                 goto err;
245         }
246
247         ret = access(dname, F_OK);
248         printf("access of existing returned %d\n", ret);
249
250         if (ret < 0) {
251                 perror("access of existing directory");
252                 goto err;
253         }
254
255         for (i = 0; i < n_files; i++) {
256                 int link_fd;
257
258                 make_test_file_name(fname, sizeof(fname), root_path, test_path, "file-", i);
259                 make_test_file_name(lname, sizeof(lname), root_path, test_path, "link-", i);
260
261                 ret = symlink(fname, lname);
262
263                 if (ret < 0) {
264                         perror("creating symlink");
265                         goto err;
266                 }
267
268                 fds[i] = open(fname, O_RDWR | O_CREAT | O_TRUNC, 0777);
269                 printf("open %s  = %d\n", fname, fds[i]);
270
271                 if (fds[i] < 0) {
272                         perror("opening test file");
273                         ret = fds[i];
274                         goto err;
275                 }
276
277
278                 link_fd = open(lname, O_RDWR, 0777);
279                 printf("opening link %s  = %d\n", lname, link_fd);
280
281                 if (link_fd < 0) {
282                         perror("opening symlink file");
283                         ret = link_fd;
284                         goto err;
285                 }
286                 close(link_fd);
287
288         }
289
290         set_uint8_t_buffer(buf, sizeof(buf), 0xAA, 1);
291
292         for(i = 0; i < n_files; i++) {
293                 ret = write(fds[i], buf, sizeof(buf));
294                 printf("write returned %d\n", ret);
295                 if (ret < 0) {
296                         perror("writing file");
297                         goto err;
298                 }
299         }
300
301         for(i = 0; i < n_files; i++) {
302                 int trunc_size = sizeof(buf2)/2;
303
304                 ret = lseek(fds[i], 0, SEEK_END);
305
306                 printf("lseek end ret = %d\n", ret);
307
308                 ret = lseek(fds[i], 0, SEEK_SET);
309                 printf("lseek start ret = %d\n", ret);
310
311                 ret = read(fds[i], buf2, sizeof(buf2));
312
313                 printf("reading file ret = %d\n", ret);
314                 if (ret < 0) {
315                         perror("reading file");
316                         goto err;
317                 }
318                 ret = ftruncate(fds[i], trunc_size);
319
320                 if (ret < 0) {
321                         perror("ftruncate");
322                         goto err;
323                 }
324
325                 ret = lseek(fds[i], 0, SEEK_END);
326                 if (ret != trunc_size) {
327                         printf("truncated size is %d but lseek returned %d\n",
328                                 trunc_size, ret);
329                         ret = -1;
330                         goto err;
331                 }
332
333
334         }
335
336         for(i = 0; i < n_files; i++) {
337                 ret = close(fds[i]);
338                 if (ret < 0) {
339                         perror("closing file");
340                         goto err;
341                 }
342         }
343
344         dump_directory_tree(root_path);
345
346         if (memcmp(buf, buf2, sizeof(buf)) == 0) {
347                 printf("buffers match\n");
348                 ret = 0;
349         } else {
350                 printf("buffers do not match\n");
351                 ret = -1;
352         }
353
354         if (del_when_done)
355                 recursively_delete(dname);
356 err:
357         free(fds);
358
359         return ret;
360 }
361
362 int create_delete_files(char *root_path, char *test_path, int n_files, int n_passes)
363 {
364         int i;
365         int ret;
366         for (i = 0; i < n_passes; i++) {
367                 printf("\nCreate and Delete Files Pass %d\n", i);
368                 ret = create_delete_files_pass(root_path, test_path, n_files, 1);
369                 if (ret < 0)
370                         return ret;
371         }
372         return 0;
373 }
374
375 #define YPATH "/yaffs_mount_pt"
376 #define FNAME YPATH"/test"
377 #define DIRNAME YPATH"/dirtest"
378
379 void check_fail(int ret)
380 {
381         if (ret < 0)
382                 printf("Test failed\n");
383 }
384
385 void run_the_test(void)
386 {
387         check_fail(basic_file_test(YPATH, "basic-test-dir"));
388         check_fail(create_delete_files(YPATH, "create-del-test-dir", 15, 50));
389
390         printf("\n\n\nAll Yaffs Tests passed Ok\n\n\n");
391 }