F´ Flight Software - C/C++ Documentation  devel
A framework for building embedded system applications to NASA flight quality standards.
Directory.cpp
Go to the documentation of this file.
1 // ======================================================================
2 // \title Os/Posix/Directory.cpp
3 // \brief Posix implementation for Os::Directory
4 // ======================================================================
5 #include <sys/stat.h>
6 #include <cerrno>
7 #include <cstring>
8 
9 #include <Fw/Types/Assert.hpp>
10 #include <Fw/Types/StringUtils.hpp>
11 #include <Os/Posix/Directory.hpp>
12 #include <Os/Posix/error.hpp>
13 
14 namespace Os {
15 namespace Posix {
16 namespace Directory {
17 
19 
21  return &this->m_handle;
22 }
23 
25  Status status = Status::OP_OK;
26 
27  // If one of the CREATE mode, attempt to create the directory
28  if (mode == OpenMode::CREATE_EXCLUSIVE || mode == OpenMode::CREATE_IF_MISSING) {
29  if (::mkdir(path, S_IRWXU) == -1) {
30  status = errno_to_directory_status(errno);
31  // If error is not ALREADY_EXISTS, return the error
32  // If any error and mode CREATE_EXCLUSIVE, return the error
33  // Else, we keep going with OP_OK
34  if (status != Status::ALREADY_EXISTS || mode == OpenMode::CREATE_EXCLUSIVE) {
35  return status;
36  } else {
37  status = Status::OP_OK;
38  }
39  }
40  }
41 
42  DIR* dir = ::opendir(path);
43 
44  if (dir == nullptr) {
45  status = errno_to_directory_status(errno);
46  }
47 
48  this->m_handle.m_dir_descriptor = dir;
49  return status;
50 }
51 
53  Status status = Status::OP_OK;
54  // no errors defined in man page for rewinddir
55  ::rewinddir(this->m_handle.m_dir_descriptor);
56  return status;
57 }
58 
59 PosixDirectory::Status PosixDirectory::read(char* fileNameBuffer, FwSizeType bufSize) {
60  FW_ASSERT(fileNameBuffer);
61 
62  Status status = Status::OP_OK;
63 
64  // Set errno to 0 so we know why we exited readdir
65  // This is recommended by the manual pages (man 3 readdir)
66  errno = 0;
67 
68  struct dirent* direntData = nullptr;
69  while ((direntData = ::readdir(this->m_handle.m_dir_descriptor)) != nullptr) {
70  // Skip . and .. directory entries
71  if ((direntData->d_name[0] == '.' and direntData->d_name[1] == '\0') or
72  (direntData->d_name[0] == '.' and direntData->d_name[1] == '.' and direntData->d_name[2] == '\0')) {
73  continue;
74  } else {
75  (void)Fw::StringUtils::string_copy(fileNameBuffer, direntData->d_name, bufSize);
76  break;
77  }
78  }
79  if (direntData == nullptr) {
80  // loop ended because readdir failed, did it error or did we run out of files?
81  if (errno != 0) {
82  // Only error from readdir is EBADF
83  status = Status::BAD_DESCRIPTOR;
84  } else {
85  status = Status::NO_MORE_FILES;
86  }
87  }
88  return status;
89 }
90 
92  // ::closedir errors if dir descriptor is nullptr
93  if (this->m_handle.m_dir_descriptor != nullptr) {
94  (void)::closedir(this->m_handle.m_dir_descriptor);
95  }
96  this->m_handle.m_dir_descriptor = nullptr;
97 }
98 
99 } // namespace Directory
100 } // namespace Posix
101 } // namespace Os
#define FW_ASSERT(...)
Definition: Assert.hpp:14
PlatformSizeType FwSizeType
Definition: FpConfig.h:35
Directory class.
Definition: Directory.hpp:117
void close() override
Close directory.
Definition: Directory.cpp:91
DirectoryHandle * getHandle() override
return the underlying mutex handle (implementation specific)
Definition: Directory.cpp:20
Status rewind() override
Rewind directory stream.
Definition: Directory.cpp:52
Status read(char *fileNameBuffer, FwSizeType buffSize) override
Get next filename from directory stream.
Definition: Directory.cpp:59
Status open(const char *path, OpenMode mode) override
Open or create a directory.
Definition: Directory.cpp:24
char * string_copy(char *destination, const char *source, FwSizeType num)
copy string with null-termination guaranteed
Definition: StringUtils.cpp:6
@ OP_OK
Operation succeeded.
Definition: Os.hpp:26
Directory::Status errno_to_directory_status(PlatformIntType errno_input)
Definition: error.cpp:106