123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244 |
- #include "il2cpp-config.h"
- #if IL2CPP_TARGET_POSIX && !RUNTIME_TINY && !IL2CPP_USE_PLATFORM_SPECIFIC_DIRECTORY
- #include "os/Directory.h"
- #include "os/ErrorCodes.h"
- #include "os/File.h"
- #include "os/Posix/Error.h"
- #include "utils/DirectoryUtils.h"
- #include "utils/Memory.h"
- #include "utils/PathUtils.h"
- #include "utils/StringUtils.h"
- #include <errno.h>
- #include <dirent.h>
- #include <stdint.h>
- #include <stdlib.h>
- #include <unistd.h>
- #if IL2CPP_TARGET_QNX
- #include <errno.h>
- #else
- #include <sys/errno.h>
- #endif
- #include <sys/stat.h>
- #include <sys/types.h>
- namespace il2cpp
- {
- namespace os
- {
- std::string Directory::GetCurrent(int *error)
- {
- char buf[PATH_MAX + 1];
- // Note: not all implementations would allocate a buffer when passing 0 to getcwd, as we used to do.
- // this does *not* seem to be part of the POSIX spec:
- // http://pubs.opengroup.org/onlinepubs/000095399/functions/getcwd.html
- char* cwd = getcwd(buf, PATH_MAX + 1);
- if (cwd == NULL)
- {
- *error = FileErrnoToErrorCode(errno);
- return std::string();
- }
- std::string directory(cwd);
- *error = kErrorCodeSuccess;
- return directory;
- }
- bool Directory::SetCurrent(const std::string& path, int *error)
- {
- const int ret = chdir(path.c_str());
- if (ret == -1)
- {
- *error = FileErrnoToErrorCode(errno);
- return false;
- }
- *error = kErrorCodeSuccess;
- return true;
- }
- bool Directory::Create(const std::string& path, int *error)
- {
- const int ret = mkdir(path.c_str(), 0777);
- if (ret == -1)
- {
- *error = PathErrnoToErrorCode(path, errno);
- return false;
- }
- *error = kErrorCodeSuccess;
- return true;
- }
- bool Directory::Remove(const std::string& path, int *error)
- {
- const int ret = rmdir(path.c_str());
- if (ret == -1)
- {
- *error = PathErrnoToErrorCode(path, errno);
- return false;
- }
- *error = kErrorCodeSuccess;
- return true;
- }
- static void DirectoryGlob(DIR *dir, const std::string& pattern, std::set<std::string>& result)
- {
- if (pattern.empty())
- return;
- std::string matchPattern = il2cpp::utils::CollapseAdjacentStars(pattern);
- struct dirent *entry;
- while ((entry = readdir(dir)) != NULL)
- {
- const std::string filename(entry->d_name);
- if (!il2cpp::utils::Match(filename, matchPattern))
- continue;
- result.insert(filename);
- }
- }
- static bool DirectoryGlob(const std::string& directoryPath, const std::string& pattern, std::set<std::string>& result, int* error)
- {
- DIR* dir = opendir(directoryPath.c_str());
- if (dir == NULL)
- {
- *error = PathErrnoToErrorCode(directoryPath, errno);
- return false;
- }
- DirectoryGlob(dir, pattern, result);
- closedir(dir);
- return true;
- }
- std::set<std::string> Directory::GetFileSystemEntries(const std::string& path, const std::string& pathWithPattern, int32_t attributes, int32_t mask, int* error)
- {
- const std::string directoryPath(il2cpp::utils::PathUtils::DirectoryName(pathWithPattern));
- const std::string pattern(il2cpp::utils::PathUtils::Basename(pathWithPattern));
- std::set<std::string> globResult;
- if (DirectoryGlob(directoryPath, pattern, globResult, error) == false)
- return std::set<std::string>();
- std::set<std::string> result;
- for (std::set<std::string>::const_iterator it = globResult.begin(), end = globResult.end(); it != end; ++it)
- {
- const std::string& filename = *it;
- if (filename == "." || filename == "..")
- continue;
- const std::string path(directoryPath + IL2CPP_DIR_SEPARATOR + filename);
- int attributeError;
- const int32_t pathAttributes = static_cast<int32_t>(File::GetFileAttributes(path, &attributeError));
- if (attributeError != kErrorCodeSuccess)
- continue;
- if ((pathAttributes & mask) == attributes)
- result.insert(path);
- }
- *error = kErrorCodeSuccess;
- return result;
- }
- Directory::FindHandle::FindHandle(const utils::StringView<Il2CppNativeChar>& searchPathWithPattern) :
- osHandle(NULL),
- handleFlags(os::kNoFindHandleFlags)
- {
- directoryPath = il2cpp::utils::PathUtils::DirectoryName(searchPathWithPattern);
- pattern = il2cpp::utils::PathUtils::Basename(searchPathWithPattern);
- pattern = il2cpp::utils::CollapseAdjacentStars(pattern);
- }
- Directory::FindHandle::~FindHandle()
- {
- IL2CPP_ASSERT(osHandle == NULL);
- }
- int32_t Directory::FindHandle::CloseOSHandle()
- {
- int32_t result = os::kErrorCodeSuccess;
- if (osHandle != NULL)
- {
- int32_t ret = closedir(static_cast<DIR*>(osHandle));
- if (ret != 0)
- result = FileErrnoToErrorCode(errno);
- osHandle = NULL;
- }
- return result;
- }
- os::ErrorCode Directory::FindFirstFile(FindHandle* findHandle, const utils::StringView<Il2CppNativeChar>& searchPathWithPattern, Il2CppNativeString* resultFileName, int32_t* resultAttributes)
- {
- DIR* dir = opendir(findHandle->directoryPath.c_str());
- if (dir == NULL)
- return PathErrnoToErrorCode(findHandle->directoryPath, errno);
- findHandle->SetOSHandle(dir);
- return FindNextFile(findHandle, resultFileName, resultAttributes);
- }
- os::ErrorCode Directory::FindNextFile(FindHandle* findHandle, Il2CppNativeString* resultFileName, int32_t* resultAttributes)
- {
- errno = 0;
- dirent* entry;
- while ((entry = readdir(static_cast<DIR*>(findHandle->osHandle))) != NULL)
- {
- const Il2CppNativeString filename(entry->d_name);
- if (il2cpp::utils::Match(filename, findHandle->pattern))
- {
- const Il2CppNativeString path = utils::PathUtils::Combine(findHandle->directoryPath, filename);
- int attributeError;
- const int32_t pathAttributes = static_cast<int32_t>(File::GetFileAttributes(path, &attributeError));
- if (attributeError == kErrorCodeSuccess)
- {
- *resultFileName = filename;
- *resultAttributes = pathAttributes;
- return os::kErrorCodeSuccess;
- }
- }
- }
- if (errno != 0)
- return FileErrnoToErrorCode(errno);
- return os::kErrorCodeNoMoreFiles;
- }
- int32_t Directory::CloseOSFindHandleDirectly(intptr_t osHandle)
- {
- IL2CPP_ASSERT(0 && "This function should be called for Windows only.");
- return 0;
- }
- }
- }
- #endif
|