module std::io::os @if(env::POSIX); import std::io, std::os, libc; <* @require dir.str_view().len > 0 *> fn void? native_rmtree(Path dir) { @pool() { DIRPtr directory = posix::opendir(dir.str_view().zstr_tcopy()); defer if (directory) posix::closedir(directory); if (!directory) return path::is_dir(dir) ? io::CANNOT_READ_DIR~ : io::FILE_NOT_DIR~; Posix_dirent* entry; while ((entry = posix::readdir(directory))) { @pool() { String name = ((ZString)&entry.name).str_view(); if (!name || name == "." || name == "..") continue; Path new_path = dir.tappend(name)!; if (entry.d_type == posix::DT_DIR) { native_rmtree(new_path)!; continue; } if (libc::remove(new_path.str_view().zstr_tcopy())) { // TODO improve return io::GENERAL_ERROR~; } }; } os::native_rmdir(dir)!; }; } module std::io::os @if(env::WIN32); import std::io, std::time, std::os; fn void? native_rmtree(Path path) { Win32_WIN32_FIND_DATAW find_data; String s = path.str_view().tconcat("\\*"); Win32_HANDLE find = win32::findFirstFileW(s.to_temp_utf16(), &find_data)!; if (find == win32::INVALID_HANDLE_VALUE) return io::CANNOT_READ_DIR~; defer win32::findClose(find); do { @pool() { String filename = string::tfrom_wstring((WString)&find_data.cFileName)!; if (filename == "." || filename == "..") continue; Path file_path = path.tappend(filename)!; if (find_data.dwFileAttributes & win32::FILE_ATTRIBUTE_DIRECTORY) { native_rmtree(file_path)!; } else { win32::deleteFileW(file_path.str_view().to_temp_wstring()!!); } }; } while (win32::findNextFileW(find, &find_data) != 0); os::native_rmdir(path)!; }