BDE 4.14.0 Production release
Loading...
Searching...
No Matches
bdls_filesystemutil_transitionaluniximputil.h
Go to the documentation of this file.
1/// @file bdls_filesystemutil_transitionaluniximputil.h
2///
3/// The content of this file has been pre-processed for Doxygen.
4///
5
6
7// bdls_filesystemutil_transitionaluniximputil.h -*-C++-*-
8#ifndef INCLUDED_BDLS_FILESYSTEMUTIL_TRANSITIONALUNIXIMPUTIL
9#define INCLUDED_BDLS_FILESYSTEMUTIL_TRANSITIONALUNIXIMPUTIL
10
11#include <bsls_ident.h>
12BSLS_IDENT("$Id: $")
13
14/// @defgroup bdls_filesystemutil_transitionaluniximputil bdls_filesystemutil_transitionaluniximputil
15/// @brief Provide testable `bdls::FilesystemUtil` operations for some Unixes.
16/// @addtogroup bdl
17/// @{
18/// @addtogroup bdls
19/// @{
20/// @addtogroup bdls_filesystemutil_transitionaluniximputil
21/// @{
22///
23/// <h1> Outline </h1>
24/// * <a href="#bdls_filesystemutil_transitionaluniximputil-purpose"> Purpose</a>
25/// * <a href="#bdls_filesystemutil_transitionaluniximputil-classes"> Classes </a>
26/// * <a href="#bdls_filesystemutil_transitionaluniximputil-description"> Description </a>
27/// * <a href="#bdls_filesystemutil_transitionaluniximputil-the-transitional-compilation-environment"> The Transitional-Compilation Environment </a>
28///
29/// # Purpose {#bdls_filesystemutil_transitionaluniximputil-purpose}
30/// Provide testable `bdls::FilesystemUtil` operations for some Unixes.
31///
32/// # Classes {#bdls_filesystemutil_transitionaluniximputil-classes}
33///
34/// - bdls::FileystemUtil_TransitionalUnixImpUtil: testable file-system utilities
35///
36/// @see bdls_filesystemutil, bdls_filesystemutil_unixplatform
37///
38/// # Description {#bdls_filesystemutil_transitionaluniximputil-description}
39/// This subordinate component to @ref bdls_filesystemutil provides a
40/// utlity `struct` template, `bdls::FilesystemUtil_TransitionalUnixImpUtil` for
41/// implementing some of `bdls::FileystemUtil`s functions on Unix platforms in
42/// the transitional-compilation environemnt.
43/// `bdls::FilesystemUtil_TransitionalUnixImpUtil` accesses Unix functions and
44/// types through its template parameter, `UNIX_INTERFACE`, in order to allow
45/// tests to supply mock Unix interfaces.
46///
47/// ## The Transitional-Compilation Environment {#bdls_filesystemutil_transitionaluniximputil-the-transitional-compilation-environment}
48///
49///
50/// Many Unix systems provide a non-standard "transitional-compilation
51/// environment", which is a compilation mode that supports large, 64-bit file
52/// operations in 32-bit (or 64-bit) programs. For more information about this
53/// and other large-file compilation modes, please see the `lfcompile64` and/or
54/// `lfcompile` manual pages provided for the operating system of interest.
55/// Note that some Unix systems may not support a transitional-compilation
56/// environment, and some that do may provide descriptions of this environment
57/// in documentation outside of a `lfcompile64` or `lfcompile` manual page.
58/// Furthermore, some Unix systems natively provide 64-bit file operations for
59/// 32-bit programs, in which case a transitional-compilation environment is not
60/// necessary.
61///
62/// Another subordinate component of @ref bdls_filesystemutil ,
63/// `bdls_filesystemutil_unixplatform`, is principally concerned with the
64/// detection of the transitional-compilation environment on any Unix platform
65/// supported by the BDE library.
66/// @}
67/** @} */
68/** @} */
69
70/** @addtogroup bdl
71 * @{
72 */
73/** @addtogroup bdls
74 * @{
75 */
76/** @addtogroup bdls_filesystemutil_transitionaluniximputil
77 * @{
78 */
79
80#include <bdlt_datetime.h>
81#include <bdlt_epochutil.h>
82#include <bdlt_timeunitratio.h>
83
84#include <bsls_assert.h>
85
86
87namespace bdls {
88
89 // =============================================
90 // struct FilesystemUtil_TransitionalUnixImpUtil
91 // =============================================
92
93/// This component-private utility `struct` provides a namespace for a suite
94/// of functions that `FilesystemUtil` uses as implementation details.
95/// These functions have a `UNIX_INTERFACE` template parameter, which
96/// provides access to the entities that transitional-compilation
97/// environment Unix systems declare, and that the function implementations
98/// need.
99///
100/// Note that, on some Unix platforms and some build configurations, the
101/// `stat` struct does not have an `st_mtime` field, and `st_mtime` is a
102/// macro that emulates the access of the field. Similarly, on some Unix
103/// platforms and some build configurations, the `stat` structure does not
104/// have an `st_mtim` field or the `st_mtim` struct does not have a
105/// `tv_nsec` (or, for some versions of Solaris, `__tv_nsec`) field, in
106/// which case the `get_st_mtim_nsec` function returns zero. For more
107/// information, please see the specification of the `sys/stat.h` header
108/// from IEEE Std
109/// 1003.1-2017, which provides information about the evolution of the
110/// `stat` struct in the POSIX specification
111/// (https://pubs.opengroup.org/onlinepubs/9699919799.2018edition/).
112///
113/// The program is ill-formed unless the specified `UNIX_INTERFACE` is a
114/// class type that meets the following requirements:
115///
116/// * `UNIX_INTERFACE::off64_t` is a type alias to the `off64_t` type
117/// provided by the `sys/types.h` header.
118/// * `UNIX_INTERFACE::stat64` is a type alias to the `stat64` type
119/// provided by the `sys/stat.h` header.
120/// * `UNIX_INTERFACE::time_t` is a type alias to the `time_t` type
121/// provided by the `sys/types.h` header.
122/// * `UNIX_INTERFACE::get_st_mtim_nsec` is a public, static member
123/// function that has `long (const stat& stat)` type and whose contract
124/// is to return the value of the `st_mtim.tv_nsec` field of the
125/// specified `stat` struct.
126/// * `UNIX_INTERFACE::get_st_mtime` is a public, static member function
127/// that has `time_t (const stat& stat)` type and whose contract is to
128/// return the value of the `st_mtime` field of the specified `stat`
129/// struct.
130/// * `UNIX_INTERFACE::get_st_size` is a public, static member function
131/// that has `off64_t (const stat& stat)` type and whose contract is to
132/// return the value of the `st_size` field of the specified `stat`
133/// struct. Note that this function is required in order to
134/// access the data members of a `stat` struct in a manner consistent
135/// with the requirements of `get_st_mtime`.
136/// * `UNIX_INTERFACE::fstat64` is a public, static member function that
137/// has `int (int fildes, stat64 *buf)` type and whose contract is to
138/// return the result of `::fstat64(fildes, buf)`, where `::fstat64` is
139/// the function provided by the `sys/stat.h` header.
140template <class UNIX_INTERFACE>
142
143 // TYPES
144
145 /// `FileDescriptor` is an alias for the operating system's native file
146 /// descriptor / file handle type.
147 typedef int FileDescriptor;
148
149 /// `Offset` is an alias for a signed integral type, and represents the
150 /// offset of a location in a file.
151 typedef typename UNIX_INTERFACE::off64_t Offset;
152
153 private:
154 // PRIVATE TYPES
155
156 /// `off_t` is an alias to the `off64_t` type provided by the
157 /// `sys/types.h` header. It is a signed integral type used to
158 /// represent quantities of bytes.
159 typedef typename UNIX_INTERFACE::off64_t off64_t;
160
161 /// `stat64` is an alias to the `stat64` `struct` provided by the
162 /// `sys/stat.h` header.
163 typedef typename UNIX_INTERFACE::stat64 stat64;
164
165 /// `time_t` is an alias to the `time_t` type provided by the `sys/types.h`
166 /// header. It represents a time point as number of seconds since January
167 /// 1st 1970 in Coordinated Universal Time.
168 typedef typename UNIX_INTERFACE::time_t time_t;
169
170 // PRIVATE CLASS METHODS
171
172 /// Return the value of the `st_mtim.nsec` field of the specified `stat`
173 /// struct.
174 static long get_st_mtim_nsec(const stat64& stat);
175
176 /// Return the value of the `st_mtime` data member of the specified `stat`.
177 static time_t get_st_mtime(const stat64& stat);
178
179 /// Return the value of the `st_size` data member of the specified `stat`.
180 /// Note that this function is provided in order to create a consistent
181 /// interface for accessing the data members of a `stat64` struct with
182 /// `get_st_mtime`.
183 static off64_t get_st_size(const stat64& stat);
184
185 /// Invoke and return the result of `::fstat64(fildes, buf)` with the
186 /// specified `fildes` and `buf`, where `::fstat64` is the function
187 /// provided by the `sys/stat.h` header.
188 static int fstat64(int fildes, stat64 *buf);
189
190 public:
191 // CLASS METHODS
192
193 /// Return the size, in bytes, of the file with the specified `descriptor`,
194 /// or a negative value if an error occurs.
195 static Offset getFileSize(FileDescriptor descriptor);
196
197 /// Load into the specified `time` the last modification time of the file
198 /// with the specified `descriptor`, as reported by the filesystem. Return
199 /// 0 on success, and a non-zero value otherwise. Note that the time is
200 /// reported in UTC.
202 FileDescriptor descriptor);
203};
204
205// ============================================================================
206// INLINE DEFINITIONS
207// ============================================================================
208
209 // ---------------------------------------------
210 // struct FilesystemUtil_TransitionalUnixImpUtil
211 // ---------------------------------------------
212
213// PRIVATE CLASS METHODS
214template <class UNIX_INTERFACE>
215long
217 const stat64& stat)
218{
219 return UNIX_INTERFACE::get_st_mtim_nsec(stat);
220}
221
222template <class UNIX_INTERFACE>
223typename UNIX_INTERFACE::time_t
224FilesystemUtil_TransitionalUnixImpUtil<UNIX_INTERFACE>::get_st_mtime(
225 const stat64& stat)
226{
227 return UNIX_INTERFACE::get_st_mtime(stat);
228}
229
230template <class UNIX_INTERFACE>
231typename UNIX_INTERFACE::off64_t
232FilesystemUtil_TransitionalUnixImpUtil<UNIX_INTERFACE>::get_st_size(
233 const stat64& stat)
234{
235 return UNIX_INTERFACE::get_st_size(stat);
236}
237
238template <class UNIX_INTERFACE>
239int FilesystemUtil_TransitionalUnixImpUtil<UNIX_INTERFACE>::fstat64(
240 int fildes,
241 stat64 *buf)
242{
243 return UNIX_INTERFACE::fstat64(fildes, buf);
244}
245
246// CLASS METHODS
247template <class UNIX_INTERFACE>
250 FileDescriptor descriptor)
251{
252 stat64 statResult;
253 const int rc = fstat64(descriptor, &statResult);
254 if (0 != rc) {
255 return -1; // RETURN
256 }
257
258 return get_st_size(statResult);
259}
260
261template <class UNIX_INTERFACE>
263 UNIX_INTERFACE>::getLastModificationTime(bdlt::Datetime *time,
264 FileDescriptor descriptor)
265{
266 stat64 statResult;
267 int rc = fstat64(descriptor, &statResult);
268 if (0 != rc) {
269 return -1; // RETURN
270 }
271
273 rc = result.addSecondsIfValid(get_st_mtime(statResult));
274 if (0 != rc) {
275 return -1; // RETURN
276 }
277
278 long nanoseconds = get_st_mtim_nsec(statResult);
279 BSLS_ASSERT_SAFE((0 <= nanoseconds) &&
280 (nanoseconds <
282 rc = result.addMicrosecondsIfValid(
284 if (0 != rc) {
285 return -1; // RETURN
286 }
287
288 *time = result;
289 return 0;
290}
291
292} // close package namespace
293
294
295#endif
296
297// ----------------------------------------------------------------------------
298// Copyright 2020 Bloomberg Finance L.P.
299//
300// Licensed under the Apache License, Version 2.0 (the "License");
301// you may not use this file except in compliance with the License.
302// You may obtain a copy of the License at
303//
304// http://www.apache.org/licenses/LICENSE-2.0
305//
306// Unless required by applicable law or agreed to in writing, software
307// distributed under the License is distributed on an "AS IS" BASIS,
308// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
309// See the License for the specific language governing permissions and
310// limitations under the License.
311// ----------------------------- END-OF-FILE ----------------------------------
312
313/** @} */
314/** @} */
315/** @} */
Definition bdlt_datetime.h:331
int addMicrosecondsIfValid(bsls::Types::Int64 microseconds)
Definition bdlt_datetime.h:2103
int addSecondsIfValid(bsls::Types::Int64 seconds)
Definition bdlt_datetime.h:2040
#define BSLS_ASSERT_SAFE(X)
Definition bsls_assert.h:1762
#define BSLS_IDENT(str)
Definition bsls_ident.h:195
Definition bdls_fdstreambuf.h:412
Definition bdls_filesystemutil_transitionaluniximputil.h:141
int FileDescriptor
Definition bdls_filesystemutil_transitionaluniximputil.h:147
static Offset getFileSize(FileDescriptor descriptor)
Definition bdls_filesystemutil_transitionaluniximputil.h:249
UNIX_INTERFACE::off64_t Offset
Definition bdls_filesystemutil_transitionaluniximputil.h:151
static int getLastModificationTime(bdlt::Datetime *time, FileDescriptor descriptor)
Definition bdls_filesystemutil_transitionaluniximputil.h:263
static const Datetime & epoch()
Definition bdlt_epochutil.h:375
static const bsls::Types::Int64 k_NANOSECONDS_PER_SECOND
Definition bdlt_timeunitratio.h:217
static const int k_NANOSECONDS_PER_MICROSECOND_32
Definition bdlt_timeunitratio.h:296