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