µOS++ IIIe Reference 7.0.0
The third edition of µOS++, a POSIX inspired open source framework, written in C++
Loading...
Searching...
No Matches
directory.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_DIRECTORY_H_
13#define CMSIS_PLUS_POSIX_IO_DIRECTORY_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
27
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#pragma clang diagnostic ignored "-Wdocumentation-unknown-command"
38#endif
39
40// ----------------------------------------------------------------------------
41
42namespace os
43{
44 namespace posix
45 {
46 // ------------------------------------------------------------------------
47
48 class directory;
49 class directory_impl;
50 class file_system;
51
52 // ------------------------------------------------------------------------
53
54 // ========================================================================
55
56#pragma GCC diagnostic push
57#if defined(__clang__)
58#pragma clang diagnostic ignored "-Wpadded"
59#elif defined(__GNUC__)
60#pragma GCC diagnostic ignored "-Wpadded"
61#endif
62
68#pragma GCC diagnostic push
69#if defined(__clang__)
70#elif defined(__GNUC__)
71#pragma GCC diagnostic ignored "-Wsuggest-final-methods"
72#pragma GCC diagnostic ignored "-Wsuggest-final-types"
73#endif
75 {
76 // ----------------------------------------------------------------------
77
82 friend class file_system;
83
88 // ----------------------------------------------------------------------
94 public:
96
101 // The rule of five.
102 directory (const directory&) = delete;
103 directory (directory&&) = delete;
104 directory&
105 operator= (const directory&)
106 = delete;
107 directory&
108 operator= (directory&&)
109 = delete;
110
115 virtual ~directory ();
116
121 // ----------------------------------------------------------------------
127 public:
128 // http://pubs.opengroup.org/onlinepubs/9699919799/functions/readdir.html
129 virtual /* struct */ dirent*
130 read (void);
131
132 // http://pubs.opengroup.org/onlinepubs/9699919799/functions/rewinddir.html
133 virtual void
134 rewind (void);
135
136 // http://pubs.opengroup.org/onlinepubs/9699919799/functions/closedir.html
137 virtual int
138 close (void);
139
140 // ----------------------------------------------------------------------
141 // Support functions.
142
143 /* struct */ dirent*
144 dir_entry (void);
145
146#pragma GCC diagnostic push
147#if defined(__clang__)
148#elif defined(__GNUC__)
149#pragma GCC diagnostic ignored "-Wredundant-tags"
150#endif
151
152 class file_system&
153 get_file_system (void) const;
154
155#pragma GCC diagnostic pop
156
158 impl (void) const;
159
164 // ----------------------------------------------------------------------
165 public:
170 // Intrusive node used to link this device to the deferred
171 // deallocation list. Must be public.
172 utils::double_list_links deferred_links_;
173
178 // ----------------------------------------------------------------------
179 protected:
184 directory_impl& impl_;
185
189 };
190#pragma GCC diagnostic pop
191
192 // ========================================================================
193
195 {
196 // ----------------------------------------------------------------------
197
202 friend class directory;
203
208 // ----------------------------------------------------------------------
214 public:
215 directory_impl (/* class */ file_system& fs);
216
221 // The rule of five.
222 directory_impl (const directory_impl&) = delete;
223 directory_impl (directory_impl&&) = delete;
225 operator= (const directory_impl&)
226 = delete;
228 operator= (directory_impl&&)
229 = delete;
230
235 virtual ~directory_impl ();
236
241 // ----------------------------------------------------------------------
247 public:
248 // Implementations
249
253 virtual /* struct */ dirent*
254 do_read (void)
255 = 0;
256
257 virtual void
259 = 0;
260
261 virtual int
262 do_close (void)
263 = 0;
264
265 // ----------------------------------------------------------------------
266 // Support functions.
267
268#pragma GCC diagnostic push
269#if defined(__clang__)
270#elif defined(__GNUC__)
271#pragma GCC diagnostic ignored "-Wredundant-tags"
272#endif
273
274 class file_system&
275 get_file_system (void) const;
276
277#pragma GCC diagnostic pop
278
283 // ----------------------------------------------------------------------
284 protected:
289 // This also solves the readdir() re-entrancy issue.
290 /* struct */ dirent dir_entry_;
291
292 /* class */ file_system& file_system_;
293
297 };
298
299 // ========================================================================
300
301#pragma GCC diagnostic push
302#if defined(__clang__)
303#elif defined(__GNUC__)
304#pragma GCC diagnostic ignored "-Wsuggest-final-methods"
305#pragma GCC diagnostic ignored "-Wsuggest-final-types"
306#endif
307 template <typename T>
309 {
310 // ----------------------------------------------------------------------
311
312 public:
313 using value_type = T;
314
315 // ----------------------------------------------------------------------
321 public:
322 directory_implementable (/* class */ file_system& fs);
323
328 // The rule of five.
332 operator= (const directory_implementable&)
333 = delete;
335 operator= (directory_implementable&&)
336 = delete;
337
342 virtual ~directory_implementable () override;
343
348 // ----------------------------------------------------------------------
354 public:
355 // Support functions.
356
358 impl (void) const;
359
364 // ----------------------------------------------------------------------
365 protected:
370 value_type impl_instance_;
371
375 };
376#pragma GCC diagnostic pop
377
378 // ========================================================================
379
380#pragma GCC diagnostic push
381#if defined(__clang__)
382#elif defined(__GNUC__)
383#pragma GCC diagnostic ignored "-Wsuggest-final-methods"
384#pragma GCC diagnostic ignored "-Wsuggest-final-types"
385#endif
386 template <typename T, typename L>
388 {
389 // ----------------------------------------------------------------------
390
391 public:
392 using value_type = T;
393 using lockable_type = L;
394
395 // ----------------------------------------------------------------------
396
402 public:
403 directory_lockable (/* class */ file_system& fs, lockable_type& locker);
404
409 // The rule of five.
410 directory_lockable (const directory_lockable&) = delete;
413 operator= (const directory_lockable&)
414 = delete;
416 operator= (directory_lockable&&)
417 = delete;
418
423 virtual ~directory_lockable () override;
424
429 // ----------------------------------------------------------------------
435 public:
436 // opendir() uses the file system lock.
437
438 // http://pubs.opengroup.org/onlinepubs/9699919799/functions/readdir.html
439 virtual /* struct */ dirent*
440 read (void) override;
441
442 // http://pubs.opengroup.org/onlinepubs/9699919799/functions/rewinddir.html
443 virtual void
444 rewind (void) override;
445
446 // http://pubs.opengroup.org/onlinepubs/9699919799/functions/closedir.html
447 virtual int
448 close (void) override;
449
450 // ----------------------------------------------------------------------
451 // Support functions.
452
454 impl (void) const;
455
460 // ----------------------------------------------------------------------
461 protected:
466 value_type impl_instance_;
467
468 lockable_type& locker_;
469
473 };
474#pragma GCC diagnostic pop
475
476#pragma GCC diagnostic pop
477
478 // ========================================================================
479 } /* namespace posix */
480} /* namespace os */
481
482// ===== Inline & template implementations ====================================
483
484namespace os
485{
486 namespace posix
487 {
488 // ========================================================================
489
490 inline file_system&
492 {
493 return impl ().get_file_system ();
494 }
495
496 inline /* struct */ dirent*
498 {
499 return &(impl ().dir_entry_);
500 }
501
502 inline directory_impl&
503 directory::impl (void) const
504 {
505 return /* static_cast<directory_impl&> */ (impl_);
506 }
507
508 // ========================================================================
509
510 inline file_system&
512 {
513 return file_system_;
514 }
515
516 // ========================================================================
517
518 template <typename T>
520 /* class */ file_system& fs)
521 : directory{ impl_instance_ }, //
522 impl_instance_{ fs }
523 {
524#if defined(OS_TRACE_POSIX_IO_DIRECTORY)
525 trace::printf ("directory_implementable::%s()=@%p\n", __func__, this);
526#endif
527 }
528
529#pragma GCC diagnostic push
530#if defined(__clang__)
531#elif defined(__GNUC__)
532#pragma GCC diagnostic ignored "-Wsuggest-final-methods"
533#endif
534 template <typename T>
536 {
537#if defined(OS_TRACE_POSIX_IO_DIRECTORY)
538 trace::printf ("directory_implementable::%s() @%p\n", __func__, this);
539#endif
540 }
541#pragma GCC diagnostic pop
542
543 template <typename T>
546 {
547 return static_cast<value_type&> (impl_);
548 }
549
550 // ========================================================================
551
552 template <typename T, typename L>
554 lockable_type& locker)
555 : directory{ impl_instance_ }, //
556 impl_instance_{ fs }, //
557 locker_ (locker)
558 {
559#if defined(OS_TRACE_POSIX_IO_DIRECTORY)
560 trace::printf ("directory_lockable::%s()=@%p\n", __func__, this);
561#endif
562 }
563
564#pragma GCC diagnostic push
565#if defined(__clang__)
566#elif defined(__GNUC__)
567#pragma GCC diagnostic ignored "-Wsuggest-final-methods"
568#endif
569 template <typename T, typename L>
571 {
572#if defined(OS_TRACE_POSIX_IO_DIRECTORY)
573 trace::printf ("directory_lockable::%s() @%p\n", __func__, this);
574#endif
575 }
576#pragma GCC diagnostic pop
577
578 // ------------------------------------------------------------------------
579
580 template <typename T, typename L>
581 /* struct */ dirent*
583 {
584#if defined(OS_TRACE_POSIX_IO_DIRECTORY)
585 trace::printf ("directory_lockable::%s() @%p\n", __func__, this);
586#endif
587
588 std::lock_guard<L> lock{ locker_ };
589
590 return directory::read ();
591 }
592
593 template <typename T, typename L>
594 void
596 {
597#if defined(OS_TRACE_POSIX_IO_DIRECTORY)
598 trace::printf ("directory_lockable::%s() @%p\n", __func__, this);
599#endif
600
601 std::lock_guard<L> lock{ locker_ };
602
603 return directory::rewind ();
604 }
605
606 template <typename T, typename L>
607 int
609 {
610#if defined(OS_TRACE_POSIX_IO_DIRECTORY)
611 trace::printf ("directory_lockable::%s() @%p\n", __func__, this);
612#endif
613
614 std::lock_guard<L> lock{ locker_ };
615
616 return directory::close ();
617 }
618
619 template <typename T, typename L>
622 {
623 return static_cast<value_type&> (impl_);
624 }
625
626 // ========================================================================
627 } /* namespace posix */
628} /* namespace os */
629
630#pragma GCC diagnostic pop
631
632// ----------------------------------------------------------------------------
633
634#endif /* __cplusplus */
635
636// ----------------------------------------------------------------------------
637
638#endif /* CMSIS_PLUS_POSIX_IO_DIRECTORY_H_ */
class file_system & get_file_system(void) const
Definition directory.h:511
virtual int do_close(void)=0
virtual dirent * do_read(void)=0
virtual void do_rewind(void)=0
value_type & impl(void) const
Definition directory.h:545
directory_implementable(file_system &fs)
Definition directory.h:519
virtual ~directory_implementable() override
Definition directory.h:535
value_type & impl(void) const
Definition directory.h:621
virtual int close(void) override
Definition directory.h:608
directory_lockable(file_system &fs, lockable_type &locker)
Definition directory.h:553
virtual ~directory_lockable() override
Definition directory.h:570
virtual dirent * read(void) override
Definition directory.h:582
virtual void rewind(void) override
Definition directory.h:595
Directory class.
Definition directory.h:75
dirent * dir_entry(void)
Definition directory.h:497
virtual int close(void)
Definition directory.cpp:84
class file_system & get_file_system(void) const
Definition directory.h:491
virtual dirent * read(void)
Definition directory.cpp:50
virtual void rewind(void)
Definition directory.cpp:68
directory_impl & impl(void) const
Definition directory.h:503
File system class.
int printf(const char *format,...)
Write a formatted string to the trace device.
Definition trace.cpp:59
System namespace.