Files
c3c/lib/std/io/os/rmtree.c3

68 lines
1.7 KiB
Plaintext

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)!;
}