µOS++ IIIe Reference 7.0.0
The third edition of µOS++, a POSIX inspired open source framework, written in C++
Loading...
Searching...
No Matches
device.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) 2018 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
30
31#include <cstring>
32#include <cassert>
33#include <cerrno>
34#include <cstdarg>
35#include <unistd.h>
36
37// ----------------------------------------------------------------------------
38
39#if defined(__clang__)
40#pragma clang diagnostic ignored "-Wc++98-compat"
41#endif
42
43// ----------------------------------------------------------------------------
44
45namespace os
46{
47 namespace posix
48 {
49 // ========================================================================
50
51 device::device (device_impl& impl, type t, const char* name) :
52 io
53 { impl, t }, //
54 name_ (name)
55 {
56#if defined(OS_TRACE_POSIX_IO_DEVICE)
57 trace::printf ("device::%s(\"%s\")=%p\n", __func__, name_, this);
58#endif
59 }
60
62 {
63#if defined(OS_TRACE_POSIX_IO_DEVICE)
64 trace::printf ("device::%s() @%p\n", __func__, this);
65#endif
66
67 registry_links_.unlink ();
68
69 name_ = nullptr;
70 }
71
72 // ------------------------------------------------------------------------
73
74 int
75 device::open (const char* path, int oflag, ...)
76 {
77 // Forward to the variadic version of the function.
78 std::va_list args;
79 va_start(args, oflag);
80 int ret = vopen (path, oflag, args);
81 va_end(args);
82
83 return ret;
84 }
85
86 int
87 device::vopen (const char* path, int oflag, std::va_list args)
88 {
89#if defined(OS_TRACE_POSIX_IO_DEVICE)
90 trace::printf ("device::%s(\"%s\") @%p\n", __func__, path ? path : "",
91 this);
92#endif
93
94 errno = 0;
95
96 int ret = 0;
97 if (impl ().open_count_ == 0)
98 {
99 // If so, use the implementation to open the device.
100 ret = impl ().do_vopen (path, oflag, args);
101 if (ret < 0)
102 {
103 // Open failed.
104 return -1;
105 }
106
107 auto iop = alloc_file_descriptor ();
108 if (iop == nullptr)
109 {
110 return -1;
111 }
112
113 }
114 ++(impl ().open_count_);
115 ret = file_descriptor ();
116#if defined(OS_TRACE_POSIX_IO_DEVICE)
117 trace::printf ("device::%s(\"%s\")=%p fd=%d\n", __func__,
118 path ? path : "", this, ret);
119#endif
120
121 return ret;
122 }
123
124 int
126 {
127#if defined(OS_TRACE_POSIX_IO_DEVICE)
128 trace::printf ("device::%s() @%p\n", __func__, this);
129#endif
130
131 errno = 0;
132
133 int ret = 0;
134 if (impl ().open_count_ == 1)
135 {
136 ret = io::close ();
137 }
138
139 if (impl ().open_count_ > 0)
140 {
141 // Must be after close(), to keep do_is_open() true.
142 --(impl ().open_count_);
143 }
144
145 return ret;
146 }
147
148 int
149 device::ioctl (int request, ...)
150 {
151 // Forward to the variadic version of the function.
152 std::va_list args;
153 va_start(args, request);
154 int ret = vioctl (request, args);
155 va_end(args);
156
157 return ret;
158 }
159
160 int
161 device::vioctl (int request, std::va_list args)
162 {
163#if defined(OS_TRACE_POSIX_IO_DEVICE)
164 trace::printf ("device::%s(%d) @%p\n", __func__, request, this);
165#endif
166
167 if (impl ().open_count_ == 0)
168 {
169 errno = EBADF; // Not opened.
170 return -1;
171 }
172
173 errno = 0;
174
175 return impl ().do_vioctl (request, args);
176 }
177
178 void
180 {
181#if defined(OS_TRACE_POSIX_IO_DEVICE)
182 trace::printf ("device::%s() @%p\n", __func__, this);
183#endif
184
185 if (impl ().open_count_ == 0)
186 {
187 errno = EBADF; // Not opened.
188 return;
189 }
190
191 impl ().do_sync ();
192 }
193
194 // ------------------------------------------------------------------------
195
196 bool
197 device::match_name (const char* name) const
198 {
199 assert(name != nullptr);
200 assert(name_ != nullptr);
201
202 return (std::strcmp (name, name_) == 0);
203 }
204
205 // ========================================================================
206
208 {
209#if defined(OS_TRACE_POSIX_IO_DEVICE)
210 trace::printf ("device_impl::%s()=%p\n", __func__, this);
211#endif
212 }
213
215 {
216#if defined(OS_TRACE_POSIX_IO_DEVICE)
217 trace::printf ("device_impl::%s() @%p\n", __func__, this);
218#endif
219 }
220
221 // ----------------------------------------------------------------------
222
223 bool
225 {
226 return (open_count_ > 0);
227 }
228
229 // ========================================================================
230
231 } /* namespace posix */
232} /* namespace os */
233
234// ----------------------------------------------------------------------------
virtual int do_vioctl(int request, std::va_list args)=0
virtual ~device_impl() override
Definition device.cpp:214
virtual bool do_is_opened(void) override
Definition device.cpp:224
virtual void do_sync(void)=0
virtual int do_vopen(const char *path, int oflag, std::va_list args)=0
device(device_impl &impl, type t, const char *name)
Definition device.cpp:51
device_impl & impl(void) const
Definition device.h:316
virtual int close(void) override
Definition device.cpp:125
virtual bool match_name(const char *name) const
Definition device.cpp:197
int vopen(const char *path, int oflag, std::va_list args)
Definition device.cpp:87
virtual int vioctl(int request, std::va_list args)
Definition device.cpp:161
int ioctl(int request,...)
Definition device.cpp:149
virtual ~device() override
Definition device.cpp:61
int open(const char *path=nullptr, int oflag=0,...)
Definition device.cpp:75
virtual void sync(void)
Definition device.cpp:179
const char * name(void) const
Definition device.h:310
Base I/O class.
Definition io.h:98
file_descriptor_t file_descriptor(void) const
Definition io.h:441
io * alloc_file_descriptor(void)
Definition io.cpp:201
virtual int close(void)
Definition io.cpp:176
int printf(const char *format,...)
Write a formatted string to the trace device.
Definition trace.cpp:74
System namespace.