µ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++ 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#ifndef CMSIS_PLUS_POSIX_IO_FILE_H_
13#define CMSIS_PLUS_POSIX_IO_FILE_H_
14
15// ----------------------------------------------------------------------------
16
17#if defined(__cplusplus)
18
19// ----------------------------------------------------------------------------
20
21#if defined(OS_USE_OS_APP_CONFIG_H)
22#include <cmsis-plus/os-app-config.h>
23#endif
24
29
30#include <mutex>
31
32// ----------------------------------------------------------------------------
33
34#pragma GCC diagnostic push
35#if defined(__clang__)
36#pragma clang diagnostic ignored "-Wc++98-compat"
37#endif
38
39// ----------------------------------------------------------------------------
40
41namespace os
42{
43 namespace posix
44 {
45 // ------------------------------------------------------------------------
46
47 class file_system;
48 class file_impl;
49
50 // ========================================================================
51
57#pragma GCC diagnostic push
58#if defined(__clang__)
59#elif defined(__GNUC__)
60#pragma GCC diagnostic ignored "-Wsuggest-final-methods"
61#pragma GCC diagnostic ignored "-Wsuggest-final-types"
62#endif
63 class file : public io
64 {
65 // ----------------------------------------------------------------------
66
71 friend class file_system;
72 friend class io;
73
78 // ----------------------------------------------------------------------
84 public:
86
91 // The rule of five.
92 file (const file&) = delete;
93 file (file&&) = delete;
94 file&
95 operator= (const file&)
96 = delete;
97 file&
98 operator= (file&&)
99 = delete;
100
105 virtual ~file () override;
106
111 // ----------------------------------------------------------------------
117 public:
118 virtual int
119 close (void) override;
120
121 virtual int
122 ftruncate (off_t length);
123
124 virtual int
125 fsync (void);
126
127 virtual int
128 fstatvfs (struct statvfs* buf);
129
130 // ----------------------------------------------------------------------
131 // Support functions.
132
133#pragma GCC diagnostic push
134#if defined(__clang__)
135#elif defined(__GNUC__)
136#pragma GCC diagnostic ignored "-Wredundant-tags"
137#endif
138
139 class file_system&
140 get_file_system (void);
141
142#pragma GCC diagnostic pop
143
144 file_impl&
145 impl (void) const;
146
151 // ----------------------------------------------------------------------
152 public:
157 // Intrusive node used to link this file to the deferred
158 // deallocation list. Must be public.
159 utils::double_list_links deferred_links_;
160
164 };
165#pragma GCC diagnostic pop
166
167 // ========================================================================
168
169 class file_impl : public io_impl
170 {
171 // ----------------------------------------------------------------------
172
177 friend class file;
178
183 // ----------------------------------------------------------------------
189 public:
190 file_impl (/* class */ file_system& fs);
191
196 // The rule of five.
197 file_impl (const file_impl&) = delete;
198 file_impl (file_impl&&) = delete;
199 file_impl&
200 operator= (const file_impl&)
201 = delete;
202 file_impl&
203 operator= (file_impl&&)
204 = delete;
205
210 virtual ~file_impl () override;
211
216 // ----------------------------------------------------------------------
222 public:
223 // Implementations
224
225 virtual int
226 do_ftruncate (off_t length)
227 = 0;
228
229 virtual int
230 do_fsync (void)
231 = 0;
232
233 // ----------------------------------------------------------------------
234 // Support functions.
235
236#pragma GCC diagnostic push
237#if defined(__clang__)
238#elif defined(__GNUC__)
239#pragma GCC diagnostic ignored "-Wredundant-tags"
240#endif
241
242 class file_system&
243 get_file_system (void);
244
245#pragma GCC diagnostic pop
246
251 // ----------------------------------------------------------------------
252 protected:
257 /* class */ file_system& file_system_;
258
262 };
263
264 // ========================================================================
265
266#pragma GCC diagnostic push
267#if defined(__clang__)
268#elif defined(__GNUC__)
269#pragma GCC diagnostic ignored "-Wsuggest-final-methods"
270#pragma GCC diagnostic ignored "-Wsuggest-final-types"
271#endif
272 template <typename T>
274 {
275 // ----------------------------------------------------------------------
276
277 public:
278 using value_type = T;
279
280 // ----------------------------------------------------------------------
281
287 public:
288 file_implementable (/* class */ file_system& fs);
289
294 // The rule of five.
295 file_implementable (const file_implementable&) = delete;
298 operator= (const file_implementable&)
299 = delete;
301 operator= (file_implementable&&)
302 = delete;
303
308 virtual ~file_implementable () override;
309
314 // ----------------------------------------------------------------------
320 public:
321 // Support functions.
322
324 impl (void) const;
325
330 // ----------------------------------------------------------------------
331 protected:
336 value_type impl_instance_;
337
341 };
342#pragma GCC diagnostic pop
343
344 // ========================================================================
345
346#pragma GCC diagnostic push
347#if defined(__clang__)
348#elif defined(__GNUC__)
349#pragma GCC diagnostic ignored "-Wsuggest-final-methods"
350#pragma GCC diagnostic ignored "-Wsuggest-final-types"
351#pragma GCC diagnostic ignored "-Wpadded"
352#endif
353 template <typename T, typename L>
354 class file_lockable : public file
355 {
356 // ----------------------------------------------------------------------
357
358 public:
359 using value_type = T;
360 using lockable_type = L;
361
362 // ----------------------------------------------------------------------
363
369 public:
370 file_lockable (/* class */ file_system& fs, lockable_type& locker);
371
376 // The rule of five.
377 file_lockable (const file_lockable&) = delete;
378 file_lockable (file_lockable&&) = delete;
380 operator= (const file_lockable&)
381 = delete;
383 operator= (file_lockable&&)
384 = delete;
385
390 virtual ~file_lockable () override;
391
396 // ----------------------------------------------------------------------
402 public:
403 virtual int
404 close (void) override;
405
406 virtual ssize_t
407 read (void* buf, std::size_t nbyte) override;
408
409 virtual ssize_t
410 write (const void* buf, std::size_t nbyte) override;
411
412 virtual ssize_t
413 writev (const /* struct */ iovec* iov, int iovcnt) override;
414
415 virtual int
416 vfcntl (int cmd, std::va_list args) override;
417
418#pragma GCC diagnostic push
419#if defined(__clang__)
420#elif defined(__GNUC__)
421#pragma GCC diagnostic ignored "-Wredundant-tags"
422#endif
423 virtual int
424 fstat (struct stat* buf) override;
425#pragma GCC diagnostic pop
426
427 virtual off_t
428 lseek (off_t offset, int whence) override;
429
430 virtual int
431 ftruncate (off_t length) override;
432
433 virtual int
434 fsync (void) override;
435
436 // fstatvfs() - must not be locked, since will be locked by the
437 // file system. (otherwise non-recursive mutexes will fail).
438
439 // ----------------------------------------------------------------------
440 // Support functions.
441
443 impl (void) const;
444
449 // ----------------------------------------------------------------------
450 protected:
455 value_type impl_instance_;
456
457 lockable_type& locker_;
458
462 };
463#pragma GCC diagnostic pop
464
465 // ========================================================================
466 } /* namespace posix */
467} /* namespace os */
468
469// ===== Inline & template implementations ====================================
470
471namespace os
472{
473 namespace posix
474 {
475 // ========================================================================
476
477 inline file_system&
479 {
480 return impl ().get_file_system ();
481 }
482
483 inline file_impl&
484 file::impl (void) const
485 {
486 return static_cast<file_impl&> (impl_);
487 }
488
489 // ========================================================================
490
491 inline /* class */ file_system&
493 {
494 return file_system_;
495 }
496
497 // ========================================================================
498
499 template <typename T>
501 : file{ impl_instance_ }, //
502 impl_instance_{ fs }
503 {
504#if defined(OS_TRACE_POSIX_IO_FILE)
505 trace::printf ("file_implementable::%s()=@%p\n", __func__, this);
506#endif
507 }
508
509#pragma GCC diagnostic push
510#if defined(__clang__)
511#elif defined(__GNUC__)
512#pragma GCC diagnostic ignored "-Wsuggest-final-methods"
513#endif
514 template <typename T>
516 {
517#if defined(OS_TRACE_POSIX_IO_FILE)
518 trace::printf ("file_implementable::%s() @%p\n", __func__, this);
519#endif
520 }
521#pragma GCC diagnostic pop
522
523 template <typename T>
526 {
527 return static_cast<value_type&> (impl_);
528 }
529
530 // ========================================================================
531
532 template <typename T, typename L>
534 lockable_type& locker)
535 : file{ impl_instance_ }, //
536 impl_instance_{ fs }, //
537 locker_ (locker)
538 {
539#if defined(OS_TRACE_POSIX_IO_FILE)
540 trace::printf ("file_lockable::%s()=@%p\n", __func__, this);
541#endif
542 }
543
544#pragma GCC diagnostic push
545#if defined(__clang__)
546#elif defined(__GNUC__)
547#pragma GCC diagnostic ignored "-Wsuggest-final-methods"
548#endif
549 template <typename T, typename L>
551 {
552#if defined(OS_TRACE_POSIX_IO_FILE)
553 trace::printf ("file_lockable::%s() @%p\n", __func__, this);
554#endif
555 }
556#pragma GCC diagnostic pop
557
558 // ------------------------------------------------------------------------
559
560 template <typename T, typename L>
561 int
563 {
564 std::lock_guard<L> lock{ locker_ };
565
566 return file::close ();
567 }
568
569 template <typename T, typename L>
570 ssize_t
571 file_lockable<T, L>::read (void* buf, std::size_t nbyte)
572 {
573 std::lock_guard<L> lock{ locker_ };
574
575 return file::read (buf, nbyte);
576 }
577
578 template <typename T, typename L>
579 ssize_t
580 file_lockable<T, L>::write (const void* buf, std::size_t nbyte)
581 {
582 std::lock_guard<L> lock{ locker_ };
583
584 return file::write (buf, nbyte);
585 }
586
587 template <typename T, typename L>
588 ssize_t
589 file_lockable<T, L>::writev (const /* struct */ iovec* iov, int iovcnt)
590 {
591 std::lock_guard<L> lock{ locker_ };
592
593 return file::writev (iov, iovcnt);
594 }
595
596 template <typename T, typename L>
597 int
598 file_lockable<T, L>::vfcntl (int cmd, std::va_list args)
599 {
600 std::lock_guard<L> lock{ locker_ };
601
602 return file::vfcntl (cmd, args);
603 }
604
605#pragma GCC diagnostic push
606#if defined(__clang__)
607#elif defined(__GNUC__)
608#pragma GCC diagnostic ignored "-Wredundant-tags"
609#endif
610 template <typename T, typename L>
611 int
613 {
614 std::lock_guard<L> lock{ locker_ };
615
616 return file::fstat (buf);
617 }
618#pragma GCC diagnostic pop
619
620 template <typename T, typename L>
621 off_t
622 file_lockable<T, L>::lseek (off_t offset, int whence)
623 {
624 std::lock_guard<L> lock{ locker_ };
625
626 return file::lseek (offset, whence);
627 }
628
629 template <typename T, typename L>
630 int
632 {
633 std::lock_guard<L> lock{ locker_ };
634
635 return file::ftruncate (length);
636 }
637
638 template <typename T, typename L>
639 int
641 {
642 std::lock_guard<L> lock{ locker_ };
643
644 return file::fsync ();
645 }
646
647 template <typename T, typename L>
650 {
651 return static_cast<value_type&> (impl_);
652 }
653
654 // ========================================================================
655 } /* namespace posix */
656} /* namespace os */
657
658#pragma GCC diagnostic pop
659
660// ----------------------------------------------------------------------------
661
662#endif /* __cplusplus */
663
664// ----------------------------------------------------------------------------
665
666#endif /* CMSIS_PLUS_POSIX_IO_FILE_H_ */
virtual ~file_impl() override
Definition file.cpp:125
virtual int do_ftruncate(off_t length)=0
Definition file.cpp:142
class file_system & get_file_system(void)
Definition file.h:492
virtual int do_fsync(void)=0
Definition file.cpp:151
file_implementable(file_system &fs)
Definition file.h:500
virtual ~file_implementable() override
Definition file.h:515
value_type & impl(void) const
Definition file.h:525
virtual ssize_t read(void *buf, std::size_t nbyte) override
Definition file.h:571
virtual ssize_t writev(const iovec *iov, int iovcnt) override
Definition file.h:589
file_lockable(file_system &fs, lockable_type &locker)
Definition file.h:533
virtual ~file_lockable() override
Definition file.h:550
virtual off_t lseek(off_t offset, int whence) override
Definition file.h:622
virtual int fstat(struct stat *buf) override
Definition file.h:612
value_type & impl(void) const
Definition file.h:649
virtual ssize_t write(const void *buf, std::size_t nbyte) override
Definition file.h:580
virtual int vfcntl(int cmd, std::va_list args) override
Definition file.h:598
virtual int close(void) override
Definition file.h:562
virtual int ftruncate(off_t length) override
Definition file.h:631
virtual int fsync(void) override
Definition file.h:640
File system class.
File class.
Definition file.h:64
file_impl & impl(void) const
Definition file.h:484
virtual int fstatvfs(struct statvfs *buf)
Definition file.cpp:104
virtual int ftruncate(off_t length)
Definition file.cpp:72
virtual ~file() override
Definition file.cpp:44
class file_system & get_file_system(void)
Definition file.h:478
virtual int fsync(void)
Definition file.cpp:91
virtual int close(void) override
Definition file.cpp:54
Base I/O class.
Definition io.h:86
virtual ssize_t writev(const iovec *iov, int iovcnt)
Definition io.cpp:321
virtual off_t lseek(off_t offset, int whence)
Definition io.cpp:447
virtual int fstat(struct stat *buf)
Definition io.cpp:416
virtual ssize_t write(const void *buf, std::size_t nbyte)
Definition io.cpp:268
virtual ssize_t read(void *buf, std::size_t nbyte)
Definition io.cpp:217
virtual int vfcntl(int cmd, std::va_list args)
Definition io.cpp:380
int printf(const char *format,...)
Write a formatted string to the trace device.
Definition trace.cpp:59
int stat(const char *path, struct stat *buf)
System namespace.
Definition uio.h:40