diff options
Diffstat (limited to 'source')
| -rw-r--r-- | source/core/slang-io.cpp | 57 | ||||
| -rw-r--r-- | source/core/slang-io.h | 5 |
2 files changed, 62 insertions, 0 deletions
diff --git a/source/core/slang-io.cpp b/source/core/slang-io.cpp index ffbb5fa98..dd390fc28 100644 --- a/source/core/slang-io.cpp +++ b/source/core/slang-io.cpp @@ -17,6 +17,7 @@ #ifdef _WIN32 # include <direct.h> # include <windows.h> +# include <shellapi.h> #endif #if defined(__linux__) || defined(__CYGWIN__) || SLANG_APPLE_FAMILY @@ -27,6 +28,7 @@ # include <dirent.h> # include <sys/stat.h> # include <sys/file.h> +# include <ftw.h> // for nftw #endif #if SLANG_APPLE_FAMILY @@ -777,6 +779,61 @@ namespace Slang #endif } + /* static */SlangResult Path::removeNonEmpty(const String& path) + { + if (File::exists(path) == false) + { + return SLANG_OK; + } + + StringBuilder msgBuilder; + // Path::remove() doesn't support remove a non-empty directory, so we need to implement + // a simple function to remove the directory recursively. +#ifdef _WIN32 + // https://learn.microsoft.com/en-us/windows/win32/api/shellapi/nf-shellapi-shfileoperationa + // Note: the fromPath requires a double-null-terminated string. + String newPath = path; + newPath.append('\0'); + SHFILEOPSTRUCTA file_op = { + NULL, + FO_DELETE, + newPath.begin(), + nullptr, + FOF_NOCONFIRMATION | + FOF_NOERRORUI | + FOF_SILENT, + false, + 0, + nullptr }; + int ret = SHFileOperationA(&file_op); + if (ret) + { + return SLANG_FAIL; + } +#else + auto unlink_cb = [](const char* fpath, const struct stat* sb, int typeflag, struct FTW* ftwbuf) -> int + { + SLANG_UNUSED(sb) + SLANG_UNUSED(typeflag) + SLANG_UNUSED(ftwbuf) + int rv = ::remove(fpath); + if (rv) + { + perror(fpath); + } + return rv; + }; + // https://linux.die.net/man/3/nftw + int ret = ::nftw(path.begin(), unlink_cb, 64, FTW_DEPTH | FTW_PHYS); + if (ret) + { + return SLANG_FAIL; + } +#endif + + return SLANG_OK; + } + #if defined(_WIN32) /* static */SlangResult Path::find(const String& directoryPath, const char* pattern, Visitor* visitor) { diff --git a/source/core/slang-io.h b/source/core/slang-io.h index 763907c98..676635a36 100644 --- a/source/core/slang-io.h +++ b/source/core/slang-io.h @@ -217,6 +217,11 @@ namespace Slang /// @return SLANG_OK if file or directory is removed static SlangResult remove(const String& path); + /// Remove a file or directory at specified path. The directory can be non-empty. + /// @param path + /// @return SLANG_OK if file or directory is removed + static SlangResult removeNonEmpty(const String& path); + static bool equals(String path1, String path2); /// Turn `path` into a relative path from base. |
