µ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 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
31
33
34#include <cerrno>
35#include <cassert>
36#include <cstddef>
37
38// ----------------------------------------------------------------------------
39
40#if defined(__clang__)
41#pragma clang diagnostic ignored "-Wc++98-compat"
42#endif
43
44// ----------------------------------------------------------------------------
45
46namespace os
47{
48 namespace posix
49 {
50 // ------------------------------------------------------------------------
51
56 std::size_t file_descriptors_manager::size__;
57
58 io** file_descriptors_manager::descriptors_array__;
59
64 // ========================================================================
66 {
67 trace::printf ("file_descriptors_manager::%s(%d)=%p\n", __func__, size,
68 this);
69
70 assert(size > 0);
71
72 size__ = size + reserved__; // Add space for standard files.
73 descriptors_array__ = new class io*[size__];
74
75 for (std::size_t i = 0; i < file_descriptors_manager::size (); ++i)
76 {
77 descriptors_array__[i] = nullptr;
78 }
79 }
80
82 {
83 trace::printf ("file_descriptors_manager::%s(%) @%p\n", __func__, this);
84
85 delete[] descriptors_array__;
86 size__ = 0;
87 }
88
89 // ------------------------------------------------------------------------
90
91 io*
93 {
94 // Check if valid descriptor or buffer not yet initialised
95 if ((fildes < 0) || (static_cast<std::size_t> (fildes) >= size__)
96 || (descriptors_array__ == nullptr))
97 {
98 return nullptr;
99 }
100 return descriptors_array__[fildes];
101 }
102
103 bool
105 {
106 if ((fildes < 0) || (static_cast<std::size_t> (fildes) >= size__))
107 {
108 return false;
109 }
110 return true;
111 }
112
113 int
115 {
116#if defined(OS_TRACE_POSIX_IO_FILE_DESCRIPTORS_MANAGER)
117 trace::printf ("file_descriptors_manager::%s(%p)\n", __func__, io);
118#endif
119
120 if (io->file_descriptor () >= 0)
121 {
122 // Already allocated
123 errno = EBUSY;
124 return -1;
125 }
126
127 for (std::size_t i = reserved__; i < size__; ++i)
128 {
129 if (descriptors_array__[i] == nullptr)
130 {
131 descriptors_array__[i] = io;
132 io->file_descriptor (static_cast<int> (i));
133#if defined(OS_TRACE_POSIX_IO_FILE_DESCRIPTORS_MANAGER)
134 trace::printf ("file_descriptors_manager::%s(%p) fd=%d\n",
135 __func__, io, i);
136#endif
137 return static_cast<int> (i);
138 }
139 }
140
141 // Too many files open in system.
142 errno = ENFILE;
143 return -1;
144 }
145
146 int
148 {
149 if ((fildes < 0) || (static_cast<std::size_t> (fildes) >= size__))
150 {
151 errno = EBADF;
152 return -1;
153 }
154
155 if (io->file_descriptor () >= 0)
156 {
157 // Already allocated
158 errno = EBUSY;
159 return -1;
160 }
161
162 descriptors_array__[fildes] = io;
163 io->file_descriptor (fildes);
164 return fildes;
165 }
166
167 int
169 {
170#if defined(OS_TRACE_POSIX_IO_FILE_DESCRIPTORS_MANAGER)
171 trace::printf ("file_descriptors_manager::%s(%d)\n", __func__, fildes);
172#endif
173
174 if ((fildes < 0) || (static_cast<std::size_t> (fildes) >= size__))
175 {
176 errno = EBADF;
177 return -1;
178 }
179
180 descriptors_array__[fildes]->clear_file_descriptor ();
181 descriptors_array__[fildes] = nullptr;
182 return 0;
183 }
184
185 class socket*
187 {
188 assert((fildes >= 0) && (static_cast<std::size_t> (fildes) < size__));
189 auto* const io = descriptors_array__[fildes];
190 if (io->get_type () != io::type::socket)
191 {
192 return nullptr;
193 }
194 return reinterpret_cast<class socket*> (io);
195 }
196
197 size_t
199 {
200 std::size_t count = reserved__;
201 for (std::size_t i = reserved__; i < file_descriptors_manager::size ();
202 ++i)
203 {
204 if (descriptors_array__[i] != nullptr)
205 {
206 ++count;
207 }
208 }
209 return count;
210 }
211
212 // ========================================================================
213 } /* namespace posix */
214} /* namespace os */
215
216// ----------------------------------------------------------------------------
217
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:98
file_descriptor_t file_descriptor(void) const
Definition io.h:441
type_t get_type(void) const
Definition io.h:423
Network socket.
int printf(const char *format,...)
Write a formatted string to the trace device.
Definition trace.cpp:74
int file_descriptor_t
Definition types.h:59
System namespace.