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