µ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++ project (https://micro-os-plus.github.io/).
3 * Copyright (c) 2015-2025 Liviu Ionescu. All rights reserved.
4 *
5 * Permission to use, copy, modify, and/or distribute this software
6 * for any purpose is hereby granted, under the terms of the MIT license.
7 *
8 * If a copy of the license was not distributed with this file, it can
9 * be obtained from https://opensource.org/licenses/mit.
10 */
11
12#if defined(OS_USE_OS_APP_CONFIG_H)
13#include <cmsis-plus/os-app-config.h>
14#endif
15
19
20#include <cerrno>
21#include <cassert>
22#include <cstring>
23
24// ----------------------------------------------------------------------------
25
26#if defined(__clang__)
27#pragma clang diagnostic ignored "-Wc++98-compat"
28#elif defined(__GNUC__)
29#pragma GCC diagnostic ignored "-Wsuggest-final-methods"
30#endif
31
32// ----------------------------------------------------------------------------
33
34namespace os
35{
36 namespace posix
37 {
38 // ------------------------------------------------------------------------
39
44#pragma GCC diagnostic push
45#if defined(__clang__)
46#pragma clang diagnostic ignored "-Wexit-time-destructors"
47#pragma clang diagnostic ignored "-Wglobal-constructors"
48#endif
49
50 file_system::mounted_list file_system::mounted_list__;
51
52#pragma GCC diagnostic pop
53
54 /* class */ file_system* file_system::mounted_root__;
55
60 // ------------------------------------------------------------------------
61 int
62 mkdir (const char* path, mode_t mode)
63 {
64#if defined(OS_TRACE_POSIX_IO_FILE_SYSTEM)
65 trace::printf ("%s(\"%s\", %u)\n", __func__, path, mode);
66#endif
67
68 if (path == nullptr)
69 {
70 errno = EFAULT;
71 return -1;
72 }
73
74 if (*path == '\0')
75 {
76 errno = ENOENT;
77 return -1;
78 }
79
80 auto adjusted_path = path;
81 auto* const fs = file_system::identify_mounted (&adjusted_path);
82
83 if (fs == nullptr)
84 {
85 errno = ENOENT;
86 return -1;
87 }
88
89 // Execute the implementation specific code.
90 return fs->mkdir (adjusted_path, mode);
91 }
92
93 int
94 rmdir (const char* path)
95 {
96#if defined(OS_TRACE_POSIX_IO_FILE_SYSTEM)
97 trace::printf ("%s(\"%s\")\n", __func__, path);
98#endif
99
100 if (path == nullptr)
101 {
102 errno = EFAULT;
103 return -1;
104 }
105
106 if (*path == '\0')
107 {
108 errno = ENOENT;
109 return -1;
110 }
111
112 auto adjusted_path = path;
113 auto* const fs = file_system::identify_mounted (&adjusted_path);
114
115 if (fs == nullptr)
116 {
117 errno = ENOENT;
118 return -1;
119 }
120
121 // Execute the implementation specific code.
122 return fs->rmdir (adjusted_path);
123 }
124
125 void
126 sync (void)
127 {
128#if defined(OS_TRACE_POSIX_IO_FILE_SYSTEM)
129 trace::printf ("%s()\n", __func__);
130#endif
131
132 // Enumerate all mounted file systems and sync them.
133#pragma GCC diagnostic push
134#if defined(__clang__)
135#elif defined(__GNUC__)
136#pragma GCC diagnostic ignored "-Waggregate-return"
137#endif
138 for (auto&& fs : file_system::mounted_list__)
139#pragma GCC diagnostic pop
140 {
141 fs.sync ();
142 }
143
144 if (file_system::mounted_root__ != nullptr)
145 {
146 file_system::mounted_root__->sync ();
147 }
148 }
149
150 // ------------------------------------------------------------------------
151 // Functions related to files, other than IO. The implementations is
152 // specific to each file_system.
153
154 int
155 chmod (const char* path, mode_t mode)
156 {
157#if defined(OS_TRACE_POSIX_IO_FILE_SYSTEM)
158 trace::printf ("%s(\"%s\", %u)\n", __func__, path, mode);
159#endif
160
161 if (path == nullptr)
162 {
163 errno = EFAULT;
164 return -1;
165 }
166
167 if (*path == '\0')
168 {
169 errno = ENOENT;
170 return -1;
171 }
172
173 const char* adjusted_path = path;
174 auto* const fs = file_system::identify_mounted (&adjusted_path);
175
176 if (fs == nullptr)
177 {
178 errno = ENOENT;
179 return -1;
180 }
181
182 return fs->chmod (adjusted_path, mode);
183 }
184
185 int
186 stat (const char* path, struct stat* buf)
187 {
188#if defined(OS_TRACE_POSIX_IO_FILE_SYSTEM)
189 trace::printf ("%s(\"%s\", %p)\n", __func__, path, buf);
190#endif
191
192 if ((path == nullptr) || (buf == nullptr))
193 {
194 errno = EFAULT;
195 return -1;
196 }
197
198 if (*path == '\0')
199 {
200 errno = ENOENT;
201 return -1;
202 }
203
204 const char* adjusted_path = path;
205 auto* const fs = file_system::identify_mounted (&adjusted_path);
206
207 if (fs == nullptr)
208 {
209 errno = ENOENT;
210 return -1;
211 }
212
213 return fs->stat (adjusted_path, buf);
214 }
215
216 int
217 truncate (const char* path, off_t length)
218 {
219#if defined(OS_TRACE_POSIX_IO_FILE_SYSTEM)
220 trace::printf ("%s(\"%s\", %u)\n", __func__, path, length);
221#endif
222
223 if (path == nullptr)
224 {
225 errno = EFAULT;
226 return -1;
227 }
228
229 if (*path == '\0')
230 {
231 errno = ENOENT;
232 return -1;
233 }
234
235 const char* adjusted_path = path;
236 auto* const fs = file_system::identify_mounted (&adjusted_path);
237
238 if (fs == nullptr)
239 {
240 errno = ENOENT;
241 return -1;
242 }
243
244 if (length < 0)
245 {
246 errno = EINVAL;
247 return -1;
248 }
249
250 return fs->truncate (adjusted_path, length);
251 }
252
253 int
254 rename (const char* existing, const char* _new)
255 {
256#if defined(OS_TRACE_POSIX_IO_FILE_SYSTEM)
257 trace::printf ("%s(\"%s\",\"%s\")\n", __func__, existing, _new);
258#endif
259
260 if ((existing == nullptr) || (_new == nullptr))
261 {
262 errno = EFAULT;
263 return -1;
264 }
265
266 if ((*existing == '\0') || (*_new == '\0'))
267 {
268 errno = ENOENT;
269 return -1;
270 }
271
272 auto adjusted_existing = existing;
273 auto adjusted_new = _new;
274 auto* const fs
275 = file_system::identify_mounted (&adjusted_existing, &adjusted_new);
276
277 if (fs == nullptr)
278 {
279 errno = ENOENT;
280 return -1;
281 }
282
283 return fs->rename (adjusted_existing, adjusted_new);
284 }
285
286 int
287 unlink (const char* path)
288 {
289#if defined(OS_TRACE_POSIX_IO_FILE_SYSTEM)
290 trace::printf ("%s(\"%s\")\n", __func__, path);
291#endif
292
293 if (path == nullptr)
294 {
295 errno = EFAULT;
296 return -1;
297 }
298
299 if (*path == '\0')
300 {
301 errno = ENOENT;
302 return -1;
303 }
304
305 auto adjusted_path = path;
306 auto* const fs = file_system::identify_mounted (&adjusted_path);
307
308 if (fs == nullptr)
309 {
310 errno = ENOENT;
311 return -1;
312 }
313
314 return fs->unlink (adjusted_path);
315 }
316
317 int
318 utime (const char* path, const /* struct */ utimbuf* times)
319 {
320#if defined(OS_TRACE_POSIX_IO_FILE_SYSTEM)
321 trace::printf ("%s(\"%s\", %p)\n", __func__, path, times);
322#endif
323
324 if ((path == nullptr) || (times == nullptr))
325 {
326 errno = EFAULT;
327 return -1;
328 }
329
330 if (*path == '\0')
331 {
332 errno = ENOENT;
333 return -1;
334 }
335
336 auto adjusted_path = path;
337 auto* const fs = file_system::identify_mounted (&adjusted_path);
338
339 if (fs == nullptr)
340 {
341 errno = ENOENT;
342 return -1;
343 }
344
345 return fs->utime (adjusted_path, times);
346 }
347
348 int
349 statvfs (const char* path, struct statvfs* buf)
350 {
351#if defined(OS_TRACE_POSIX_IO_FILE_SYSTEM)
352 trace::printf ("%s(\"%s\", %p)\n", __func__, path, buf);
353#endif
354
355 if ((path == nullptr) || (buf == nullptr))
356 {
357 errno = EFAULT;
358 return -1;
359 }
360
361 if (*path == '\0')
362 {
363 errno = ENOENT;
364 return -1;
365 }
366
367 auto adjusted_path = path;
368 auto* const fs = file_system::identify_mounted (&adjusted_path);
369
370 if (fs == nullptr)
371 {
372 errno = ENOENT;
373 return -1;
374 }
375
376 return fs->statvfs (buf);
377 }
378
379 directory*
380 opendir (const char* dirpath)
381 {
382#if defined(OS_TRACE_POSIX_IO_FILE_SYSTEM)
383 trace::printf ("%s(\"%s\")\n", __func__, dirpath);
384#endif
385
386 if (dirpath == nullptr)
387 {
388 errno = EFAULT;
389 return nullptr;
390 }
391
392 if (*dirpath == '\0')
393 {
394 errno = ENOENT;
395 return nullptr;
396 }
397
398 errno = 0;
399
401
402 while (true)
403 {
404 // Check if path is a device.
407 if (io != nullptr)
408 {
409 // Cannot list devices (for now).
410 return nullptr;
411 }
412
413 // Check if a regular folder.
414 auto adjusted_path = dirpath;
415 auto* const fs
417
418 // The manager will return null if there are no file systems
419 // registered, no need to check this condition separately.
420 if (fs == nullptr)
421 {
422 errno = EBADF;
423 return nullptr;
424 }
425
426 // Use the file system implementation to open the directory, using
427 // the adjusted path (mount point prefix removed).
428 dir = fs->opendir (adjusted_path);
429 if (dir == nullptr)
430 {
431 // Open failed.
432 return nullptr;
433 }
434
435 break;
436 }
437
438 // Return a valid pointer to an object derived from directory, or
439 // 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
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#pragma GCC diagnostic push
640#if defined(__clang__)
641#pragma clang diagnostic ignored "-Wunsafe-buffer-usage"
642#endif
643 // If so, adjust paths to skip over prefix, but keep '/'.
644 *path1 = (*path1 + len - 1);
645 while ((*path1)[1] == '/')
646 {
647 *path1 = (*path1 + 1);
648 }
649
650 if ((path2 != nullptr) && (*path2 != nullptr))
651 {
652 *path2 = (*path2 + len - 1);
653 while ((*path2)[1] == '/')
654 {
655 *path2 = (*path2 + 1);
656 }
657 }
658#pragma GCC diagnostic pop
659
660 return &fs;
661 }
662 }
663
664 // If root file system defined, return it.
665 if (mounted_root__ != nullptr)
666 {
667 return mounted_root__;
668 }
669
670 // Not found.
671 return nullptr;
672 }
673
674 // ------------------------------------------------------------------------
675
676 file*
677 file_system::open (const char* path, int oflag, ...)
678 {
679 // Forward to the variadic version of the function.
680 std::va_list args;
681 va_start (args, oflag);
682 file* ret = vopen (path, oflag, args);
683 va_end (args);
684
685 return ret;
686 }
687
688 file*
689 file_system::vopen (const char* path, int oflag, std::va_list args)
690 {
691#if defined(OS_TRACE_POSIX_IO_FILE_SYSTEM)
692 trace::printf ("file_system::%s(\"%s\", %u)\n", __func__, path, oflag);
693#endif
694
695 if (!device ().is_opened ())
696 {
697 errno = EBADF; // Not opened.
698 return nullptr;
699 }
700
701 errno = 0;
702
703 // Execute the file specific implementation code.
704 // Allocation is done by the implementation, where
705 // the size is known.
706 file* fil = impl ().do_vopen (*this, path, oflag, args);
707 if (fil == nullptr)
708 {
709 return nullptr;
710 }
711
712 // If successful, allocate a file descriptor.
713 fil->alloc_file_descriptor ();
714
715 return fil;
716 }
717
718 directory*
719 file_system::opendir (const char* dirpath)
720 {
721#if defined(OS_TRACE_POSIX_IO_FILE_SYSTEM)
722 trace::printf ("file_system::%s(\"%s\")\n", __func__, dirpath);
723#endif
724
725 if (!device ().is_opened ())
726 {
727 errno = EBADF; // Not opened.
728 return nullptr;
729 }
730
731 errno = 0;
732
733 // Execute the dir specific implementation code.
734 // Allocation is done by the implementation, where
735 // the size is known.
736 directory* dir = impl ().do_opendir (*this, dirpath);
737 if (dir == nullptr)
738 {
739 return nullptr;
740 }
741
742 return dir;
743 }
744
745 // ------------------------------------------------------------------------
746
747 int
748 file_system::mkdir (const char* path, mode_t mode)
749 {
750#if defined(OS_TRACE_POSIX_IO_FILE_SYSTEM)
751 trace::printf ("file_system::%s(\"%s\", %u)\n", __func__, path, mode);
752#endif
753
754 if (path == nullptr)
755 {
756 errno = EFAULT;
757 return -1;
758 }
759
760 if (*path == '\0')
761 {
762 errno = ENOENT;
763 return -1;
764 }
765
766 if (!device ().is_opened ())
767 {
768 errno = EBADF; // Not opened.
769 return -1;
770 }
771
772 errno = 0;
773
774 return impl ().do_mkdir (path, mode);
775 }
776
777 int
778 file_system::rmdir (const char* path)
779 {
780#if defined(OS_TRACE_POSIX_IO_FILE_SYSTEM)
781 trace::printf ("file_system::%s(\"%s\")\n", __func__, path);
782#endif
783
784 if (path == nullptr)
785 {
786 errno = EFAULT;
787 return -1;
788 }
789
790 if (*path == '\0')
791 {
792 errno = ENOENT;
793 return -1;
794 }
795
796 if (!device ().is_opened ())
797 {
798 errno = EBADF; // Not opened.
799 return -1;
800 }
801
802 errno = 0;
803
804 return impl ().do_rmdir (path);
805 }
806
807 void
809 {
810#if defined(OS_TRACE_POSIX_IO_FILE_SYSTEM)
811 trace::printf ("file_system::%s() @%p\n", __func__, this);
812#endif
813
814 if (!device ().is_opened ())
815 {
816 errno = EBADF; // Not opened.
817 return;
818 }
819
820 errno = 0;
821
822 impl ().do_sync ();
823 }
824
825 // ------------------------------------------------------------------------
826
827 int
828 file_system::chmod (const char* path, mode_t mode)
829 {
830#if defined(OS_TRACE_POSIX_IO_FILE_SYSTEM)
831 trace::printf ("file_system::%s(\"%s\", %u)\n", __func__, path, mode);
832#endif
833
834 if (path == nullptr)
835 {
836 errno = EFAULT;
837 return -1;
838 }
839
840 if (*path == '\0')
841 {
842 errno = ENOENT;
843 return -1;
844 }
845
846 if (!device ().is_opened ())
847 {
848 errno = EBADF; // Not opened.
849 return -1;
850 }
851
852 errno = 0;
853
854 // Execute the implementation specific code.
855 return impl ().do_chmod (path, mode);
856 }
857
858 int
859 file_system::stat (const char* path, struct stat* buf)
860 {
861#if defined(OS_TRACE_POSIX_IO_FILE_SYSTEM)
862 trace::printf ("file_system::%s(\"%s\", %p)\n", __func__, path, buf);
863#endif
864
865 if ((path == nullptr) || (buf == nullptr))
866 {
867 errno = EFAULT;
868 return -1;
869 }
870
871 if (*path == '\0')
872 {
873 errno = ENOENT;
874 return -1;
875 }
876
877 if (!device ().is_opened ())
878 {
879 errno = EBADF; // Not opened.
880 return -1;
881 }
882
883 errno = 0;
884
885 // Execute the implementation specific code.
886 return impl ().do_stat (path, buf);
887 }
888
889 int
890 file_system::truncate (const char* path, off_t length)
891 {
892#if defined(OS_TRACE_POSIX_IO_FILE_SYSTEM)
893 trace::printf ("file_system::%s(\"%s\", %u)\n", __func__, path, length);
894#endif
895
896 if (path == nullptr)
897 {
898 errno = EFAULT;
899 return -1;
900 }
901
902 if (*path == '\0')
903 {
904 errno = ENOENT;
905 return -1;
906 }
907
908 if (!device ().is_opened ())
909 {
910 errno = EBADF; // Not opened.
911 return -1;
912 }
913
914 errno = 0;
915
916 // Execute the implementation specific code.
917 return impl ().do_truncate (path, length);
918 }
919
920 int
921 file_system::rename (const char* existing, const char* _new)
922 {
923#if defined(OS_TRACE_POSIX_IO_FILE_SYSTEM)
924 trace::printf ("file_system::%s(\"%s\",\"%s\")\n", __func__, existing,
925 _new);
926#endif
927
928 if ((existing == nullptr) || (_new == nullptr))
929 {
930 errno = EFAULT;
931 return -1;
932 }
933
934 if ((*existing == '\0') || (*_new == '\0'))
935 {
936 errno = ENOENT;
937 return -1;
938 }
939
940 if (!device ().is_opened ())
941 {
942 errno = EBADF; // Not opened.
943 return -1;
944 }
945
946 errno = 0;
947
948 // Execute the implementation specific code.
949 return impl ().do_rename (existing, _new);
950 }
951
952 int
953 file_system::unlink (const char* path)
954 {
955#if defined(OS_TRACE_POSIX_IO_FILE_SYSTEM)
956 trace::printf ("file_system::%s(\"%s\")\n", __func__, path);
957#endif
958
959 if (path == nullptr)
960 {
961 errno = EFAULT;
962 return -1;
963 }
964
965 if (*path == '\0')
966 {
967 errno = ENOENT;
968 return -1;
969 }
970
971 if (!device ().is_opened ())
972 {
973 errno = EBADF; // Not opened.
974 return -1;
975 }
976
977 errno = 0;
978
979 // Execute the implementation specific code.
980 return impl ().do_unlink (path);
981 }
982
983 // http://pubs.opengroup.org/onlinepubs/9699919799/functions/utime.html
984 int
985 file_system::utime (const char* path, const /* struct */ utimbuf* times)
986 {
987#if defined(OS_TRACE_POSIX_IO_FILE_SYSTEM)
988 trace::printf ("file_system::%s(\"%s\", %p)\n", __func__, path, times);
989#endif
990
991 if ((path == nullptr) || (times == nullptr))
992 {
993 errno = EFAULT;
994 return -1;
995 }
996
997 if (*path == '\0')
998 {
999 errno = ENOENT;
1000 return -1;
1001 }
1002
1003 if (!device ().is_opened ())
1004 {
1005 errno = EBADF; // Not opened.
1006 return -1;
1007 }
1008
1009 errno = 0;
1010
1011 /* struct */ utimbuf tmp;
1012 if (times == nullptr)
1013 {
1014 // If times is a null pointer, the access and modification times
1015 // of the file shall be set to the current time.
1016 tmp.actime = time (nullptr);
1017 tmp.modtime = tmp.actime;
1018 return impl ().do_utime (path, &tmp);
1019 }
1020 else
1021 {
1022 // Execute the implementation specific code.
1023 return impl ().do_utime (path, times);
1024 }
1025 }
1026
1027 // http://pubs.opengroup.org/onlinepubs/9699919799/functions/fstatvfs.html
1028 int
1030 {
1031#if defined(OS_TRACE_POSIX_IO_FILE_SYSTEM)
1032 trace::printf ("file_system::%s(%p)\n", __func__, buf);
1033#endif
1034
1035 if (!device ().is_opened ())
1036 {
1037 errno = EBADF; // Not opened.
1038 return -1;
1039 }
1040
1041 return impl ().do_statvfs (buf);
1042 }
1043 // TODO: check if the file system should keep a static current path for
1044 // relative paths.
1045
1046 // http://pubs.opengroup.org/onlinepubs/9699919799/functions/chdir.html
1047 // ------------------------------------------------------------------------
1048
1049 // ========================================================================
1050
1052 : device_ (device)
1053 {
1054#if defined(OS_TRACE_POSIX_IO_FILE_SYSTEM)
1055 trace::printf ("file_system_impl::%s()=%p\n", __func__, this);
1056#endif
1057 }
1058
1060 {
1061#if defined(OS_TRACE_POSIX_IO_FILE_SYSTEM)
1062 trace::printf ("file_system_impl::%s() @%p\n", __func__, this);
1063#endif
1064 }
1065
1066 // ========================================================================
1067 } /* namespace posix */
1068} /* namespace os */
1069
1070// ----------------------------------------------------------------------------
Block device class.
static value_type * identify_device(const char *path)
Base device class.
Definition device.h:67
Directory class.
Definition directory.h:75
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:64
Base I/O class.
Definition io.h:86
io * alloc_file_descriptor(void)
Definition io.cpp:189
int printf(const char *format,...)
Write a formatted string to the trace device.
Definition trace.cpp:59
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.