µOS++ IIIe Reference 7.0.0
The third edition of µOS++, a POSIX inspired open source framework, written in C++
Loading...
Searching...
No Matches
file-system.cpp
Go to the documentation of this file.
1/*
2 * This file is part of the µOS++ distribution.
3 * (https://github.com/micro-os-plus)
4 * Copyright (c) 2015-2023 Liviu Ionescu. All rights reserved.
5 *
6 * Permission to use, copy, modify, and/or distribute this software
7 * for any purpose is hereby granted, under the terms of the MIT license.
8 *
9 * If a copy of the license was not distributed with this file, it can
10 * be obtained from https://opensource.org/licenses/mit/.
11 */
12
13#if defined(OS_USE_OS_APP_CONFIG_H)
14#include <cmsis-plus/os-app-config.h>
15#endif
16
20
21#include <cerrno>
22#include <cassert>
23#include <cstring>
24
25// ----------------------------------------------------------------------------
26
27#if defined(__clang__)
28#pragma clang diagnostic ignored "-Wc++98-compat"
29#elif defined(__GNUC__)
30#pragma GCC diagnostic ignored "-Wsuggest-final-methods"
31#endif
32
33// ----------------------------------------------------------------------------
34
35namespace os
36{
37 namespace posix
38 {
39 // ------------------------------------------------------------------------
40
45#pragma GCC diagnostic push
46#if defined(__clang__)
47#pragma clang diagnostic ignored "-Wexit-time-destructors"
48#pragma clang diagnostic ignored "-Wglobal-constructors"
49#endif
50
51 file_system::mounted_list file_system::mounted_list__;
52
53#pragma GCC diagnostic pop
54
55 /* class */ file_system* file_system::mounted_root__;
56
61 // ------------------------------------------------------------------------
62 int
63 mkdir (const char* path, mode_t mode)
64 {
65#if defined(OS_TRACE_POSIX_IO_FILE_SYSTEM)
66 trace::printf ("%s(\"%s\", %u)\n", __func__, path, mode);
67#endif
68
69 if (path == nullptr)
70 {
71 errno = EFAULT;
72 return -1;
73 }
74
75 if (*path == '\0')
76 {
77 errno = ENOENT;
78 return -1;
79 }
80
81 auto adjusted_path = path;
82 auto* const fs = file_system::identify_mounted (&adjusted_path);
83
84 if (fs == nullptr)
85 {
86 errno = ENOENT;
87 return -1;
88 }
89
90 // Execute the implementation specific code.
91 return fs->mkdir (adjusted_path, mode);
92 }
93
94 int
95 rmdir (const char* path)
96 {
97#if defined(OS_TRACE_POSIX_IO_FILE_SYSTEM)
98 trace::printf ("%s(\"%s\")\n", __func__, path);
99#endif
100
101 if (path == nullptr)
102 {
103 errno = EFAULT;
104 return -1;
105 }
106
107 if (*path == '\0')
108 {
109 errno = ENOENT;
110 return -1;
111 }
112
113 auto adjusted_path = path;
114 auto* const fs = file_system::identify_mounted (&adjusted_path);
115
116 if (fs == nullptr)
117 {
118 errno = ENOENT;
119 return -1;
120 }
121
122 // Execute the implementation specific code.
123 return fs->rmdir (adjusted_path);
124 }
125
126 void
127 sync (void)
128 {
129#if defined(OS_TRACE_POSIX_IO_FILE_SYSTEM)
130 trace::printf ("%s()\n", __func__);
131#endif
132
133 // Enumerate all mounted file systems and sync them.
134#pragma GCC diagnostic push
135#if defined(__clang__)
136#elif defined(__GNUC__)
137#pragma GCC diagnostic ignored "-Waggregate-return"
138#endif
139 for (auto&& fs : file_system::mounted_list__)
140#pragma GCC diagnostic pop
141 {
142 fs.sync ();
143 }
144
145 if (file_system::mounted_root__ != nullptr)
146 {
147 file_system::mounted_root__->sync ();
148 }
149 }
150
151 // ------------------------------------------------------------------------
152 // Functions related to files, other than IO. The implementations is
153 // specific to each file_system.
154
155 int
156 chmod (const char* path, mode_t mode)
157 {
158#if defined(OS_TRACE_POSIX_IO_FILE_SYSTEM)
159 trace::printf ("%s(\"%s\", %u)\n", __func__, path, mode);
160#endif
161
162 if (path == nullptr)
163 {
164 errno = EFAULT;
165 return -1;
166 }
167
168 if (*path == '\0')
169 {
170 errno = ENOENT;
171 return -1;
172 }
173
174 const char* adjusted_path = path;
175 auto* const fs = file_system::identify_mounted (&adjusted_path);
176
177 if (fs == nullptr)
178 {
179 errno = ENOENT;
180 return -1;
181 }
182
183 return fs->chmod (adjusted_path, mode);
184 }
185
186 int
187 stat (const char* path, struct stat* buf)
188 {
189#if defined(OS_TRACE_POSIX_IO_FILE_SYSTEM)
190 trace::printf ("%s(\"%s\", %p)\n", __func__, path, buf);
191#endif
192
193 if ((path == nullptr) || (buf == nullptr))
194 {
195 errno = EFAULT;
196 return -1;
197 }
198
199 if (*path == '\0')
200 {
201 errno = ENOENT;
202 return -1;
203 }
204
205 const char* adjusted_path = path;
206 auto* const fs = file_system::identify_mounted (&adjusted_path);
207
208 if (fs == nullptr)
209 {
210 errno = ENOENT;
211 return -1;
212 }
213
214 return fs->stat (adjusted_path, buf);
215 }
216
217 int
218 truncate (const char* path, off_t length)
219 {
220#if defined(OS_TRACE_POSIX_IO_FILE_SYSTEM)
221 trace::printf ("%s(\"%s\", %u)\n", __func__, path, length);
222#endif
223
224 if (path == nullptr)
225 {
226 errno = EFAULT;
227 return -1;
228 }
229
230 if (*path == '\0')
231 {
232 errno = ENOENT;
233 return -1;
234 }
235
236 const char* adjusted_path = path;
237 auto* const fs = file_system::identify_mounted (&adjusted_path);
238
239 if (fs == nullptr)
240 {
241 errno = ENOENT;
242 return -1;
243 }
244
245 if (length < 0)
246 {
247 errno = EINVAL;
248 return -1;
249 }
250
251 return fs->truncate (adjusted_path, length);
252 }
253
254 int
255 rename (const char* existing, const char* _new)
256 {
257#if defined(OS_TRACE_POSIX_IO_FILE_SYSTEM)
258 trace::printf ("%s(\"%s\",\"%s\")\n", __func__, existing, _new);
259#endif
260
261 if ((existing == nullptr) || (_new == nullptr))
262 {
263 errno = EFAULT;
264 return -1;
265 }
266
267 if ((*existing == '\0') || (*_new == '\0'))
268 {
269 errno = ENOENT;
270 return -1;
271 }
272
273 auto adjusted_existing = existing;
274 auto adjusted_new = _new;
275 auto* const fs = file_system::identify_mounted (&adjusted_existing,
276 &adjusted_new);
277
278 if (fs == nullptr)
279 {
280 errno = ENOENT;
281 return -1;
282 }
283
284 return fs->rename (adjusted_existing, adjusted_new);
285 }
286
287 int
288 unlink (const char* path)
289 {
290#if defined(OS_TRACE_POSIX_IO_FILE_SYSTEM)
291 trace::printf ("%s(\"%s\")\n", __func__, path);
292#endif
293
294 if (path == nullptr)
295 {
296 errno = EFAULT;
297 return -1;
298 }
299
300 if (*path == '\0')
301 {
302 errno = ENOENT;
303 return -1;
304 }
305
306 auto adjusted_path = path;
307 auto* const fs = file_system::identify_mounted (&adjusted_path);
308
309 if (fs == nullptr)
310 {
311 errno = ENOENT;
312 return -1;
313 }
314
315 return fs->unlink (adjusted_path);
316 }
317
318 int
319 utime (const char* path, const /* struct */ utimbuf* times)
320 {
321#if defined(OS_TRACE_POSIX_IO_FILE_SYSTEM)
322 trace::printf ("%s(\"%s\", %p)\n", __func__, path, times);
323#endif
324
325 if ((path == nullptr) || (times == nullptr))
326 {
327 errno = EFAULT;
328 return -1;
329 }
330
331 if (*path == '\0')
332 {
333 errno = ENOENT;
334 return -1;
335 }
336
337 auto adjusted_path = path;
338 auto* const fs = file_system::identify_mounted (&adjusted_path);
339
340 if (fs == nullptr)
341 {
342 errno = ENOENT;
343 return -1;
344 }
345
346 return fs->utime (adjusted_path, times);
347 }
348
349 int
350 statvfs (const char* path, struct statvfs* buf)
351 {
352#if defined(OS_TRACE_POSIX_IO_FILE_SYSTEM)
353 trace::printf ("%s(\"%s\", %p)\n", __func__, path, buf);
354#endif
355
356 if ((path == nullptr) || (buf == nullptr))
357 {
358 errno = EFAULT;
359 return -1;
360 }
361
362 if (*path == '\0')
363 {
364 errno = ENOENT;
365 return -1;
366 }
367
368 auto adjusted_path = path;
369 auto* const fs = file_system::identify_mounted (&adjusted_path);
370
371 if (fs == nullptr)
372 {
373 errno = ENOENT;
374 return -1;
375 }
376
377 return fs->statvfs (buf);
378 }
379
380 directory*
381 opendir (const char* dirpath)
382 {
383#if defined(OS_TRACE_POSIX_IO_FILE_SYSTEM)
384 trace::printf ("%s(\"%s\")\n", __func__, dirpath);
385#endif
386
387 if (dirpath == nullptr)
388 {
389 errno = EFAULT;
390 return nullptr;
391 }
392
393 if (*dirpath == '\0')
394 {
395 errno = ENOENT;
396 return nullptr;
397 }
398
399 errno = 0;
400
402
403 while (true)
404 {
405 // Check if path is a device.
408 if (io != nullptr)
409 {
410 // Cannot list devices (for now).
411 return nullptr;
412 }
413
414 // Check if a regular folder.
415 auto adjusted_path = dirpath;
417 &adjusted_path);
418
419 // The manager will return null if there are no file systems
420 // registered, no need to check this condition separately.
421 if (fs == nullptr)
422 {
423 errno = EBADF;
424 return nullptr;
425 }
426
427 // Use the file system implementation to open the directory, using
428 // the adjusted path (mount point prefix removed).
429 dir = fs->opendir (adjusted_path);
430 if (dir == nullptr)
431 {
432 // Open failed.
433 return nullptr;
434 }
435
436 break;
437 }
438
439 // Return a valid pointer to an object derived from directory, or nullptr.
440
441#if defined(OS_TRACE_POSIX_IO_FILE_SYSTEM)
442 trace::printf ("%s(\"%s\")=%p\n", __func__, dirpath, dir);
443#endif
444 return dir;
445 }
446
447 // ========================================================================
448
449 file_system::file_system (file_system_impl& impl, const char* name) :
450 name_ (name), //
451 impl_ (impl)
452 {
453#if defined(OS_TRACE_POSIX_IO_FILE_SYSTEM)
454 trace::printf ("file_system::%s(\"%s\")=%p\n", __func__, name_, this);
455#endif
456 deferred_files_list_.clear ();
457 deferred_directories_list_.clear ();
458 }
459
461 {
462#if defined(OS_TRACE_POSIX_IO_FILE_SYSTEM)
463 trace::printf ("file_system::%s() @%p %s\n", __func__, this, name_);
464#endif
465 }
466
467 // ------------------------------------------------------------------------
468
469 int
470 file_system::mkfs (int options, ...)
471 {
472 // Forward to the variadic version of the function.
473 std::va_list args;
474 va_start(args, options);
475 int ret = vmkfs (options, args);
476 va_end(args);
477
478 return ret;
479 }
480
481 int
482 file_system::vmkfs (int options, std::va_list args)
483 {
484#if defined(OS_TRACE_POSIX_IO_FILE_SYSTEM)
485 trace::printf ("file_system::%s(%u) @%p\n", __func__, options, this);
486#endif
487
488 if (mounted_path_ != nullptr)
489 {
490 // File system already mounted.
491 errno = EBUSY;
492 return -1;
493 }
494
495 errno = 0;
496
497 int ret;
498 ret = impl ().do_vmkfs (options, args);
499
500 return ret;
501 }
502
503 int
504 file_system::mount (const char* path, unsigned int flags, ...)
505 {
506 // Forward to the variadic version of the function.
507 std::va_list args;
508 va_start(args, flags);
509 int ret = vmount (path, flags, args);
510 va_end(args);
511
512 return ret;
513 }
514
515 int
516 file_system::vmount (const char* path, unsigned int flags,
517 std::va_list args)
518 {
519#if defined(OS_TRACE_POSIX_IO_FILE_SYSTEM)
520 trace::printf ("file_system::%s(\"%s\", %u) @%p\n", __func__,
521 path ? path : "nullptr", flags, this);
522#endif
523
524 if (mounted_path_ != nullptr)
525 {
526 // File system already mounted.
527 errno = EBUSY;
528 return -1;
529 }
530
531 if (path != nullptr)
532 {
533#pragma GCC diagnostic push
534#if defined(__clang__)
535#elif defined(__GNUC__)
536#pragma GCC diagnostic ignored "-Waggregate-return"
537#endif
538 for (auto&& fs : mounted_list__)
539#pragma GCC diagnostic pop
540 {
541 // Validate the device name by checking duplicates.
542 if (std::strcmp (path, fs.mounted_path_) == 0)
543 {
544 trace::printf ("Path \"%s\" already mounted.", path);
545
546 errno = EBUSY;
547 return -1;
548 }
549 }
550 }
551
552 char* p = const_cast<char*> (path);
553 if (p != nullptr)
554 {
555 if (strcmp ("/", path) == 0)
556 {
557 p = nullptr;
558 }
559 }
560
561 errno = 0;
562
563 int ret = impl ().do_vmount (flags, args);
564 if (ret < 0)
565 {
566 return -1;
567 }
568
569 if (p == nullptr)
570 {
571 mounted_root__ = this;
572 mounted_path_ = "/";
573 }
574 else
575 {
576 mounted_list__.link (*this);
577 mounted_path_ = path;
578 }
579
580 return 0;
581 }
582
588 int
589 file_system::umount (int unsigned flags)
590 {
591#if defined(OS_TRACE_POSIX_IO_FILE_SYSTEM)
592 trace::printf ("file_system::%s(%u) @%p\n", __func__, flags, this);
593#endif
594
595 mount_manager_links_.unlink ();
596 mounted_path_ = nullptr;
597
598 if (this == mounted_root__)
599 {
600 if (!mounted_list__.empty ())
601 {
602 errno = EBUSY;
603 return -1;
604 }
605
606 mounted_root__ = nullptr;
607 }
608
609 if (!device ().is_opened ())
610 {
611 errno = EBADF; // Not opened.
612 return -1;
613 }
614
615 impl ().do_sync ();
616 int ret = impl ().do_umount (flags);
617 return ret;
618 }
619
621 file_system::identify_mounted (const char** path1, const char** path2)
622 {
623 assert(path1 != nullptr);
624 assert(*path1 != nullptr);
625
626#pragma GCC diagnostic push
627#if defined(__clang__)
628#elif defined(__GNUC__)
629#pragma GCC diagnostic ignored "-Waggregate-return"
630#endif
631 for (auto&& fs : mounted_list__)
632#pragma GCC diagnostic pop
633 {
634 auto len = std::strlen (fs.mounted_path_);
635
636 // Check if path1 starts with the mounted path.
637 if (std::strncmp (fs.mounted_path_, *path1, len) == 0)
638 {
639 // If so, adjust paths to skip over prefix, but keep '/'.
640 *path1 = (*path1 + len - 1);
641 while ((*path1)[1] == '/')
642 {
643 *path1 = (*path1 + 1);
644 }
645
646 if ((path2 != nullptr) && (*path2 != nullptr))
647 {
648 *path2 = (*path2 + len - 1);
649 while ((*path2)[1] == '/')
650 {
651 *path2 = (*path2 + 1);
652 }
653 }
654
655 return &fs;
656 }
657 }
658
659 // If root file system defined, return it.
660 if (mounted_root__ != nullptr)
661 {
662 return mounted_root__;
663 }
664
665 // Not found.
666 return nullptr;
667 }
668
669 // ------------------------------------------------------------------------
670
671 file*
672 file_system::open (const char* path, int oflag, ...)
673 {
674 // Forward to the variadic version of the function.
675 std::va_list args;
676 va_start(args, oflag);
677 file* ret = vopen (path, oflag, args);
678 va_end(args);
679
680 return ret;
681 }
682
683 file*
684 file_system::vopen (const char* path, int oflag, std::va_list args)
685 {
686#if defined(OS_TRACE_POSIX_IO_FILE_SYSTEM)
687 trace::printf ("file_system::%s(\"%s\", %u)\n", __func__, path, oflag);
688#endif
689
690 if (!device ().is_opened ())
691 {
692 errno = EBADF; // Not opened.
693 return nullptr;
694 }
695
696 errno = 0;
697
698 // Execute the file specific implementation code.
699 // Allocation is done by the implementation, where
700 // the size is known.
701 file* fil = impl ().do_vopen (*this, path, oflag, args);
702 if (fil == nullptr)
703 {
704 return nullptr;
705 }
706
707 // If successful, allocate a file descriptor.
708 fil->alloc_file_descriptor ();
709
710 return fil;
711 }
712
713 directory*
714 file_system::opendir (const char* dirpath)
715 {
716#if defined(OS_TRACE_POSIX_IO_FILE_SYSTEM)
717 trace::printf ("file_system::%s(\"%s\")\n", __func__, dirpath);
718#endif
719
720 if (!device ().is_opened ())
721 {
722 errno = EBADF; // Not opened.
723 return nullptr;
724 }
725
726 errno = 0;
727
728 // Execute the dir specific implementation code.
729 // Allocation is done by the implementation, where
730 // the size is known.
731 directory* dir = impl ().do_opendir (*this, dirpath);
732 if (dir == nullptr)
733 {
734 return nullptr;
735 }
736
737 return dir;
738 }
739
740 // ------------------------------------------------------------------------
741
742 int
743 file_system::mkdir (const char* path, mode_t mode)
744 {
745#if defined(OS_TRACE_POSIX_IO_FILE_SYSTEM)
746 trace::printf ("file_system::%s(\"%s\", %u)\n", __func__, path, mode);
747#endif
748
749 if (path == nullptr)
750 {
751 errno = EFAULT;
752 return -1;
753 }
754
755 if (*path == '\0')
756 {
757 errno = ENOENT;
758 return -1;
759 }
760
761 if (!device ().is_opened ())
762 {
763 errno = EBADF; // Not opened.
764 return -1;
765 }
766
767 errno = 0;
768
769 return impl ().do_mkdir (path, mode);
770 }
771
772 int
773 file_system::rmdir (const char* path)
774 {
775#if defined(OS_TRACE_POSIX_IO_FILE_SYSTEM)
776 trace::printf ("file_system::%s(\"%s\")\n", __func__, path);
777#endif
778
779 if (path == nullptr)
780 {
781 errno = EFAULT;
782 return -1;
783 }
784
785 if (*path == '\0')
786 {
787 errno = ENOENT;
788 return -1;
789 }
790
791 if (!device ().is_opened ())
792 {
793 errno = EBADF; // Not opened.
794 return -1;
795 }
796
797 errno = 0;
798
799 return impl ().do_rmdir (path);
800 }
801
802 void
804 {
805#if defined(OS_TRACE_POSIX_IO_FILE_SYSTEM)
806 trace::printf ("file_system::%s() @%p\n", __func__, this);
807#endif
808
809 if (!device ().is_opened ())
810 {
811 errno = EBADF; // Not opened.
812 return;
813 }
814
815 errno = 0;
816
817 impl ().do_sync ();
818 }
819
820 // ------------------------------------------------------------------------
821
822 int
823 file_system::chmod (const char* path, mode_t mode)
824 {
825#if defined(OS_TRACE_POSIX_IO_FILE_SYSTEM)
826 trace::printf ("file_system::%s(\"%s\", %u)\n", __func__, path, mode);
827#endif
828
829 if (path == nullptr)
830 {
831 errno = EFAULT;
832 return -1;
833 }
834
835 if (*path == '\0')
836 {
837 errno = ENOENT;
838 return -1;
839 }
840
841 if (!device ().is_opened ())
842 {
843 errno = EBADF; // Not opened.
844 return -1;
845 }
846
847 errno = 0;
848
849 // Execute the implementation specific code.
850 return impl ().do_chmod (path, mode);
851 }
852
853 int
854 file_system::stat (const char* path, struct stat* buf)
855 {
856#if defined(OS_TRACE_POSIX_IO_FILE_SYSTEM)
857 trace::printf ("file_system::%s(\"%s\", %p)\n", __func__, path, buf);
858#endif
859
860 if ((path == nullptr) || (buf == nullptr))
861 {
862 errno = EFAULT;
863 return -1;
864 }
865
866 if (*path == '\0')
867 {
868 errno = ENOENT;
869 return -1;
870 }
871
872 if (!device ().is_opened ())
873 {
874 errno = EBADF; // Not opened.
875 return -1;
876 }
877
878 errno = 0;
879
880 // Execute the implementation specific code.
881 return impl ().do_stat (path, buf);
882 }
883
884 int
885 file_system::truncate (const char* path, off_t length)
886 {
887#if defined(OS_TRACE_POSIX_IO_FILE_SYSTEM)
888 trace::printf ("file_system::%s(\"%s\", %u)\n", __func__, path, length);
889#endif
890
891 if (path == nullptr)
892 {
893 errno = EFAULT;
894 return -1;
895 }
896
897 if (*path == '\0')
898 {
899 errno = ENOENT;
900 return -1;
901 }
902
903 if (!device ().is_opened ())
904 {
905 errno = EBADF; // Not opened.
906 return -1;
907 }
908
909 errno = 0;
910
911 // Execute the implementation specific code.
912 return impl ().do_truncate (path, length);
913 }
914
915 int
916 file_system::rename (const char* existing, const char* _new)
917 {
918#if defined(OS_TRACE_POSIX_IO_FILE_SYSTEM)
919 trace::printf ("file_system::%s(\"%s\",\"%s\")\n", __func__, existing,
920 _new);
921#endif
922
923 if ((existing == nullptr) || (_new == nullptr))
924 {
925 errno = EFAULT;
926 return -1;
927 }
928
929 if ((*existing == '\0') || (*_new == '\0'))
930 {
931 errno = ENOENT;
932 return -1;
933 }
934
935 if (!device ().is_opened ())
936 {
937 errno = EBADF; // Not opened.
938 return -1;
939 }
940
941 errno = 0;
942
943 // Execute the implementation specific code.
944 return impl ().do_rename (existing, _new);
945 }
946
947 int
948 file_system::unlink (const char* path)
949 {
950#if defined(OS_TRACE_POSIX_IO_FILE_SYSTEM)
951 trace::printf ("file_system::%s(\"%s\")\n", __func__, path);
952#endif
953
954 if (path == nullptr)
955 {
956 errno = EFAULT;
957 return -1;
958 }
959
960 if (*path == '\0')
961 {
962 errno = ENOENT;
963 return -1;
964 }
965
966 if (!device ().is_opened ())
967 {
968 errno = EBADF; // Not opened.
969 return -1;
970 }
971
972 errno = 0;
973
974 // Execute the implementation specific code.
975 return impl ().do_unlink (path);
976 }
977
978 // http://pubs.opengroup.org/onlinepubs/9699919799/functions/utime.html
979 int
980 file_system::utime (const char* path, const /* struct */ utimbuf* times)
981 {
982#if defined(OS_TRACE_POSIX_IO_FILE_SYSTEM)
983 trace::printf ("file_system::%s(\"%s\", %p)\n", __func__, path, times);
984#endif
985
986 if ((path == nullptr) || (times == nullptr))
987 {
988 errno = EFAULT;
989 return -1;
990 }
991
992 if (*path == '\0')
993 {
994 errno = ENOENT;
995 return -1;
996 }
997
998 if (!device ().is_opened ())
999 {
1000 errno = EBADF; // Not opened.
1001 return -1;
1002 }
1003
1004 errno = 0;
1005
1006 /* struct */ utimbuf tmp;
1007 if (times == nullptr)
1008 {
1009 // If times is a null pointer, the access and modification times
1010 // of the file shall be set to the current time.
1011 tmp.actime = time (nullptr);
1012 tmp.modtime = tmp.actime;
1013 return impl ().do_utime (path, &tmp);
1014 }
1015 else
1016 {
1017 // Execute the implementation specific code.
1018 return impl ().do_utime (path, times);
1019 }
1020 }
1021
1022 // http://pubs.opengroup.org/onlinepubs/9699919799/functions/fstatvfs.html
1023 int
1025 {
1026#if defined(OS_TRACE_POSIX_IO_FILE_SYSTEM)
1027 trace::printf ("file_system::%s(%p)\n", __func__, buf);
1028#endif
1029
1030 if (!device ().is_opened ())
1031 {
1032 errno = EBADF; // Not opened.
1033 return -1;
1034 }
1035
1036 return impl ().do_statvfs (buf);
1037 }
1038 // TODO: check if the file system should keep a static current path for
1039 // relative paths.
1040
1041 // http://pubs.opengroup.org/onlinepubs/9699919799/functions/chdir.html
1042 // ------------------------------------------------------------------------
1043
1044 // ========================================================================
1045
1047 device_ (device)
1048 {
1049#if defined(OS_TRACE_POSIX_IO_FILE_SYSTEM)
1050 trace::printf ("file_system_impl::%s()=%p\n", __func__, this);
1051#endif
1052 }
1053
1055 {
1056#if defined(OS_TRACE_POSIX_IO_FILE_SYSTEM)
1057 trace::printf ("file_system_impl::%s() @%p\n", __func__, this);
1058#endif
1059 }
1060
1061 // ==========================================================================
1062 } /* namespace posix */
1063} /* namespace os */
1064
1065// ----------------------------------------------------------------------------
Block device class.
static value_type * identify_device(const char *path)
Base device class.
Definition device.h:68
Directory class.
Definition directory.h:76
virtual int do_rename(const char *existing, const char *_new)=0
virtual int do_mkdir(const char *path, mode_t mode)=0
virtual directory * do_opendir(file_system &fs, const char *dirname)=0
virtual int do_unlink(const char *path)=0
file_system_impl(block_device &device)
virtual int do_umount(unsigned int flags)=0
virtual void do_sync(void)=0
virtual int do_truncate(const char *path, off_t length)=0
virtual int do_vmkfs(int options, std::va_list args)=0
virtual int do_chmod(const char *path, mode_t mode)=0
virtual int do_vmount(unsigned int flags, std::va_list args)=0
virtual int do_utime(const char *path, const utimbuf *times)=0
virtual file * do_vopen(file_system &fs, const char *path, int oflag, std::va_list args)=0
virtual int do_stat(const char *path, struct stat *buf)=0
virtual int do_statvfs(struct statvfs *buf)=0
virtual int do_rmdir(const char *path)=0
File system class.
int mount(const char *path=nullptr, unsigned int flags=0,...)
virtual int truncate(const char *path, off_t length)
file * open(const char *path=nullptr, int oflag=0,...)
virtual int mkdir(const char *path, mode_t mode)
virtual int rename(const char *existing, const char *_new)
file_system(file_system_impl &impl, const char *name)
virtual void sync(void)
virtual int unlink(const char *path)
virtual int statvfs(struct statvfs *buf)
virtual int utime(const char *path, const utimbuf *times)
virtual int stat(const char *path, struct stat *buf)
static file_system * identify_mounted(const char **path1, const char **path2=nullptr)
int mkfs(int options,...)
virtual int chmod(const char *path, mode_t mode)
virtual int vmount(const char *path, unsigned int flags, std::va_list args)
Mount file system.
virtual file * vopen(const char *path, int oflag, std::va_list args)
virtual int umount(int unsigned flags=0)
Unmount file system.
virtual int rmdir(const char *path)
file_system_impl & impl(void) const
virtual int vmkfs(int options, std::va_list args)
virtual directory * opendir(const char *dirpath)
File class.
Definition file.h:65
Base I/O class.
Definition io.h:87
io * alloc_file_descriptor(void)
Definition io.cpp:190
int printf(const char *format,...)
Write a formatted string to the trace device.
Definition trace.cpp:60
clock_t times(struct tms *buf)
int utime(const char *path, const utimbuf *times)
int unlink(const char *path)
int rmdir(const char *path)
int rename(const char *existing, const char *_new)
int stat(const char *path, struct stat *buf)
int chmod(const char *path, mode_t mode)
int truncate(const char *path, off_t length)
void sync(void)
directory * opendir(const char *dirname)
Open directory.
int mkdir(const char *path, mode_t mode)
System namespace.