µ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.h
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#ifndef CMSIS_PLUS_POSIX_IO_FILE_H_
14#define CMSIS_PLUS_POSIX_IO_FILE_H_
15
16// ----------------------------------------------------------------------------
17
18#if defined(__cplusplus)
19
20// ----------------------------------------------------------------------------
21
22#if defined(OS_USE_OS_APP_CONFIG_H)
23#include <cmsis-plus/os-app-config.h>
24#endif
25
30
31#include <mutex>
32
33// ----------------------------------------------------------------------------
34
35#pragma GCC diagnostic push
36#if defined(__clang__)
37#pragma clang diagnostic ignored "-Wc++98-compat"
38#endif
39
40// ----------------------------------------------------------------------------
41
42namespace os
43{
44 namespace posix
45 {
46 // ------------------------------------------------------------------------
47
48 class file_system;
49 class file_impl;
50
51 // ========================================================================
52
58#pragma GCC diagnostic push
59#if defined(__clang__)
60#elif defined(__GNUC__)
61#pragma GCC diagnostic ignored "-Wsuggest-final-methods"
62#pragma GCC diagnostic ignored "-Wsuggest-final-types"
63#endif
64 class file : public io
65 {
66 // ----------------------------------------------------------------------
67
72 friend class file_system;
73 friend class io;
74
79 // ----------------------------------------------------------------------
85 public:
86
88
93 // The rule of five.
94 file (const file&) = delete;
95 file (file&&) = delete;
96 file&
97 operator= (const file&) = delete;
98 file&
99 operator= (file&&) = delete;
100
105 virtual
106 ~file () override;
107
112 // ----------------------------------------------------------------------
118 public:
119
120 virtual int
121 close (void) override;
122
123 virtual int
124 ftruncate (off_t length);
125
126 virtual int
127 fsync (void);
128
129 virtual int
130 fstatvfs (struct statvfs *buf);
131
132 // ----------------------------------------------------------------------
133 // Support functions.
134
135#pragma GCC diagnostic push
136#if defined(__clang__)
137#elif defined(__GNUC__)
138#pragma GCC diagnostic ignored "-Wredundant-tags"
139#endif
140
141 class file_system&
142 get_file_system (void);
143
144#pragma GCC diagnostic pop
145
146 file_impl&
147 impl (void) const;
148
153 // ----------------------------------------------------------------------
154 public:
155
160 // Intrusive node used to link this file to the deferred
161 // deallocation list. Must be public.
162 utils::double_list_links deferred_links_;
163
167 };
168#pragma GCC diagnostic pop
169
170 // ========================================================================
171
172 class file_impl : public io_impl
173 {
174 // ----------------------------------------------------------------------
175
180 friend class file;
181
186 // ----------------------------------------------------------------------
192 public:
193
194 file_impl (/* class */ file_system& fs);
195
200 // The rule of five.
201 file_impl (const file_impl&) = delete;
202 file_impl (file_impl&&) = delete;
203 file_impl&
204 operator= (const file_impl&) = delete;
205 file_impl&
206 operator= (file_impl&&) = delete;
207
212 virtual
213 ~file_impl () override;
214
219 // ----------------------------------------------------------------------
225 public:
226
227 // Implementations
228
229 virtual int
230 do_ftruncate (off_t length) = 0;
231
232 virtual int
233 do_fsync (void) = 0;
234
235 // ----------------------------------------------------------------------
236 // Support functions.
237
238#pragma GCC diagnostic push
239#if defined(__clang__)
240#elif defined(__GNUC__)
241#pragma GCC diagnostic ignored "-Wredundant-tags"
242#endif
243
244 class file_system&
245 get_file_system (void);
246
247#pragma GCC diagnostic pop
248
253 // ----------------------------------------------------------------------
254 protected:
255
260 /* class */ file_system& file_system_;
261
265 };
266
267 // ========================================================================
268
269#pragma GCC diagnostic push
270#if defined(__clang__)
271#elif defined(__GNUC__)
272#pragma GCC diagnostic ignored "-Wsuggest-final-methods"
273#pragma GCC diagnostic ignored "-Wsuggest-final-types"
274#endif
275 template<typename T>
277 {
278 // --------------------------------------------------------------------
279
280 public:
281
282 using value_type = T;
283
284 // --------------------------------------------------------------------
285
291 public:
292
293 file_implementable (/* class */ file_system& fs);
294
299 // The rule of five.
300 file_implementable (const file_implementable&) = delete;
303 operator= (const file_implementable&) = delete;
305 operator= (file_implementable&&) = delete;
306
311 virtual
312 ~file_implementable () override;
313
318 // --------------------------------------------------------------------
324 public:
325
326 // Support functions.
327
329 impl (void) const;
330
335 // --------------------------------------------------------------------
336 protected:
337
342 value_type impl_instance_;
343
347 };
348#pragma GCC diagnostic pop
349
350 // ========================================================================
351
352#pragma GCC diagnostic push
353#if defined(__clang__)
354#elif defined(__GNUC__)
355#pragma GCC diagnostic ignored "-Wsuggest-final-methods"
356#pragma GCC diagnostic ignored "-Wsuggest-final-types"
357#pragma GCC diagnostic ignored "-Wpadded"
358#endif
359 template<typename T, typename L>
360 class file_lockable : public file
361 {
362 // --------------------------------------------------------------------
363
364 public:
365
366 using value_type = T;
367 using lockable_type = L;
368
369 // --------------------------------------------------------------------
370
376 public:
377
378 file_lockable (/* class */ file_system& fs, lockable_type& locker);
379
384 // The rule of five.
385 file_lockable (const file_lockable&) = delete;
386 file_lockable (file_lockable&&) = delete;
388 operator= (const file_lockable&) = delete;
390 operator= (file_lockable&&) = delete;
391
396 virtual
397 ~file_lockable () override;
398
403 // --------------------------------------------------------------------
409 public:
410
411 virtual int
412 close (void) override;
413
414 virtual ssize_t
415 read (void* buf, std::size_t nbyte) override;
416
417 virtual ssize_t
418 write (const void* buf, std::size_t nbyte) override;
419
420 virtual ssize_t
421 writev (const /* struct */ iovec* iov, int iovcnt) override;
422
423 virtual int
424 vfcntl (int cmd, std::va_list args) override;
425
426#pragma GCC diagnostic push
427#if defined(__clang__)
428#elif defined(__GNUC__)
429#pragma GCC diagnostic ignored "-Wredundant-tags"
430#endif
431 virtual int
432 fstat (struct stat* buf) override;
433#pragma GCC diagnostic pop
434
435 virtual off_t
436 lseek (off_t offset, int whence) override;
437
438 virtual int
439 ftruncate (off_t length) override;
440
441 virtual int
442 fsync (void) override;
443
444 // fstatvfs() - must not be locked, since will be locked by the
445 // file system. (otherwise non-recursive mutexes will fail).
446
447 // --------------------------------------------------------------------
448 // Support functions.
449
451 impl (void) const;
452
457 // --------------------------------------------------------------------
458 protected:
459
464 value_type impl_instance_;
465
466 lockable_type& locker_;
467
471 };
472#pragma GCC diagnostic pop
473
474 // ==========================================================================
475 } /* namespace posix */
476} /* namespace os */
477
478// ===== Inline & template implementations ====================================
479
480namespace os
481{
482 namespace posix
483 {
484 // ========================================================================
485
486 inline file_system&
488 {
489 return impl ().get_file_system ();
490 }
491
492 inline file_impl&
493 file::impl (void) const
494 {
495 return static_cast<file_impl&> (impl_);
496 }
497
498 // ========================================================================
499
500 inline /* class */ file_system&
502 {
503 return file_system_;
504 }
505
506 // ========================================================================
507
508 template<typename T>
510 file
511 { impl_instance_ }, //
512 impl_instance_
513 { fs }
514 {
515#if defined(OS_TRACE_POSIX_IO_FILE)
516 trace::printf ("file_implementable::%s()=@%p\n", __func__, this);
517#endif
518 }
519
520#pragma GCC diagnostic push
521#if defined(__clang__)
522#elif defined(__GNUC__)
523#pragma GCC diagnostic ignored "-Wsuggest-final-methods"
524#endif
525 template<typename T>
527 {
528#if defined(OS_TRACE_POSIX_IO_FILE)
529 trace::printf ("file_implementable::%s() @%p\n", __func__, this);
530#endif
531 }
532#pragma GCC diagnostic pop
533
534 template<typename T>
537 {
538 return static_cast<value_type&> (impl_);
539 }
540
541 // ========================================================================
542
543 template<typename T, typename L>
545 lockable_type& locker) :
546 file
547 { impl_instance_ }, //
548 impl_instance_
549 { fs }, //
550 locker_ (locker)
551 {
552#if defined(OS_TRACE_POSIX_IO_FILE)
553 trace::printf ("file_lockable::%s()=@%p\n", __func__, this);
554#endif
555 }
556
557#pragma GCC diagnostic push
558#if defined(__clang__)
559#elif defined(__GNUC__)
560#pragma GCC diagnostic ignored "-Wsuggest-final-methods"
561#endif
562 template<typename T, typename L>
564 {
565#if defined(OS_TRACE_POSIX_IO_FILE)
566 trace::printf ("file_lockable::%s() @%p\n", __func__, this);
567#endif
568 }
569#pragma GCC diagnostic pop
570
571 // ------------------------------------------------------------------------
572
573 template<typename T, typename L>
574 int
576 {
577 std::lock_guard<L> lock
578 { locker_ };
579
580 return file::close ();
581 }
582
583 template<typename T, typename L>
584 ssize_t
585 file_lockable<T, L>::read (void* buf, std::size_t nbyte)
586 {
587 std::lock_guard<L> lock
588 { locker_ };
589
590 return file::read (buf, nbyte);
591 }
592
593 template<typename T, typename L>
594 ssize_t
595 file_lockable<T, L>::write (const void* buf, std::size_t nbyte)
596 {
597 std::lock_guard<L> lock
598 { locker_ };
599
600 return file::write (buf, nbyte);
601 }
602
603 template<typename T, typename L>
604 ssize_t
605 file_lockable<T, L>::writev (const /* struct */ iovec* iov, int iovcnt)
606 {
607 std::lock_guard<L> lock
608 { locker_ };
609
610 return file::writev (iov, iovcnt);
611 }
612
613 template<typename T, typename L>
614 int
615 file_lockable<T, L>::vfcntl (int cmd, std::va_list args)
616 {
617 std::lock_guard<L> lock
618 { locker_ };
619
620 return file::vfcntl (cmd, args);
621 }
622
623#pragma GCC diagnostic push
624#if defined(__clang__)
625#elif defined(__GNUC__)
626#pragma GCC diagnostic ignored "-Wredundant-tags"
627#endif
628 template<typename T, typename L>
629 int
631 {
632 std::lock_guard<L> lock
633 { locker_ };
634
635 return file::fstat (buf);
636 }
637#pragma GCC diagnostic pop
638
639 template<typename T, typename L>
640 off_t
641 file_lockable<T, L>::lseek (off_t offset, int whence)
642 {
643 std::lock_guard<L> lock
644 { locker_ };
645
646 return file::lseek (offset, whence);
647 }
648
649 template<typename T, typename L>
650 int
652 {
653 std::lock_guard<L> lock
654 { locker_ };
655
656 return file::ftruncate (length);
657 }
658
659 template<typename T, typename L>
660 int
662 {
663 std::lock_guard<L> lock
664 { locker_ };
665
666 return file::fsync ();
667 }
668
669 template<typename T, typename L>
672 {
673 return static_cast<value_type&> (impl_);
674 }
675
676 // ==========================================================================
677 } /* namespace posix */
678} /* namespace os */
679
680#pragma GCC diagnostic pop
681
682// ----------------------------------------------------------------------------
683
684#endif /* __cplusplus */
685
686// ----------------------------------------------------------------------------
687
688#endif /* CMSIS_PLUS_POSIX_IO_FILE_H_ */
virtual ~file_impl() override
Definition file.cpp:129
virtual int do_ftruncate(off_t length)=0
Definition file.cpp:146
class file_system & get_file_system(void)
Definition file.h:501
virtual int do_fsync(void)=0
Definition file.cpp:155
file_implementable(file_system &fs)
Definition file.h:509
virtual ~file_implementable() override
Definition file.h:526
value_type & impl(void) const
Definition file.h:536
virtual ssize_t read(void *buf, std::size_t nbyte) override
Definition file.h:585
virtual ssize_t writev(const iovec *iov, int iovcnt) override
Definition file.h:605
file_lockable(file_system &fs, lockable_type &locker)
Definition file.h:544
virtual ~file_lockable() override
Definition file.h:563
virtual off_t lseek(off_t offset, int whence) override
Definition file.h:641
virtual int fstat(struct stat *buf) override
Definition file.h:630
value_type & impl(void) const
Definition file.h:671
virtual ssize_t write(const void *buf, std::size_t nbyte) override
Definition file.h:595
virtual int vfcntl(int cmd, std::va_list args) override
Definition file.h:615
virtual int close(void) override
Definition file.h:575
virtual int ftruncate(off_t length) override
Definition file.h:651
virtual int fsync(void) override
Definition file.h:661
File system class.
File class.
Definition file.h:65
file_impl & impl(void) const
Definition file.h:493
virtual int fstatvfs(struct statvfs *buf)
Definition file.cpp:107
virtual int ftruncate(off_t length)
Definition file.cpp:75
virtual ~file() override
Definition file.cpp:47
class file_system & get_file_system(void)
Definition file.h:487
virtual int fsync(void)
Definition file.cpp:94
virtual int close(void) override
Definition file.cpp:57
Base I/O class.
Definition io.h:87
virtual ssize_t writev(const iovec *iov, int iovcnt)
Definition io.cpp:322
virtual off_t lseek(off_t offset, int whence)
Definition io.cpp:448
virtual int fstat(struct stat *buf)
Definition io.cpp:417
virtual ssize_t write(const void *buf, std::size_t nbyte)
Definition io.cpp:269
virtual ssize_t read(void *buf, std::size_t nbyte)
Definition io.cpp:218
virtual int vfcntl(int cmd, std::va_list args)
Definition io.cpp:381
int printf(const char *format,...)
Write a formatted string to the trace device.
Definition trace.cpp:60
int stat(const char *path, struct stat *buf)
System namespace.
Definition uio.h:41