µ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++ 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
28#ifndef CMSIS_PLUS_POSIX_IO_DIRECTORY_H_
29#define CMSIS_PLUS_POSIX_IO_DIRECTORY_H_
30
31// ----------------------------------------------------------------------------
32
33#if defined(__cplusplus)
34
35// ----------------------------------------------------------------------------
36
37#if defined(OS_USE_OS_APP_CONFIG_H)
38#include <cmsis-plus/os-app-config.h>
39#endif
40
43
45
46#include <mutex>
47
48// ----------------------------------------------------------------------------
49
50#pragma GCC diagnostic push
51
52#if defined(__clang__)
53#pragma clang diagnostic ignored "-Wc++98-compat"
54#pragma clang diagnostic ignored "-Wdocumentation-unknown-command"
55#endif
56
57// ----------------------------------------------------------------------------
58
59namespace os
60{
61 namespace posix
62 {
63 // ------------------------------------------------------------------------
64
65 class directory;
66 class directory_impl;
67 class file_system;
68
69 // ------------------------------------------------------------------------
70
71 // ========================================================================
72#pragma GCC diagnostic push
73#pragma GCC diagnostic ignored "-Wpadded"
74
81 {
82 // ----------------------------------------------------------------------
83
88 friend class file_system;
89
94 // ----------------------------------------------------------------------
100 public:
101
103
108 // The rule of five.
109 directory (const directory&) = delete;
110 directory (directory&&) = delete;
111 directory&
112 operator= (const directory&) = delete;
113 directory&
114 operator= (directory&&) = delete;
115
120 virtual
121 ~directory ();
122
127 // ----------------------------------------------------------------------
133 public:
134
135 // http://pubs.opengroup.org/onlinepubs/9699919799/functions/readdir.html
136 virtual struct dirent *
137 read (void);
138
139 // http://pubs.opengroup.org/onlinepubs/9699919799/functions/rewinddir.html
140 virtual void
141 rewind (void);
142
143 // http://pubs.opengroup.org/onlinepubs/9699919799/functions/closedir.html
144 virtual int
145 close (void);
146
147 // ----------------------------------------------------------------------
148 // Support functions.
149
150 struct dirent*
151 dir_entry (void);
152
153 class file_system&
154 file_system (void) const;
155
157 impl (void) const;
158
163 // ----------------------------------------------------------------------
164 public:
165
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:
180
185 directory_impl& impl_;
186
190 };
191
192 // ========================================================================
193
195 {
196 // ----------------------------------------------------------------------
197
202 friend class directory;
203
208 // ----------------------------------------------------------------------
214 public:
215
216 directory_impl (class file_system& fs);
217
222 // The rule of five.
223 directory_impl (const directory_impl&) = delete;
224 directory_impl (directory_impl&&) = delete;
226 operator= (const directory_impl&) = delete;
228 operator= (directory_impl&&) = delete;
229
234 virtual
236
241 // ----------------------------------------------------------------------
247 public:
248
249 // Implementations
250
254 virtual struct dirent*
255 do_read (void) = 0;
256
257 virtual void
258 do_rewind (void) = 0;
259
260 virtual int
261 do_close (void) = 0;
262
263 // ----------------------------------------------------------------------
264 // Support functions.
265
266 class file_system&
267 file_system (void) const;
268
273 // ----------------------------------------------------------------------
274 protected:
275
280 // This also solves the readdir() re-entrancy issue.
281 struct dirent dir_entry_;
282
283 class file_system& file_system_;
284
288 };
289
290 // ========================================================================
291
292 template<typename T>
294 {
295 // --------------------------------------------------------------------
296
297 public:
298
299 using value_type = T;
300
301 // --------------------------------------------------------------------
307 public:
308
310
315 // The rule of five.
319 operator= (const directory_implementable&) = delete;
321 operator= (directory_implementable&&) = delete;
322
327 virtual
328 ~directory_implementable () override;
329
334 // --------------------------------------------------------------------
340 public:
341
342 // Support functions.
343
345 impl (void) const;
346
351 // --------------------------------------------------------------------
352 protected:
353
358 value_type impl_instance_;
359
363 };
364
365 // ========================================================================
366
367 template<typename T, typename L>
369 {
370 // --------------------------------------------------------------------
371
372 public:
373
374 using value_type = T;
375 using lockable_type = L;
376
377 // --------------------------------------------------------------------
378
384 public:
385
386 directory_lockable (class file_system& fs, lockable_type& locker);
387
392 // The rule of five.
393 directory_lockable (const directory_lockable&) = delete;
396 operator= (const directory_lockable&) = delete;
398 operator= (directory_lockable&&) = delete;
399
404 virtual
405 ~directory_lockable () override;
406
411 // --------------------------------------------------------------------
417 public:
418
419 // opendir() uses the file system lock.
420
421 // http://pubs.opengroup.org/onlinepubs/9699919799/functions/readdir.html
422 virtual struct dirent *
423 read (void) override;
424
425 // http://pubs.opengroup.org/onlinepubs/9699919799/functions/rewinddir.html
426 virtual void
427 rewind (void) override;
428
429 // http://pubs.opengroup.org/onlinepubs/9699919799/functions/closedir.html
430 virtual int
431 close (void) override;
432
433 // --------------------------------------------------------------------
434 // Support functions.
435
437 impl (void) const;
438
443 // --------------------------------------------------------------------
444 protected:
445
450 value_type impl_instance_;
451
452 lockable_type& locker_;
453
457 };
458
459#pragma GCC diagnostic pop
460
461 // ==========================================================================
462 } /* namespace posix */
463} /* namespace os */
464
465// ===== Inline & template implementations ====================================
466
467namespace os
468{
469 namespace posix
470 {
471 // ========================================================================
472
473 inline file_system&
475 {
476 return impl ().file_system ();
477 }
478
479 inline struct dirent*
481 {
482 return &(impl ().dir_entry_);
483 }
484
485 inline directory_impl&
486 directory::impl (void) const
487 {
488 return static_cast<directory_impl&> (impl_);
489 }
490
491 // ========================================================================
492
493 inline file_system&
495 {
496 return file_system_;
497 }
498
499 // ========================================================================
500
501 template<typename T>
503 class file_system& fs) :
505 { impl_instance_ }, //
506 impl_instance_
507 { fs }
508 {
509#if defined(OS_TRACE_POSIX_IO_DIRECTORY)
510 trace::printf ("directory_implementable::%s()=@%p\n", __func__, this);
511#endif
512 }
513
514 template<typename T>
516 {
517#if defined(OS_TRACE_POSIX_IO_DIRECTORY)
518 trace::printf ("directory_implementable::%s() @%p\n", __func__, this);
519#endif
520 }
521
522 template<typename T>
525 {
526 return static_cast<value_type&> (impl_);
527 }
528
529 // ========================================================================
530
531 template<typename T, typename L>
533 lockable_type& locker) :
535 { impl_instance_ }, //
536 impl_instance_
537 { fs }, //
538 locker_ (locker)
539 {
540#if defined(OS_TRACE_POSIX_IO_DIRECTORY)
541 trace::printf ("directory_lockable::%s()=@%p\n", __func__, this);
542#endif
543 }
544
545 template<typename T, typename L>
547 {
548#if defined(OS_TRACE_POSIX_IO_DIRECTORY)
549 trace::printf ("directory_lockable::%s() @%p\n", __func__, this);
550#endif
551 }
552
553 // ------------------------------------------------------------------------
554
555 template<typename T, typename L>
556 struct dirent *
558 {
559#if defined(OS_TRACE_POSIX_IO_DIRECTORY)
560 trace::printf ("directory_lockable::%s() @%p\n", __func__, this);
561#endif
562
563 std::lock_guard<L> lock
564 { locker_ };
565
566 return directory::read ();
567 }
568
569 template<typename T, typename L>
570 void
572 {
573#if defined(OS_TRACE_POSIX_IO_DIRECTORY)
574 trace::printf ("directory_lockable::%s() @%p\n", __func__, this);
575#endif
576
577 std::lock_guard<L> lock
578 { locker_ };
579
580 return directory::rewind ();
581 }
582
583 template<typename T, typename L>
584 int
586 {
587#if defined(OS_TRACE_POSIX_IO_DIRECTORY)
588 trace::printf ("directory_lockable::%s() @%p\n", __func__, this);
589#endif
590
591 std::lock_guard<L> lock
592 { locker_ };
593
594 return directory::close ();
595 }
596
597 template<typename T, typename L>
600 {
601 return static_cast<value_type&> (impl_);
602 }
603
604 // ==========================================================================
605 } /* namespace posix */
606} /* namespace os */
607
608#pragma GCC diagnostic pop
609
610// ----------------------------------------------------------------------------
611
612#endif /* __cplusplus */
613
614// ----------------------------------------------------------------------------
615
616#endif /* CMSIS_PLUS_POSIX_IO_DIRECTORY_H_ */
virtual struct dirent * do_read(void)=0
class file_system & file_system(void) const
Definition directory.h:494
virtual int do_close(void)=0
virtual void do_rewind(void)=0
value_type & impl(void) const
Definition directory.h:524
virtual ~directory_implementable() override
Definition directory.h:515
directory_implementable(class file_system &fs)
Definition directory.h:502
value_type & impl(void) const
Definition directory.h:599
virtual int close(void) override
Definition directory.h:585
virtual ~directory_lockable() override
Definition directory.h:546
directory_lockable(class file_system &fs, lockable_type &locker)
Definition directory.h:532
virtual struct dirent * read(void) override
Definition directory.h:557
virtual void rewind(void) override
Definition directory.h:571
Directory class.
Definition directory.h:81
virtual int close(void)
Definition directory.cpp:97
virtual struct dirent * read(void)
Definition directory.cpp:63
class file_system & file_system(void) const
Definition directory.h:474
struct dirent * dir_entry(void)
Definition directory.h:480
virtual void rewind(void)
Definition directory.cpp:81
directory_impl & impl(void) const
Definition directory.h:486
File system class.
int printf(const char *format,...)
Write a formatted string to the trace device.
Definition trace.cpp:74
System namespace.