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