µ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-descriptors-manager.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-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#if defined(OS_USE_OS_APP_CONFIG_H)
14#include <cmsis-plus/os-app-config.h>
15#endif
16
20
22
23#include <cerrno>
24#include <cassert>
25#include <cstddef>
26
27// ----------------------------------------------------------------------------
28
29#if defined(__clang__)
30#pragma clang diagnostic ignored "-Wc++98-compat"
31#endif
32
33// ----------------------------------------------------------------------------
34
35namespace os
36{
37 namespace posix
38 {
39 // ------------------------------------------------------------------------
40
45 std::size_t file_descriptors_manager::size__;
46
47 io** file_descriptors_manager::descriptors_array__;
48
53 // ========================================================================
55 {
56 trace::printf ("file_descriptors_manager::%s(%d)=%p\n", __func__, size,
57 this);
58
59 assert(size > 0);
60
61 size__ = size + reserved__; // Add space for standard files.
62 descriptors_array__ = new class io*[size__];
63
64 for (std::size_t i = 0; i < file_descriptors_manager::size (); ++i)
65 {
66 descriptors_array__[i] = nullptr;
67 }
68 }
69
71 {
72 trace::printf ("file_descriptors_manager::%s(%) @%p\n", __func__, this);
73
74 delete[] descriptors_array__;
75 size__ = 0;
76 }
77
78 // ------------------------------------------------------------------------
79
80 io*
82 {
83 // Check if valid descriptor or buffer not yet initialised
84 if ((fildes < 0) || (static_cast<std::size_t> (fildes) >= size__)
85 || (descriptors_array__ == nullptr))
86 {
87 return nullptr;
88 }
89 return descriptors_array__[fildes];
90 }
91
92 bool
94 {
95 if ((fildes < 0) || (static_cast<std::size_t> (fildes) >= size__))
96 {
97 return false;
98 }
99 return true;
100 }
101
102 int
104 {
105#if defined(OS_TRACE_POSIX_IO_FILE_DESCRIPTORS_MANAGER)
106 trace::printf ("file_descriptors_manager::%s(%p)\n", __func__, io);
107#endif
108
109 if (io->file_descriptor () >= 0)
110 {
111 // Already allocated
112 errno = EBUSY;
113 return -1;
114 }
115
116 for (std::size_t i = reserved__; i < size__; ++i)
117 {
118 if (descriptors_array__[i] == nullptr)
119 {
120 descriptors_array__[i] = io;
121 io->file_descriptor (static_cast<int> (i));
122#if defined(OS_TRACE_POSIX_IO_FILE_DESCRIPTORS_MANAGER)
123 trace::printf ("file_descriptors_manager::%s(%p) fd=%d\n",
124 __func__, io, i);
125#endif
126 return static_cast<int> (i);
127 }
128 }
129
130 // Too many files open in system.
131 errno = ENFILE;
132 return -1;
133 }
134
135 int
137 {
138 if ((fildes < 0) || (static_cast<std::size_t> (fildes) >= size__))
139 {
140 errno = EBADF;
141 return -1;
142 }
143
144 if (io->file_descriptor () >= 0)
145 {
146 // Already allocated
147 errno = EBUSY;
148 return -1;
149 }
150
151 descriptors_array__[fildes] = io;
152 io->file_descriptor (fildes);
153 return fildes;
154 }
155
156 int
158 {
159#if defined(OS_TRACE_POSIX_IO_FILE_DESCRIPTORS_MANAGER)
160 trace::printf ("file_descriptors_manager::%s(%d)\n", __func__, fildes);
161#endif
162
163 if ((fildes < 0) || (static_cast<std::size_t> (fildes) >= size__))
164 {
165 errno = EBADF;
166 return -1;
167 }
168
169 descriptors_array__[fildes]->clear_file_descriptor ();
170 descriptors_array__[fildes] = nullptr;
171 return 0;
172 }
173
174 /* class */ socket*
176 {
177 assert((fildes >= 0) && (static_cast<std::size_t> (fildes) < size__));
178 auto* const io = descriptors_array__[fildes];
179 if (io->get_type () != static_cast<posix::io::type_t>(io::type::socket))
180 {
181 return nullptr;
182 }
183 return reinterpret_cast<class socket*> (io);
184 }
185
186 size_t
188 {
189 std::size_t count = reserved__;
190 for (std::size_t i = reserved__; i < file_descriptors_manager::size ();
191 ++i)
192 {
193 if (descriptors_array__[i] != nullptr)
194 {
195 ++count;
196 }
197 }
198 return count;
199 }
200
201 // ========================================================================
202 } /* namespace posix */
203} /* namespace os */
204
205// ----------------------------------------------------------------------------
206
static class socket * socket(int fildes)
static int deallocate(file_descriptor_t fildes)
static int assign(file_descriptor_t fildes, class io *io)
Base I/O class.
Definition io.h:87
file_descriptor_t file_descriptor(void) const
Definition io.h:456
unsigned int type_t
Definition io.h:127
type_t get_type(void) const
Definition io.h:438
Network socket.
int printf(const char *format,...)
Write a formatted string to the trace device.
Definition trace.cpp:60
int file_descriptor_t
Definition types.h:43
System namespace.