1 /*
2 * Copyright (C) 2015-2017 Alibaba Group Holding Limited
3 */
4
5 #include <stdint.h>
6 #include <stdio.h>
7 #include <string.h>
8 #include <unistd.h>
9
10 #include "ramfs_types.h"
11 #include "ramfs_api.h"
12 #include "ramfs_adapt.h"
13
14 #define RAMFS_LL_NODE_META_SIZE (sizeof(ramfs_ll_node_t *) + \
15 sizeof(ramfs_ll_node_t *))
16
17 #define RAMFS_LL_PREV_OFFSET(ll) (ll->size)
18 #define RAMFS_LL_NEXT_OFFSET(ll) (ll->size + sizeof(ramfs_ll_node_t *))
19
20 #define RAMFS_LL_READ(ll, i) \
21 for (i = ramfs_ll_get_head(&ll); i != NULL; i = ramfs_ll_get_next(&ll, i))
22 #define RAMFS_LL_READ_BACK(ll, i) \
23 for (i = ramfs_ll_get_tail(&ll); i != NULL, u = ramfs_ll_get_prev(&ll, i))
24
25 static ramfs_ll_t g_file_ll;
26
27 static uint8_t g_inited = 0;
28
29 /**
30 * @brief Set the previous node pointer of a node
31 *
32 * @param[in] ll pointer to linked list
33 * @param[out] act pointer to a node which prev node pointer should be set
34 * @param[in] prev pointer to the previous node before act
35 *
36 * @return None
37 */
ramfs_node_set_prev(ramfs_ll_t * ll,ramfs_ll_node_t * act,ramfs_ll_node_t * prev)38 static void ramfs_node_set_prev(ramfs_ll_t *ll, ramfs_ll_node_t *act,
39 ramfs_ll_node_t *prev)
40 {
41 memcpy(act + RAMFS_LL_PREV_OFFSET(ll), &prev, sizeof(ramfs_ll_node_t *));
42 }
43
44 /**
45 * @brief Set the next node pointer of a node
46 *
47 * @param[in] ll pointer to linked list
48 * @param[out] act poiner to a node which next node pointer should be set
49 * @param[in] next poiner to the next node after act
50 *
51 * @return None
52 */
ramfs_node_set_next(ramfs_ll_t * ll,ramfs_ll_node_t * act,ramfs_ll_node_t * next)53 static void ramfs_node_set_next(ramfs_ll_t *ll, ramfs_ll_node_t *act,
54 ramfs_ll_node_t *next)
55 {
56 memcpy(act + RAMFS_LL_NEXT_OFFSET(ll), &next, sizeof(ramfs_ll_node_t *));
57 }
58
59 /**
60 * @brief Initialize ramfs linked list
61 *
62 * @param[out] ll pointer to the ramfs linked list
63 * @param[in] size the size of 1 node in bytes
64 *
65 * @return None
66 */
ramfs_ll_init(ramfs_ll_t * ll,uint32_t size)67 static void ramfs_ll_init(ramfs_ll_t *ll, uint32_t size)
68 {
69 ll->head = NULL;
70 ll->tail = NULL;
71
72 if (size & 0x3) {
73 size &= ~0x3;
74 size += 4;
75 }
76
77 ll->size = size;
78 }
79
80 /**
81 * @brief Add a new head to the linked list
82 *
83 * @param[in] ll pointer to the linked list
84 *
85 * @return pointer to the new head, NULL if no memory
86 */
ramfs_ll_ins_head(ramfs_ll_t * ll)87 static void *ramfs_ll_ins_head(ramfs_ll_t *ll)
88 {
89 ramfs_ll_node_t *new = NULL;
90
91 new = ramfs_mm_alloc(ll->size + RAMFS_LL_NODE_META_SIZE);
92
93 if (new != NULL) {
94 ramfs_node_set_prev(ll, new, NULL); /* No prev before the new head */
95 ramfs_node_set_next(ll, new, ll->head); /* After new comes the old head */
96
97 if (ll->head != NULL) { /* If there is old head then before it goes the new */
98 ramfs_node_set_prev(ll, ll->head, new);
99 }
100
101 ll->head = new; /* Set the new head in the linked list */
102 if (ll->tail == NULL) { /* If there is no tail, set the tail too */
103 ll->tail = new;
104 }
105 }
106
107 return new;
108 }
109
110 /**
111 * @brief Return with head node of the linked list
112 *
113 * @param[in] ll pointer to the linked list
114 *
115 * @return pointer to the head of linked list
116 */
ramfs_ll_get_head(ramfs_ll_t * ll)117 void *ramfs_ll_get_head(ramfs_ll_t *ll)
118 {
119 void *head = NULL;
120
121 if (ll->head != NULL) {
122 head = ll->head;
123 }
124
125 return head;
126 }
127
128 /**
129 * @brief Return with tail node of the linked list
130 *
131 * @param[in] ll pointer to the linked list
132 *
133 * @return pointer to the tail of linked list
134 */
ramfs_ll_get_tail(ramfs_ll_t * ll)135 void *ramfs_ll_get_tail(ramfs_ll_t *ll)
136 {
137 void *tail = NULL;
138
139 if (ll->tail != NULL) {
140 tail = ll->tail;
141 }
142
143 return tail;
144 }
145
146 /**
147 * @brief Return with the pointer of the next node after act
148 *
149 * @param[in] ll pointer to the linked list
150 * @param[in] act pointer to a node
151 *
152 * @return pointer to the next node
153 */
ramfs_ll_get_next(ramfs_ll_t * ll,void * act)154 void *ramfs_ll_get_next(ramfs_ll_t *ll, void *act)
155 {
156 void *next = NULL;
157
158 ramfs_ll_node_t *node = act;
159
160 if (ll != NULL) {
161 memcpy(&next, node + RAMFS_LL_NEXT_OFFSET(ll), sizeof(void *));
162 }
163
164 return next;
165 }
166
167 /**
168 * @brief Return with the pointer of the previous node after act
169 *
170 * @param[in] ll pointer to the linked list
171 * @param[in] act pointer to a node
172 *
173 * @return pointer to the previous node
174 */
ramfs_ll_get_prev(ramfs_ll_t * ll,void * act)175 void *ramfs_ll_get_prev(ramfs_ll_t *ll, void *act)
176 {
177 void *prev = NULL;
178
179 ramfs_ll_node_t *node = act;
180
181 if (ll != NULL) {
182 memcpy(&prev, node + RAMFS_LL_PREV_OFFSET(ll), sizeof(void *));
183 }
184
185 return prev;
186 }
187
188 /**
189 * @brief Remove the node from linked list
190 *
191 * @param[in] ll pointer to the linked list of node
192 * @param[in] node pointer to the node in linked list
193 *
194 * @return None
195 */
ramfs_ll_remove(ramfs_ll_t * ll,void * node)196 static void ramfs_ll_remove(ramfs_ll_t *ll, void *node)
197 {
198 ramfs_ll_node_t *prev;
199 ramfs_ll_node_t *next;
200
201 if (ramfs_ll_get_head(ll) == node) {
202 ll->head = ramfs_ll_get_next(ll, node);
203
204 if (ll->head == NULL) {
205 ll->tail = NULL;
206 } else {
207 ramfs_node_set_prev(ll, ll->head, NULL);
208 }
209
210 } else if (ramfs_ll_get_tail(ll) == node) {
211 ll->tail = ramfs_ll_get_prev(ll, node);
212
213 if (ll->tail == NULL) {
214 ll->head = NULL;
215 } else {
216 ramfs_node_set_next(ll, ll->tail, NULL);
217 }
218
219 } else {
220 prev = ramfs_ll_get_prev(ll, node);
221 next = ramfs_ll_get_next(ll, node);
222
223 ramfs_node_set_next(ll, prev, next);
224 ramfs_node_set_prev(ll, next, prev);
225 }
226 }
227
228 /**
229 * @brief Search path in link
230 *
231 * @param[in] fn file name
232 *
233 * @return 0 if get path in link, RAMFS_ERR_FS if failed
234 */
ramfs_search_link(ramfs_entry_t * entry,char * path)235 static int ramfs_search_link(ramfs_entry_t *entry, char *path)
236 {
237 link_name_t *link_name = entry->link;
238
239 while (link_name != NULL) {
240 if (strcmp(link_name->name, path) == 0) {
241 return RAMFS_OK;
242 } else {
243 link_name = link_name->next;
244 }
245 }
246
247 return RAMFS_ERR_FS;
248 }
249
250 /**
251 * @brief Search path in link
252 *
253 * @param[in] fn file name
254 *
255 * @return 0 if get path in link, RAMFS_ERR_FS if failed
256 */
ramfs_search_link_part(ramfs_entry_t * entry,char * path)257 static int ramfs_search_link_part(ramfs_entry_t *entry, char *path)
258 {
259 link_name_t *link_name = entry->link;
260
261 while (link_name != NULL) {
262 if (strncmp(link_name->name, path, strlen(path)) == 0) {
263 return RAMFS_OK;
264 } else {
265 link_name = link_name->next;
266 }
267 }
268
269 return RAMFS_ERR_FS;
270 }
271
272 /**
273 * @brief Give the ramfs entry from a filename
274 *
275 * @param[in] fn file name
276 *
277 * @return pointer to the dynamically allocated entry with 'fn'.
278 * NULL if no entry found with that name
279 */
ramfs_entry_get(const char * fn)280 static ramfs_entry_t *ramfs_entry_get(const char *fn)
281 {
282 ramfs_entry_t *entry;
283 int ret = -1;
284
285 RAMFS_LL_READ(g_file_ll, entry) {
286 if (strcmp(entry->fn, fn) == 0) {
287 return entry;
288 } else {
289 ret = ramfs_search_link(entry, (char *)fn);
290 if (ret == RAMFS_OK) {
291 return entry;
292 }
293 }
294 }
295
296 return NULL;
297 }
298
299 /**
300 * @brief Create dir involved in path
301 *
302 * @param[in] fn file name
303 *
304 * @return poiner to the dynamically allocated new entry
305 * NULL if no space for the entry
306 */
ramfs_entry_dir_new(const char * path)307 static int ramfs_entry_dir_new(const char *path)
308 {
309 int i = 0;
310 int flag = 0;
311
312 char dir_buf[RAMFS_PATH_MAX];
313
314 ramfs_entry_t *new_entry = NULL;
315
316 /* create dir involved in path, if path is "/ramfs/f1/f2/file1", then
317 create dir "/ramfs/f1" and "/ramfs/f1/f2" */
318 for(i = 1; i < strlen(path); i++) {
319 if (path[i] == '/') {
320 memset(dir_buf, 0, sizeof(dir_buf));
321 memcpy(dir_buf, path, i);
322
323 flag = 0;
324 new_entry = NULL;
325
326 /* if the same dir is found, ignore this dir */
327 RAMFS_LL_READ(g_file_ll, new_entry) {
328 if ((strcmp(new_entry->fn, dir_buf) == 0) && (new_entry->is_dir == 1)) {
329 flag = 1;
330 break;
331 }
332 }
333
334 if (flag == 0) {
335 new_entry = ramfs_ll_ins_head(&g_file_ll); /* Create a new file */
336 if (new_entry == NULL) {
337 return RAMFS_ERR_MALLOC;
338 }
339
340 new_entry->fn = ramfs_mm_alloc(i + 1);
341 memset(new_entry->fn, 0, (i + 1));
342 strncpy(new_entry->fn, path, i);
343
344 new_entry->data = NULL;
345 new_entry->size = 0;
346 new_entry->refs = 0;
347 new_entry->const_data = 0;
348 new_entry->is_dir = 1;
349 new_entry->link = NULL;
350 new_entry->link_count = 0;
351 }
352 }
353 }
354
355 return RAMFS_OK;
356 }
357
358 /**
359 * @brief Create a new entry with 'fn' file name
360 *
361 * @param[in] fn file name
362 *
363 * @return poiner to the dynamically allocated new entry
364 * NULL if no space for the entry
365 */
ramfs_entry_new(const char * fn)366 static ramfs_entry_t *ramfs_entry_new(const char *fn)
367 {
368 ramfs_entry_t *new_entry = NULL;
369
370 int ret = -1;
371
372 /* create dir involved in path, if path is "/ramfs/f1/f2/file1", then
373 create dir "/ramfs/f1" and "/ramfs/f1/f2" */
374 ret = ramfs_entry_dir_new(fn);
375 if (ret != RAMFS_OK) {
376 return NULL;
377 }
378
379 new_entry = ramfs_ll_ins_head(&g_file_ll); /* Create a new file */
380 if (new_entry == NULL) {
381 return NULL;
382 }
383
384 new_entry->fn = ramfs_mm_alloc(strlen(fn) + 1);
385 strcpy(new_entry->fn, fn);
386
387 new_entry->data = NULL;
388 new_entry->size = 0;
389 new_entry->refs = 0;
390 new_entry->const_data = 0;
391 new_entry->is_dir = 0;
392 new_entry->link = NULL;
393 new_entry->link_count = 0;
394
395 return new_entry;
396 }
397
ramfs_init(void)398 void ramfs_init(void)
399 {
400 ramfs_ll_init(&g_file_ll, sizeof(ramfs_entry_t));
401
402 g_inited = 1;
403 }
404
ramfs_deinit(void)405 void ramfs_deinit(void)
406 {
407 if (g_inited) {
408 memset(&g_file_ll, 0 , sizeof(g_file_ll));
409 g_inited = 0;
410 }
411 }
412
ramfs_ready(void)413 int32_t ramfs_ready(void)
414 {
415 return g_inited;
416 }
417
ramfs_open(void * fp,const char * fn,uint32_t mode)418 int32_t ramfs_open(void *fp, const char* fn, uint32_t mode)
419 {
420 ramfs_file_t *file = (ramfs_file_t *)fp;
421 ramfs_entry_t *entry = ramfs_entry_get(fn);
422
423 file->entry = NULL;
424
425 if ((entry != NULL) && (entry->is_dir == 1)) {
426 return RAMFS_ERR_NOT_EXIST;
427 }
428
429 if (entry == NULL) {
430 if ((mode & RAMFS_MODE_WR) != 0) {
431 entry = ramfs_entry_new(fn);
432 if (entry == NULL) {
433 return RAMFS_ERR_FULL;
434 }
435 } else {
436 return RAMFS_ERR_NOT_EXIST;
437 }
438
439 }
440
441 file->entry = entry;
442 file->entry->ar = mode & RAMFS_MODE_RD ? 1 : 0;
443 file->entry->aw = mode & RAMFS_MODE_WR ? 1 : 0;
444 file->rwp = 0;
445
446 entry->refs++;
447
448 return RAMFS_OK;
449 }
450
ramfs_create_const(const char * fn,const void * data,uint32_t len)451 int32_t ramfs_create_const(const char *fn, const void *data, uint32_t len)
452 {
453 int32_t res;
454
455 ramfs_file_t file;
456 ramfs_entry_t *entry;
457
458 res = ramfs_open(&file, fn, RAMFS_MODE_RD);
459 if (res == RAMFS_OK) {
460 ramfs_close(&file);
461 return RAMFS_ERR_DENIED;
462 }
463
464 res = ramfs_open(&file, fn, RAMFS_MODE_WR);
465 if (res != RAMFS_OK) {
466 return res;
467 }
468
469 entry = file.entry;
470
471 if (entry->data != NULL) {
472 return RAMFS_ERR_DENIED;
473 }
474
475 entry->data = (void *)data;
476 entry->size = len;
477 entry->const_data = 1;
478 entry->ar = 1;
479 entry->aw = 0;
480
481 res = ramfs_close(&file);
482
483 return res;
484 }
485
ramfs_close(void * fp)486 int32_t ramfs_close(void *fp)
487 {
488 ramfs_file_t *file = (ramfs_file_t *)fp;
489
490 if (file->entry == NULL) {
491 return RAMFS_OK;
492 }
493
494 if (file->entry->refs > 0) {
495 file->entry->refs--;
496 }
497
498 return RAMFS_OK;
499 }
500
ramfs_remove(const char * fn)501 int32_t ramfs_remove(const char *fn)
502 {
503 ramfs_entry_t *entry = ramfs_entry_get(fn);
504
505 link_name_t *link_name = NULL;
506 link_name_t *link_name_next = NULL;
507
508 if (entry == NULL) {
509 return RAMFS_ERR_NOT_EXIST;
510 }
511
512 if (entry->is_dir == 1) {
513 return ramfs_rmdir(fn);
514 }
515
516 if (entry->refs != 0) {
517 return RAMFS_ERR_DENIED;
518 }
519
520 ramfs_ll_remove(&g_file_ll, entry);
521 ramfs_mm_free(entry->fn);
522 entry->fn = NULL;
523
524 link_name = entry->link;
525 while(link_name != NULL) {
526 link_name_next = link_name->next;
527 ramfs_mm_free(link_name->name);
528 ramfs_mm_free(link_name);
529 link_name = link_name_next;
530 }
531
532 if (entry->const_data == 0) {
533 ramfs_mm_free(entry->data);
534 entry->data = NULL;
535 }
536
537 ramfs_mm_free(entry);
538
539 return RAMFS_OK;
540 }
541
ramfs_rename(const char * old,const char * new)542 int32_t ramfs_rename(const char *old, const char *new)
543 {
544 ramfs_entry_t *entry = NULL;
545
546 entry = ramfs_entry_get(new);
547 if (entry != NULL) {
548 return RAMFS_ERR_PATH;
549 }
550
551 entry = ramfs_entry_get(old);
552 if (entry == NULL) {
553 return RAMFS_ERR_NOT_EXIST;
554 }
555
556 if ((entry != NULL) && (entry->is_dir == 1)) {
557 return RAMFS_ERR_PATH;
558 }
559
560 /* rename linked name is not supported */
561 if (strcmp(entry->fn, old) != 0) {
562 return RAMFS_ERR_NOT_IMP;
563 }
564
565 entry->fn = ramfs_mm_realloc(entry->fn, strlen(new) + 1);
566 if (entry->fn == NULL) {
567 return RAMFS_ERR_MALLOC;
568 }
569 memset(entry->fn, 0 , strlen(new) + 1);
570 strncpy(entry->fn, new, strlen(new));
571
572 return RAMFS_OK;
573 }
574
ramfs_read(void * fp,void * buf,uint32_t btr,uint32_t * br)575 int32_t ramfs_read(void *fp, void *buf, uint32_t btr, uint32_t *br)
576 {
577 uint8_t *data;
578 ramfs_file_t *file;
579 ramfs_entry_t *entry;
580
581 file = (ramfs_file_t *)fp;
582 entry = file->entry;
583 *br = 0;
584
585 if (entry->data == NULL || entry->size == 0) {
586 return RAMFS_OK;
587 } else if (entry->ar == 0) {
588 return RAMFS_ERR_DENIED;
589 }
590
591 if (file->rwp + btr > entry->size) {
592 *br = entry->size - file->rwp;
593 } else {
594 *br = btr;
595 }
596
597 if (entry->const_data == 0) {
598 data = (uint8_t *)entry->data;
599 } else {
600 data = entry->data;
601 }
602
603 data += file->rwp;
604 memcpy(buf, data, *br);
605
606 file->rwp += *br;
607
608 return RAMFS_OK;
609 }
610
ramfs_write(void * fp,const void * buf,uint32_t btw,uint32_t * bw)611 int32_t ramfs_write(void *fp, const void *buf, uint32_t btw, uint32_t *bw)
612 {
613 uint32_t new_size;
614 uint8_t *new_data;
615 uint8_t *rwp;
616
617 ramfs_file_t *file;
618 ramfs_entry_t *entry;
619
620 file = (ramfs_file_t *)fp;
621 entry = file->entry;
622 *bw = 0;
623
624 if (entry->aw == 0) {
625 return RAMFS_ERR_DENIED;
626 }
627
628 new_size = file->rwp + btw;
629 if (new_size > entry->size) {
630 new_data = ramfs_mm_realloc(entry->data, new_size);
631 if (new_data == NULL) {
632 return RAMFS_ERR_FULL;
633 }
634
635 entry->data = new_data;
636 entry->size = new_size;
637 }
638
639 rwp = (uint8_t *)entry->data;
640 rwp += file->rwp;
641
642 memcpy(rwp, buf, btw);
643 *bw = btw;
644 file->rwp += *bw;
645
646 return RAMFS_OK;
647 }
648
ramfs_seek(void * fp,uint32_t pos)649 int32_t ramfs_seek(void *fp, uint32_t pos)
650 {
651 uint8_t *new_data;
652
653 ramfs_file_t *file;
654 ramfs_entry_t *entry;
655
656 file = (ramfs_file_t *)fp;
657 entry = file->entry;
658
659 if (pos < entry->size) {
660 file->rwp = pos;
661 } else {
662 if (entry->aw == 0) {
663 return RAMFS_ERR_DENIED;
664 }
665
666 new_data = ramfs_mm_realloc(entry->data, pos);
667 if (new_data == NULL) {
668 return RAMFS_ERR_FULL;
669 }
670
671 entry->data = new_data;
672 entry->size = pos;
673 file->rwp = pos;
674 }
675
676 return RAMFS_OK;
677 }
678
ramfs_tell(void * fp,uint32_t * pos)679 int32_t ramfs_tell(void *fp, uint32_t *pos)
680 {
681 *pos = ((ramfs_file_t *)fp)->rwp;
682
683 return RAMFS_OK;
684 }
685
ramfs_trunc(void * fp)686 int32_t ramfs_trunc(void *fp)
687 {
688 void *new_data;
689
690 ramfs_file_t *file;
691 ramfs_entry_t *entry;
692
693 file = (ramfs_file_t *)fp;
694 entry = file->entry;
695
696 if (entry->aw == 0) {
697 return RAMFS_ERR_DENIED;
698 }
699
700 new_data = ramfs_mm_realloc(entry->data, file->rwp);
701 if (new_data == NULL) {
702 return RAMFS_ERR_FULL;
703 }
704
705 entry->data = new_data;
706 entry->size = file->rwp;
707
708 return RAMFS_OK;
709 }
710
ramfs_size(void * fp,uint32_t * size)711 int32_t ramfs_size(void *fp, uint32_t *size)
712 {
713 *size = ((ramfs_file_t *)fp)->entry->size;
714
715 return RAMFS_OK;
716 }
717
ramfs_access(const char * path,int32_t mode)718 int32_t ramfs_access(const char *path, int32_t mode)
719 {
720 ramfs_entry_t *entry = ramfs_entry_get(path);
721
722 if (mode == F_OK) {
723 if (entry == NULL) {
724 return RAMFS_ERR_DENIED;
725 } else {
726 return RAMFS_OK;
727 }
728 }
729
730 if (mode == R_OK) {
731 if (entry == NULL) {
732 return RAMFS_OK;
733 } else {
734 if (entry->ar == 1) {
735 return RAMFS_OK;
736 } else {
737 return RAMFS_ERR_DENIED;
738 }
739 }
740 }
741
742 if (mode == W_OK) {
743 if (entry == NULL) {
744 return RAMFS_OK;
745 } else {
746 if (entry->aw == 1) {
747 return RAMFS_OK;
748 } else {
749 return RAMFS_ERR_DENIED;
750 }
751 }
752 }
753
754 if (mode == X_OK) {
755 return RAMFS_OK;
756 }
757
758 return RAMFS_ERR_DENIED;
759 }
760
ramfs_mkdir(const char * path)761 int32_t ramfs_mkdir(const char *path)
762 {
763 ramfs_entry_t *entry = ramfs_entry_get(path);
764
765 if ((entry != NULL) && (entry->is_dir == 1)) {
766 return RAMFS_ERR_EXIST;
767 }
768
769 entry = ramfs_entry_new(path);
770 if (entry == NULL) {
771 return RAMFS_ERR_FULL;
772 }
773
774 entry->is_dir = 1;
775
776 return RAMFS_OK;
777 }
778
ramfs_opendir(void * dp,const char * path)779 int32_t ramfs_opendir(void *dp, const char *path)
780 {
781 ramfs_dir_t *ramfs_dp;
782 ramfs_entry_t *entry;
783
784 ramfs_dp = (ramfs_dir_t *)dp;
785 entry = ramfs_entry_get(path);
786
787 if (entry == NULL) {
788 return RAMFS_ERR_NOT_EXIST;
789 }
790
791 if (entry->is_dir != 1) {
792 entry = ramfs_entry_get(path);
793 if (entry == NULL) {
794 return RAMFS_ERR_NOT_EXIST;
795 }
796
797 if (entry->is_dir != 1) {
798 return RAMFS_ERR_NOT_EXIST;
799 }
800 }
801
802 ramfs_dp->dir_name = ramfs_mm_alloc(strlen(path) + 1);
803
804 if (ramfs_dp->dir_name == NULL) {
805 return RAMFS_ERR_FULL;
806 }
807 memset(ramfs_dp->dir_name, 0 ,strlen(path) + 1);
808
809 strncpy(ramfs_dp->dir_name, path, strlen(path));
810 ramfs_dp->last_entry = NULL;
811
812 return RAMFS_OK;
813 }
814
ramfs_readdir(void * dp,char * fn)815 int32_t ramfs_readdir(void *dp, char *fn)
816 {
817 int i = 0;
818 int len = 0;
819 int search = 1;
820
821 char *name = NULL;
822 char *data = NULL;
823
824 ramfs_dir_t *ramfs_dp = (ramfs_dir_t *)dp;
825
826 if (ramfs_dp->last_entry == NULL) {
827 ramfs_dp->last_entry = ramfs_ll_get_head(&g_file_ll);
828 }
829
830 while ((search == 1) && (ramfs_dp->last_entry != NULL)) {
831 if ((strncmp(ramfs_dp->dir_name, ramfs_dp->last_entry->fn, strlen(ramfs_dp->dir_name)) == 0)
832 &&(*(ramfs_dp->last_entry->fn + strlen(ramfs_dp->dir_name)) != '\0')) {
833 name = ramfs_dp->last_entry->fn + strlen(ramfs_dp->dir_name) + 1;
834 data = name;
835 len = strlen(ramfs_dp->last_entry->fn) - strlen(ramfs_dp->dir_name);
836
837 search = 0;
838
839 for (i = 0; i < len; i++) {
840 if (*name == '/') {
841 search = 1;
842 break;
843 }
844 name++;
845 }
846 }
847
848 ramfs_dp->last_entry = ramfs_ll_get_next(&g_file_ll, ramfs_dp->last_entry);
849 }
850
851 if (ramfs_dp->last_entry != NULL) {
852 strncpy(fn, data, strlen(data));
853 fn[strlen(data)] = '\0';
854 } else {
855 return RAMFS_ERR_NOT_EXIST;
856 }
857
858 return RAMFS_OK;
859 }
860
ramfs_closedir(void * dp)861 int32_t ramfs_closedir(void *dp)
862 {
863 ramfs_dir_t *ramfs_dp = (ramfs_dir_t *)dp;
864
865 if (ramfs_dp->dir_name != NULL) {
866 ramfs_mm_free(ramfs_dp->dir_name);
867 }
868
869 return RAMFS_OK;
870 }
871
ramfs_rmdir(const char * path)872 int32_t ramfs_rmdir(const char *path)
873 {
874 ramfs_entry_t *entry;
875 int ret = -1;
876 int flag = 0;
877
878 /* if file existed in the dir return error ! */
879 RAMFS_LL_READ(g_file_ll, entry) {
880 if ((strncmp(entry->fn, path, strlen(path)) == 0)
881 && (*(char*)(entry->fn + strlen(path)) == '/')) {
882 flag = 1;
883 break;
884 } else {
885 ret = ramfs_search_link_part(entry, (char *)path);
886 if (ret == RAMFS_OK) {
887 flag = 1;
888 break;
889 }
890 }
891 }
892
893 if (flag == 1) {
894 return RAMFS_ERR_DENIED;
895 }
896
897 /* if no file existed in the dir remove the dir ! */
898 RAMFS_LL_READ(g_file_ll, entry) {
899 if ((strncmp(entry->fn, path, strlen(path)) == 0) && (entry->is_dir == 1)) {
900 ramfs_ll_remove(&g_file_ll, entry);
901 ramfs_mm_free(entry->fn);
902 entry->fn = NULL;
903 ramfs_mm_free(entry);
904 }
905 }
906
907 return RAMFS_OK;
908 }
909
ramfs_stat(const char * path,ramfs_stat_t * st)910 int32_t ramfs_stat(const char *path, ramfs_stat_t *st)
911 {
912 ramfs_entry_t *entry = ramfs_entry_get(path);
913
914 if (st == NULL) {
915 return RAMFS_ERR_INV_PARAM;
916 }
917
918 if (entry != NULL) {
919 st->st_size = entry->size;
920
921 if (entry->ar == 1) {
922 st->st_mode |= RAMFS_MODE_RD;
923 }
924
925 if (entry->aw == 1) {
926 st->st_mode |= RAMFS_MODE_WR;
927 }
928
929 if (entry->is_dir == 1) {
930 st->is_dir = 1;
931 }
932
933 } else {
934 return RAMFS_ERR_NOT_EXIST;
935 }
936
937 return RAMFS_OK;
938 }
939
ramfs_add_link(ramfs_entry_t * entry,char * path)940 int ramfs_add_link(ramfs_entry_t *entry, char *path)
941 {
942 link_name_t *link_name = entry->link;
943 link_name_t *link_name_c = NULL;
944
945 link_name_c = ramfs_mm_alloc(sizeof(link_name_t));
946
947 if (link_name_c != NULL) {
948 link_name_c->name = ramfs_mm_alloc(strlen(path) + 1);
949 if (link_name_c->name != NULL) {
950 memset(link_name_c->name, 0, strlen(path) + 1);
951 strncpy(link_name_c->name, path, strlen(path));
952 link_name_c->next = NULL;
953 entry->link_count += 1;
954 } else {
955 ramfs_mm_free(link_name_c);
956 return RAMFS_ERR_MALLOC;
957 }
958 } else {
959 return RAMFS_ERR_MALLOC;
960 }
961
962 if (link_name == NULL) {
963 entry->link = link_name_c;
964 } else {
965 while (link_name->next != NULL) {
966 link_name = link_name->next;
967 }
968
969 link_name->next = link_name_c;
970 }
971
972 return 0;
973 }
974
ramfs_remove_link(ramfs_entry_t * entry,char * path)975 int ramfs_remove_link(ramfs_entry_t *entry, char *path)
976 {
977 link_name_t *link_name = entry->link;
978 link_name_t *link_name_c = NULL;
979 link_name_t *link_name_l = NULL;
980
981 if (link_name == NULL) {
982 return RAMFS_ERR_INV_PARAM;
983 }
984
985 if (strncmp(link_name->name, path, strlen(path)) == 0) {
986 ramfs_mm_free(link_name->name);
987 link_name->name = ramfs_mm_alloc(strlen(link_name->next->name) + 1);
988 if (link_name->name == NULL) {
989 return RAMFS_ERR_MALLOC;
990 }
991 memset(link_name->name, 0 , strlen(link_name->next->name) + 1);
992 strncpy(link_name->name, link_name->next->name, strlen(link_name->next->name));
993 link_name->next = link_name->next->next;
994 entry->link_count -= 1;
995 } else {
996 link_name_l = link_name;
997 link_name_c = link_name->next;
998
999 while (link_name_c != NULL) {
1000 if (strncmp(link_name_c->name, path, strlen(path)) == 0) {
1001 link_name_l->next = link_name_c->next;
1002 ramfs_mm_free(link_name_c->name);
1003 ramfs_mm_free(link_name_c);
1004 entry->link_count -= 1;
1005 }
1006
1007 link_name_l = link_name_c;
1008 link_name_c = link_name_c->next;
1009 }
1010 }
1011
1012 return 0;
1013 }
1014
ramfs_link(const char * path1,const char * path2)1015 int ramfs_link(const char *path1, const char *path2)
1016 {
1017 ramfs_entry_t *entry = NULL;
1018 int ret = -1;
1019
1020 entry = ramfs_entry_get(path2);
1021 if (entry != NULL) {
1022 return RAMFS_ERR_PATH;
1023 }
1024
1025 entry = ramfs_entry_get(path1);
1026 if (entry == NULL) {
1027 return RAMFS_ERR_NOT_EXIST;
1028 }
1029
1030 if ((entry != NULL) && (entry->is_dir == 1)) {
1031 return RAMFS_ERR_PATH;
1032 }
1033
1034 if (entry->link_count >= RAMFS_LINK_MAX) {
1035 return RAMFS_ERR_LINK_MAX;
1036 }
1037
1038 ret = ramfs_add_link(entry, (char *)path2);
1039 if (ret != 0) {
1040 return RAMFS_ERR_MALLOC;
1041 }
1042
1043 return 0;
1044 }
1045
ramfs_unlink(const char * path)1046 int ramfs_unlink(const char *path)
1047 {
1048 ramfs_entry_t *entry = NULL;
1049 int ret = -1;
1050
1051 entry = ramfs_entry_get(path);
1052 if (entry == NULL) {
1053 return RAMFS_ERR_PATH;
1054 }
1055
1056 if (strncmp(entry->fn, path, strlen(path)) == 0) {
1057 ret = ramfs_remove(path);
1058 } else {
1059 ret = ramfs_remove_link(entry, (char *)path);
1060 }
1061
1062 return ret;
1063 }
1064
ramfs_pathconf(int32_t name)1065 int32_t ramfs_pathconf(int32_t name)
1066 {
1067 int32_t val = 0;
1068
1069 switch (name) {
1070 case _PC_FILESIZEBITS :
1071 val = -1;
1072 break;
1073 case _PC_LINK_MAX :
1074 val = RAMFS_LINK_MAX;
1075 break;
1076 case _PC_MAX_CANON :
1077 val = -1;
1078 break;
1079 case _PC_MAX_INPUT :
1080 val = -1;
1081 break;
1082 case _PC_NAME_MAX :
1083 val = RAMFS_NAME_MAX;
1084 break;
1085 case _PC_PATH_MAX :
1086 val = RAMFS_PATH_MAX;
1087 break;
1088 case _PC_PIPE_BUF :
1089 val = -1;
1090 break;
1091 case _PC_2_SYMLINKS :
1092 val = -1;
1093 break;
1094 case _PC_ALLOC_SIZE_MIN :
1095 val = RAMFS_ALLOC_SIZE_MIN;
1096 break;
1097 case _PC_REC_INCR_XFER_SIZE :
1098 val = -1;
1099 break;
1100 case _PC_REC_MAX_XFER_SIZE :
1101 val = -1;
1102 break;
1103 case _PC_REC_MIN_XFER_SIZE :
1104 val = -1;
1105 break;
1106 case _PC_REC_XFER_ALIGN :
1107 val = -1;
1108 break;
1109 case _PC_SYMLINK_MAX :
1110 val = -1;
1111 break;
1112 case _PC_CHOWN_RESTRICTED :
1113 val = -1;
1114 break;
1115 case _PC_NO_TRUNC :
1116 val = -1;
1117 break;
1118 case _PC_VDISABLE :
1119 val = -1;
1120 break;
1121 case _PC_ASYNC_IO :
1122 val = -1;
1123 break;
1124 case _PC_PRIO_IO :
1125 val = -1;
1126 break;
1127 case _PC_SYNC_IO :
1128 val = -1;
1129 break;
1130 default:
1131 val = -1;
1132 break;
1133 }
1134
1135 return val;
1136 }
1137