HDK
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros Groups Pages
fileSystem.h
Go to the documentation of this file.
1 //
2 // Copyright 2016 Pixar
3 //
4 // Licensed under the terms set forth in the LICENSE.txt file available at
5 // https://openusd.org/license.
6 //
7 #ifndef PXR_BASE_ARCH_FILE_SYSTEM_H
8 #define PXR_BASE_ARCH_FILE_SYSTEM_H
9 
10 /// \file arch/fileSystem.h
11 /// \ingroup group_arch_SystemFunctions
12 /// Architecture dependent file system access
13 
14 #include "pxr/pxr.h"
15 #include "pxr/base/arch/api.h"
16 #include "pxr/base/arch/defines.h"
17 #include "pxr/base/arch/inttypes.h"
18 #include <memory>
19 #include <cstdio>
20 #include <cstdint>
21 #include <string>
22 #include <set>
23 
24 #include <fcntl.h>
25 #include <sys/types.h>
26 #include <sys/stat.h>
27 
28 #if defined(ARCH_OS_LINUX)
29 #include <unistd.h>
30 #include <sys/statfs.h>
31 #include <glob.h>
32 #elif defined(ARCH_OS_DARWIN)
33 #include <unistd.h>
34 #include <sys/mount.h>
35 #include <glob.h>
36 #elif defined(ARCH_OS_WINDOWS)
37 #include <io.h>
38 #include <windows.h>
39 #include <stringapiset.h>
40 #endif
41 
43 
44 /// \addtogroup group_arch_SystemFunctions
45 ///@{
46 #if !defined(ARCH_OS_WINDOWS)
47  #ifdef _POSIX_VERSION
48  #include <limits.h> /* for PATH_MAX */
49  #else
50  #include <sys/param.h> /* for MAXPATHLEN */
51  #endif
52 #else
53  // XXX -- Should probably have ARCH_ macro for this.
54  #define S_ISDIR(m) (((m) & S_IFMT) == S_IFDIR)
55 
56  // See https://msdn.microsoft.com/en-us/library/1w06ktdy.aspx
57  // XXX -- Should probably have Arch enum for these.
58  #define F_OK 0 // Test for existence.
59  #define X_OK 1 // Test for execute permission.
60  #define W_OK 2 // Test for write permission.
61  #define R_OK 4 // Test for read permission.
62 #endif
63 
64 #if defined(ARCH_OS_WINDOWS)
65  #define ARCH_GLOB_NOCHECK 1
66  #define ARCH_GLOB_MARK 2
67  #define ARCH_GLOB_NOSORT 4
68 #else
69  #define ARCH_GLOB_NOCHECK GLOB_NOCHECK
70  #define ARCH_GLOB_MARK GLOB_MARK
71  #define ARCH_GLOB_NOSORT GLOB_NOSORT
72 #endif
73 #define ARCH_GLOB_DEFAULT (ARCH_GLOB_NOCHECK | ARCH_GLOB_MARK)
74 
75 #ifndef ARCH_PATH_MAX
76  #ifdef PATH_MAX
77  #define ARCH_PATH_MAX PATH_MAX
78  #else
79  #ifdef MAXPATHLEN
80  #define ARCH_PATH_MAX MAXPATHLEN
81  #else
82  #ifdef _MAX_PATH
83  #define ARCH_PATH_MAX _MAX_PATH
84  #else
85  #define ARCH_PATH_MAX 1024
86  #endif
87  #endif
88  #endif
89 #endif
90 
91 #if defined(ARCH_OS_WINDOWS)
92  #define ARCH_PATH_SEP "\\"
93  #define ARCH_PATH_LIST_SEP ";"
94  #define ARCH_REL_PATH_IDENT ".\\"
95 #else
96  #define ARCH_PATH_SEP "/"
97  #define ARCH_PATH_LIST_SEP ":"
98  #define ARCH_REL_PATH_IDENT "./"
99 #endif
100 
101 #if defined(ARCH_OS_WINDOWS)
102 typedef struct __stat64 ArchStatType;
103 #else
104 typedef struct stat ArchStatType;
105 #endif
106 
107 /// \file fileSystem.h
108 /// Architecture dependent file system access
109 /// \ingroup group_arch_SystemFunctions
110 ///
111 
112 /// Opens a file.
113 ///
114 /// Opens the file that is specified by filename.
115 /// Returning true if the file was opened successfully; false otherwise.
116 ///
117 ARCH_API FILE*
118 ArchOpenFile(char const* fileName, char const* mode);
119 
120 #if defined(ARCH_OS_WINDOWS)
121 # define ArchChmod(path, mode) _chmod(path, mode)
122 #else
123 # define ArchChmod(path, mode) chmod(path, mode)
124 #endif
125 
126 #if defined(ARCH_OS_WINDOWS)
127 # define ArchCloseFile(fd) _close(fd)
128 #else
129 # define ArchCloseFile(fd) close(fd)
130 #endif
131 
132 #if defined(ARCH_OS_WINDOWS)
133 # define ArchUnlinkFile(path) _unlink(path)
134 #else
135 # define ArchUnlinkFile(path) unlink(path)
136 #endif
137 
138 #if defined(ARCH_OS_WINDOWS)
139  ARCH_API int ArchWindowsFileAccess(const char* path, uint32_t dwAccessMask);
140  ARCH_API int ArchFileAccess(const char* path, int mode);
141 #else
142 # define ArchFileAccess(path, mode) access(path, mode)
143 #endif
144 
145 #if defined(ARCH_OS_WINDOWS)
146 # define ArchFdOpen(fd, mode) _fdopen(fd, mode)
147 #else
148 # define ArchFdOpen(fd, mode) fdopen(fd, mode)
149 #endif
150 
151 #if defined(ARCH_OS_WINDOWS)
152 # define ArchFileNo(stream) _fileno(stream)
153 #else
154 # define ArchFileNo(stream) fileno(stream)
155 #endif
156 
157 #if defined(ARCH_OS_WINDOWS)
158 # define ArchFileIsaTTY(stream) _isatty(stream)
159 #else
160 # define ArchFileIsaTTY(stream) isatty(stream)
161 #endif
162 
163 #if defined(ARCH_OS_WINDOWS)
164  ARCH_API int ArchRmDir(const char* path);
165 #else
166 # define ArchRmDir(path) rmdir(path)
167 #endif
168 
169 /// Return the length of a file in bytes.
170 ///
171 /// Returns -1 if the file cannot be opened/read.
172 ARCH_API int64_t ArchGetFileLength(const char* fileName);
173 ARCH_API int64_t ArchGetFileLength(FILE *file);
174 
175 /// Return a filename for this file, if one can be obtained. Note that there
176 /// are many reasons why it may be impossible to obtain a filename, even for an
177 /// opened FILE *. Whenever possible avoid using this function and instead
178 /// store the filename for future use.
179 ARCH_API std::string ArchGetFileName(FILE *file);
180 
181 /// Returns true if the data in \c stat struct \p st indicates that the target
182 /// file or directory is writable.
183 ///
184 /// This returns true if the struct pointer is valid, and the stat indicates
185 /// the target is writable by the effective user, effective group, or all
186 /// users.
188 
189 /// Returns the modification time (mtime) in seconds for a file.
190 ///
191 /// This function stores the modification time with as much precision as is
192 /// available in the stat structure for the current platform in \p time and
193 /// returns \c true on success, otherwise just returns \c false.
194 ARCH_API bool ArchGetModificationTime(const char* pathname, double* time);
195 
196 /// Returns the modification time (mtime) in seconds from the stat struct.
197 ///
198 /// This function returns the modification time with as much precision as is
199 /// available in the stat structure for the current platform.
201 
202 /// Normalizes the specified path, eliminating double slashes, etc.
203 ///
204 /// This canonicalizes paths, removing any double slashes, and eliminiating
205 /// '.', and '..' components of the path. This emulates the behavior of
206 /// os.path.normpath in Python.
207 ///
208 /// On Windows, all backslashes are converted to forward slashes and drive
209 /// specifiers (e.g., "C:") are lower-cased. If \p stripDriveSpecifier
210 /// is \c true, these drive specifiers are removed from the path.
211 ARCH_API std::string ArchNormPath(const std::string& path,
212  bool stripDriveSpecifier = false);
213 
214 /// Returns the canonical absolute path of the specified filename.
215 ///
216 /// This makes the specified path absolute, by prepending the current working
217 /// directory. If the path is already absolute, it is returned unmodified.
218 ARCH_API std::string ArchAbsPath(const std::string& path);
219 
220 /// Returns the permissions mode (mode_t) for the given pathname.
221 ///
222 /// This function stats the given pathname and returns the permissions flags
223 /// for it and returns true. If the stat fails, returns false.
224 ///
225 ARCH_API bool ArchGetStatMode(const char *pathname, int *mode);
226 
227 /// Return the path to a temporary directory for this platform.
228 ///
229 /// The returned temporary directory will be a location that will normally
230 /// be cleaned out on a reboot. This is /var/tmp on Linux machines (for
231 /// legacy reasons), but /tmp on Darwin machines (/var/tmp on Darwin is
232 /// specified as a location where files are kept between system reboots -
233 /// see "man hier"). The returned string will not have a trailing slash.
234 ///
235 /// This routine is threadsafe and will not perform any memory allocations.
236 ARCH_API const char *ArchGetTmpDir();
237 
238 /// Make a temporary file name, in a system-determined temporary directory.
239 ///
240 /// The result returned has the form TMPDIR/prefix.pid[.n]suffix where TMPDIR
241 /// is a system-determined temporary directory (typically /tmp or /usr/tmp),
242 /// pid is the process id of the process, and the optional .n records the
243 /// number of times this function has been called by a process (and is ommited
244 /// the first time this function is called).
245 ///
246 /// The call is threadsafe.
247 ///
248 /// \warning This call opens a security hole because of the race between
249 /// choosing the name and opening the file. This call should be avoided in
250 /// favor of \c ArchMakeTmpFile().
251 ARCH_API
252 std::string ArchMakeTmpFileName(const std::string& prefix,
253  const std::string& suffix = std::string());
254 
255 /// Create a temporary file, in a system-determined temporary directory.
256 ///
257 /// The result returned has the form TMPDIR/prefix.XXXXXX where TMPDIR is a
258 /// system-determined temporary directory (typically /tmp or /usr/tmp) and
259 /// XXXXXX is a unique suffix. Returns the file descriptor of the new file
260 /// and, if pathname isn't NULL, returns the full path to the file in
261 /// pathname. Returns -1 on failure and errno is set.
262 ///
263 /// The call is threadsafe.
264 ARCH_API
265 int ArchMakeTmpFile(const std::string& prefix, std::string* pathname = 0);
266 
267 /// Create a temporary file, in a given temporary directory.
268 ///
269 /// The result returned has the form TMPDIR/prefix.XXXXXX where TMPDIR is the
270 /// given temporary directory and XXXXXX is a unique suffix. Returns the file
271 /// descriptor of the new file and, if pathname isn't NULL, returns the full
272 /// path to the file in pathname. Returns -1 on failure and errno is set.
273 ///
274 /// The call is threadsafe.
275 ARCH_API
276 int ArchMakeTmpFile(const std::string& tmpdir,
277  const std::string& prefix, std::string* pathname = 0);
278 
279 /// Create a temporary sub-direcrory, in a given temporary directory.
280 ///
281 /// The result returned has the form TMPDIR/prefix.XXXXXX/ where TMPDIR is the
282 /// given temporary directory and XXXXXX is a unique suffix. Returns the the
283 /// full path to the subdir in pathname. Returns empty string on failure and
284 /// errno is set.
285 ///
286 /// The call is threadsafe.
287 ARCH_API
288 std::string ArchMakeTmpSubdir(const std::string& tmpdir,
289  const std::string& prefix);
290 
291 // Helper 'deleter' for use with std::unique_ptr for file mappings.
293  Arch_Unmapper() : _length(~0) {}
294  explicit Arch_Unmapper(size_t length) : _length(length) {}
295  ARCH_API void operator()(char *mapStart) const;
296  ARCH_API void operator()(char const *mapStart) const;
297  size_t GetLength() const { return _length; }
298 private:
299  size_t _length;
300 };
301 
302 /// ArchConstFileMapping and ArchMutableFileMapping are std::unique_ptr<char
303 /// const *, ...> and std::unique_ptr<char *, ...> respectively. The functions
304 /// ArchMapFileReadOnly() and ArchMapFileReadWrite() return them and provide
305 /// access to memory-mapped file contents.
306 using ArchConstFileMapping = std::unique_ptr<char const, Arch_Unmapper>;
307 using ArchMutableFileMapping = std::unique_ptr<char, Arch_Unmapper>;
308 
309 /// Return the length of an ArchConstFileMapping.
310 inline size_t
312  return m.get_deleter().GetLength();
313 }
314 
315 /// Return the length of an ArchMutableFileMapping.
316 inline size_t
318  return m.get_deleter().GetLength();
319 }
320 
321 /// Privately map the passed \p file into memory and return a unique_ptr to the
322 /// read-only mapped contents. The contents may not be modified. If mapping
323 /// fails, return a null unique_ptr and if errMsg is not null fill it with
324 /// information about the failure.
325 ARCH_API
327 ArchMapFileReadOnly(FILE *file, std::string *errMsg=nullptr);
328 
329 /// \overload
330 ARCH_API
332 ArchMapFileReadOnly(std::string const& path, std::string *errMsg=nullptr);
333 
334 /// Privately map the passed \p file into memory and return a unique_ptr to the
335 /// copy-on-write mapped contents. If modified, the affected pages are
336 /// dissociated from the underlying file and become backed by the system's swap
337 /// or page-file storage. Edits are not carried through to the underlying file.
338 /// If mapping fails, return a null unique_ptr and if errMsg is not null fill it
339 /// with information about the failure.
340 ARCH_API
342 ArchMapFileReadWrite(FILE *file, std::string *errMsg=nullptr);
343 
344 /// \overload
345 ARCH_API
347 ArchMapFileReadWrite(std::string const& path, std::string *errMsg=nullptr);
348 
350  ArchMemAdviceNormal, // Treat range with default behavior.
351  ArchMemAdviceWillNeed, // OS may prefetch this range.
352  ArchMemAdviceDontNeed, // OS may free resources related to this range.
353  ArchMemAdviceRandomAccess, // Prefetching may not be beneficial.
354 };
355 
356 /// Advise the OS regarding how the application intends to access a range of
357 /// memory. See ArchMemAdvice. This is primarily useful for mapped file
358 /// regions. This call does not change program semantics. It is only an
359 /// optimization hint to the OS, and may be a no-op on some systems.
360 ARCH_API
361 void ArchMemAdvise(void const *addr, size_t len, ArchMemAdvice adv);
362 
363 /// Report whether or not the mapped virtual memory pages starting at \p addr
364 /// for \p len bytes are resident in RAM. Pages that are resident will not,
365 /// when accessed, cause a page fault while those that are not will. Return
366 /// true on success and false in case of an error. The \p addr argument must be
367 /// a multiple of ArchGetPageSize(). The \p len argument need not be a multiple
368 /// of the page size; it will be rounded up to the next page boundary. Fill
369 /// \p pageMap with 0s for pages not resident in memory and 1s for pages that
370 /// are. The \p pageMap argument must therefore point to at least (\p len +
371 /// ArchGetPageSize()-1)/ArchGetPageSize() bytes.
372 ///
373 /// Note that currently this function is only implemented on Linux and Darwin.
374 /// On Windows it currently always returns false.
375 ARCH_API
376 bool
378  void const *addr, size_t len, unsigned char *pageMap);
379 
380 /// Read up to \p count bytes from \p offset in \p file into \p buffer. The
381 /// file position indicator for \p file is not changed. Return the number of
382 /// bytes read, or zero if at end of file. Return -1 in case of an error, with
383 /// errno set appropriately.
384 ARCH_API
385 int64_t ArchPRead(FILE *file, void *buffer, size_t count, int64_t offset);
386 
387 /// Write up to \p count bytes from \p buffer to \p file at \p offset. The file
388 /// position indicator for \p file is not changed. Return the number of bytes
389 /// written, possibly zero if none written. Return -1 in case of an error, with
390 /// errno set appropriately.
391 ARCH_API
392 int64_t ArchPWrite(FILE *file, void const *bytes, size_t count, int64_t offset);
393 
394 /// Returns the value of the symbolic link at \p path. Returns the empty
395 /// string on error or if \p path does not refer to a symbolic link.
396 ARCH_API
397 std::string ArchReadLink(const char* path);
398 
400  ArchFileAdviceNormal, // Treat range with default behavior.
401  ArchFileAdviceWillNeed, // OS may prefetch this range.
402  ArchFileAdviceDontNeed, // OS may free resources related to this range.
403  ArchFileAdviceRandomAccess, // Prefetching may not be beneficial.
404 };
405 
406 /// Advise the OS regarding how the application intends to access a range of
407 /// bytes in a file. See ArchFileAdvice. This call does not change program
408 /// semantics. It is only an optimization hint to the OS, and may be a no-op on
409 /// some systems.
410 ARCH_API
411 void ArchFileAdvise(FILE *file, int64_t offset, size_t count,
412  ArchFileAdvice adv);
413 
414 #if defined(ARCH_OS_WINDOWS)
415 
416 /// Converts UTF-16 windows string to regular std::string - Windows-only
417 inline std::string ArchWindowsUtf16ToUtf8(const std::wstring &wstr)
418 {
419  if (wstr.empty()) return std::string();
420  // first call is only to get required size for string
421  int size = WideCharToMultiByte(
422  CP_UTF8, 0, wstr.data(), (int)wstr.size(), NULL, 0, NULL, NULL);
423  if (size == 0) return std::string();
424  std::string str(size, 0);
425  if (WideCharToMultiByte(CP_UTF8, 0, wstr.data(), (int)wstr.size(),
426  &str[0], size, NULL, NULL) == 0) {
427  return std::string();
428  }
429  return str;
430 }
431 
432 /// Converts regular std::string to UTF-16 windows string - Windows-only
433 inline std::wstring ArchWindowsUtf8ToUtf16(const std::string &str)
434 {
435  if (str.empty()) return std::wstring();
436  // first call is only to get required size for wstring
437  int size = MultiByteToWideChar(
438  CP_UTF8, 0, str.data(), (int)str.size(), NULL, 0);
439  if (size == 0) return std::wstring();
440  std::wstring wstr(size, 0);
441  if(MultiByteToWideChar(
442  CP_UTF8, 0, str.data(), (int)str.size(), &wstr[0], size) == 0) {
443  return std::wstring();
444  }
445  return wstr;
446 }
447 
448 #endif
449 
450 ///@}
451 
453 
454 #endif // PXR_BASE_ARCH_FILE_SYSTEM_H
ArchFileAdvice
Definition: fileSystem.h:399
typedef int(APIENTRYP RE_PFNGLXSWAPINTERVALSGIPROC)(int)
ARCH_API FILE * ArchOpenFile(char const *fileName, char const *mode)
ARCH_API void ArchMemAdvise(void const *addr, size_t len, ArchMemAdvice adv)
GT_API const UT_StringHolder time
GLsizei const GLchar *const * path
Definition: glcorearb.h:3341
ARCH_API std::string ArchAbsPath(const std::string &path)
ARCH_API void ArchFileAdvise(FILE *file, int64_t offset, size_t count, ArchFileAdvice adv)
ARCH_API std::string ArchNormPath(const std::string &path, bool stripDriveSpecifier=false)
GLuint GLsizei GLsizei * length
Definition: glcorearb.h:795
ARCH_API ArchConstFileMapping ArchMapFileReadOnly(FILE *file, std::string *errMsg=nullptr)
GLuint buffer
Definition: glcorearb.h:660
std::unique_ptr< char const, Arch_Unmapper > ArchConstFileMapping
Definition: fileSystem.h:306
Arch_Unmapper(size_t length)
Definition: fileSystem.h:294
ARCH_API ArchMutableFileMapping ArchMapFileReadWrite(FILE *file, std::string *errMsg=nullptr)
ARCH_API const char * ArchGetTmpDir()
ARCH_API int ArchMakeTmpFile(const std::string &prefix, std::string *pathname=0)
GLintptr offset
Definition: glcorearb.h:665
std::unique_ptr< char, Arch_Unmapper > ArchMutableFileMapping
Definition: fileSystem.h:307
ARCH_API std::string ArchReadLink(const char *path)
ARCH_API int64_t ArchGetFileLength(const char *fileName)
size_t ArchGetFileMappingLength(ArchConstFileMapping const &m)
Return the length of an ArchConstFileMapping.
Definition: fileSystem.h:311
ARCH_API bool ArchGetStatMode(const char *pathname, int *mode)
GLenum mode
Definition: glcorearb.h:99
ARCH_API bool ArchStatIsWritable(const ArchStatType *st)
GLsizeiptr size
Definition: glcorearb.h:664
struct stat ArchStatType
Definition: fileSystem.h:104
ARCH_API bool ArchQueryMappedMemoryResidency(void const *addr, size_t len, unsigned char *pageMap)
GT_API const UT_StringHolder st
PXR_NAMESPACE_CLOSE_SCOPE PXR_NAMESPACE_OPEN_SCOPE
Definition: path.h:1425
#define ArchRmDir(path)
Definition: fileSystem.h:166
#define PXR_NAMESPACE_CLOSE_SCOPE
Definition: pxr.h:74
ARCH_API std::string ArchGetFileName(FILE *file)
#define ARCH_API
Definition: api.h:23
#define ArchFileAccess(path, mode)
Definition: fileSystem.h:142
ARCH_API int64_t ArchPRead(FILE *file, void *buffer, size_t count, int64_t offset)
ARCH_API void operator()(char *mapStart) const
size_t GetLength() const
Definition: fileSystem.h:297
ArchMemAdvice
Definition: fileSystem.h:349
ARCH_API std::string ArchMakeTmpSubdir(const std::string &tmpdir, const std::string &prefix)
ARCH_API int64_t ArchPWrite(FILE *file, void const *bytes, size_t count, int64_t offset)
GLint GLsizei count
Definition: glcorearb.h:405
Definition: format.h:4365
ARCH_API bool ArchGetModificationTime(const char *pathname, double *time)
ARCH_API std::string ArchMakeTmpFileName(const std::string &prefix, const std::string &suffix=std::string())