| Line | Branch | Exec | Source |
|---|---|---|---|
| 1 | // ====================================================================== | ||
| 2 | // \title Os/Posix/FileSystem.cpp | ||
| 3 | // \brief Posix implementation for Os::FileSystem | ||
| 4 | // ====================================================================== | ||
| 5 | #include "Os/Posix/FileSystem.hpp" | ||
| 6 | #include "Os/Posix/error.hpp" | ||
| 7 | |||
| 8 | #include <dirent.h> | ||
| 9 | #ifndef TGT_OS_TYPE_VXWORKS | ||
| 10 | #include <sys/statvfs.h> | ||
| 11 | #endif | ||
| 12 | #include <sys/stat.h> | ||
| 13 | #include <unistd.h> | ||
| 14 | #include <cstdio> | ||
| 15 | |||
| 16 | #include <cerrno> | ||
| 17 | |||
| 18 | namespace Os { | ||
| 19 | namespace Posix { | ||
| 20 | namespace FileSystem { | ||
| 21 | |||
| 22 | 9 | PosixFileSystem::Status PosixFileSystem::_removeDirectory(const char* path) { | |
| 23 | 9 | Status status = OP_OK; | |
| 24 |
2/4✗ Branch 0 not taken.
✓ Branch 1 taken 9 times.
✗ Branch 3 not taken.
✓ Branch 4 taken 9 times.
|
9 | if (::rmdir(path) == -1) { |
| 25 | ✗ | status = errno_to_filesystem_status(errno); | |
| 26 | } | ||
| 27 | 9 | return status; | |
| 28 | } | ||
| 29 | |||
| 30 | 10 | PosixFileSystem::Status PosixFileSystem::_removeFile(const char* path) { | |
| 31 | 10 | Status status = OP_OK; | |
| 32 |
3/4✗ Branch 0 not taken.
✓ Branch 1 taken 10 times.
✓ Branch 3 taken 6 times.
✓ Branch 4 taken 4 times.
|
10 | if (::unlink(path) == -1) { |
| 33 | 6 | status = errno_to_filesystem_status(errno); | |
| 34 | } | ||
| 35 | 10 | return status; | |
| 36 | } | ||
| 37 | |||
| 38 | ✗ | PosixFileSystem::Status PosixFileSystem::_rename(const char* originPath, const char* destPath) { | |
| 39 | ✗ | Status status = OP_OK; | |
| 40 | ✗ | if (::rename(originPath, destPath) == -1) { | |
| 41 | ✗ | status = errno_to_filesystem_status(errno); | |
| 42 | } | ||
| 43 | ✗ | return status; | |
| 44 | } | ||
| 45 | |||
| 46 | 2 | PosixFileSystem::Status PosixFileSystem::_getWorkingDirectory(char* path, FwSizeType bufferSize) { | |
| 47 | 2 | Status status = OP_OK; | |
| 48 | 2 | const char* cwd = ::getcwd(path, static_cast<size_t>(bufferSize)); | |
| 49 |
1/2✗ Branch 0 not taken.
✓ Branch 1 taken 2 times.
|
2 | if (cwd == nullptr) { |
| 50 | ✗ | status = errno_to_filesystem_status(errno); | |
| 51 | } | ||
| 52 | 2 | return status; | |
| 53 | } | ||
| 54 | |||
| 55 | ✗ | PosixFileSystem::Status PosixFileSystem::_changeWorkingDirectory(const char* path) { | |
| 56 | ✗ | Status status = OP_OK; | |
| 57 | ✗ | if (::chdir(path) == -1) { | |
| 58 | ✗ | status = errno_to_filesystem_status(errno); | |
| 59 | } | ||
| 60 | ✗ | return status; | |
| 61 | } | ||
| 62 | |||
| 63 | ✗ | PosixFileSystem::Status PosixFileSystem::_getFreeSpace(const char* path, | |
| 64 | FwSizeType& totalBytes, | ||
| 65 | FwSizeType& freeBytes) { | ||
| 66 | #ifdef TGT_OS_TYPE_VXWORKS | ||
| 67 | return Status::NOT_SUPPORTED; | ||
| 68 | #else | ||
| 69 | ✗ | Status stat = OP_OK; | |
| 70 | static_assert(std::numeric_limits<FwSizeType>::max() >= std::numeric_limits<fsblkcnt_t>::max(), | ||
| 71 | "FwSizeType must be able to hold fsblkcnt_t"); | ||
| 72 | static_assert(std::numeric_limits<FwSizeType>::min() <= std::numeric_limits<fsblkcnt_t>::min(), | ||
| 73 | "FwSizeType must be able to hold fsblkcnt_t"); | ||
| 74 | static_assert(std::numeric_limits<FwSizeType>::max() >= std::numeric_limits<unsigned long>::max(), | ||
| 75 | "FwSizeType must be able to hold unsigned long"); | ||
| 76 | ✗ | struct statvfs fsStat; | |
| 77 | ✗ | int ret = statvfs(path, &fsStat); | |
| 78 | ✗ | if (ret) { | |
| 79 | ✗ | return errno_to_filesystem_status(errno); | |
| 80 | } | ||
| 81 | |||
| 82 | ✗ | const FwSizeType block_size = static_cast<FwSizeType>(fsStat.f_frsize); | |
| 83 | ✗ | const FwSizeType free_blocks = static_cast<FwSizeType>(fsStat.f_bfree); | |
| 84 | ✗ | const FwSizeType total_blocks = static_cast<FwSizeType>(fsStat.f_blocks); | |
| 85 | |||
| 86 | // Guard against divide-by-zero if filesystem reports invalid block size | ||
| 87 | ✗ | if (block_size == 0) { | |
| 88 | ✗ | return OTHER_ERROR; | |
| 89 | } | ||
| 90 | |||
| 91 | // Check for overflow in multiplication | ||
| 92 | ✗ | if (free_blocks > (std::numeric_limits<FwSizeType>::max() / block_size) || | |
| 93 | ✗ | total_blocks > (std::numeric_limits<FwSizeType>::max() / block_size)) { | |
| 94 | ✗ | return OVERFLOW_ERROR; | |
| 95 | } | ||
| 96 | ✗ | freeBytes = free_blocks * block_size; | |
| 97 | ✗ | totalBytes = total_blocks * block_size; | |
| 98 | ✗ | return stat; | |
| 99 | #endif | ||
| 100 | } | ||
| 101 | |||
| 102 | ✗ | FileSystemHandle* PosixFileSystem::getHandle() { | |
| 103 | ✗ | return &this->m_handle; | |
| 104 | } | ||
| 105 | |||
| 106 | ✗ | PosixFileSystem::Status PosixFileSystem::_getPathType(const char* path, PathType& pathType) { | |
| 107 | ✗ | FW_ASSERT(path != nullptr); | |
| 108 | ✗ | struct stat path_stat; | |
| 109 | ✗ | const I32 status = lstat(path, &path_stat); | |
| 110 | ✗ | if (status == 0) { | |
| 111 | ✗ | if (S_ISDIR(path_stat.st_mode)) { | |
| 112 | ✗ | pathType = PathType::DIRECTORY; | |
| 113 | ✗ | } else if (S_ISREG(path_stat.st_mode)) { | |
| 114 | ✗ | pathType = PathType::FILE; | |
| 115 | } else { | ||
| 116 | ✗ | pathType = PathType::OTHER; | |
| 117 | } | ||
| 118 | ✗ | return Status::OP_OK; | |
| 119 | } else { | ||
| 120 | ✗ | return errno_to_filesystem_status(errno); | |
| 121 | } | ||
| 122 | } | ||
| 123 | |||
| 124 | } // namespace FileSystem | ||
| 125 | } // namespace Posix | ||
| 126 | } // namespace Os | ||
| 127 |