mirror of
https://github.com/Ed94/Odin.git
synced 2026-07-24 16:37:54 +00:00
Mock out os2.remove_all for Windows
This commit is contained in:
@@ -31,11 +31,11 @@ getwd :: get_working_directory
|
||||
|
||||
@(require_results)
|
||||
get_working_directory :: proc(allocator: runtime.Allocator) -> (dir: string, err: Error) {
|
||||
return _getwd(allocator)
|
||||
return _get_working_directory(allocator)
|
||||
}
|
||||
|
||||
setwd :: set_working_directory
|
||||
|
||||
set_working_directory :: proc(dir: string) -> (err: Error) {
|
||||
return _setwd(dir)
|
||||
return _set_working_directory(dir)
|
||||
}
|
||||
|
||||
@@ -163,7 +163,7 @@ _remove_all :: proc(path: string) -> Error {
|
||||
return _get_platform_error(linux.rmdir(path_cstr))
|
||||
}
|
||||
|
||||
_getwd :: proc(allocator: runtime.Allocator) -> (string, Error) {
|
||||
_get_working_directory :: proc(allocator: runtime.Allocator) -> (string, Error) {
|
||||
// NOTE(tetra): I would use PATH_MAX here, but I was not able to find
|
||||
// an authoritative value for it across all systems.
|
||||
// The largest value I could find was 4096, so might as well use the page size.
|
||||
@@ -183,7 +183,7 @@ _getwd :: proc(allocator: runtime.Allocator) -> (string, Error) {
|
||||
unreachable()
|
||||
}
|
||||
|
||||
_setwd :: proc(dir: string) -> Error {
|
||||
_set_working_directory :: proc(dir: string) -> Error {
|
||||
dir_cstr := temp_cstring(dir) or_return
|
||||
return _get_platform_error(linux.chdir(dir_cstr))
|
||||
}
|
||||
|
||||
@@ -71,18 +71,109 @@ _mkdir_all :: proc(path: string, perm: int) -> Error {
|
||||
}
|
||||
|
||||
_remove_all :: proc(path: string) -> Error {
|
||||
// TODO(bill): _remove_all for windows
|
||||
return nil
|
||||
if path == "" {
|
||||
return nil
|
||||
}
|
||||
|
||||
|
||||
err := remove(path)
|
||||
if err == nil || err == .Not_Exist {
|
||||
return nil
|
||||
}
|
||||
|
||||
TEMP_ALLOCATOR_GUARD()
|
||||
dir, serr := stat_do_not_follow_links(path, temp_allocator())
|
||||
if serr != nil {
|
||||
if serr == .Not_Exist || serr == .Invalid_Dir {
|
||||
return nil
|
||||
}
|
||||
return serr
|
||||
}
|
||||
if dir.type != .Directory {
|
||||
return err
|
||||
}
|
||||
|
||||
err = nil
|
||||
remove_contents: {
|
||||
f: ^File
|
||||
f, err = open(path)
|
||||
if err != nil {
|
||||
if err == .Not_Exist {
|
||||
return nil
|
||||
}
|
||||
return err
|
||||
}
|
||||
|
||||
files, read_err := read_all_directory(f, temp_allocator())
|
||||
for file in files {
|
||||
err1 := remove_all(file.fullpath)
|
||||
if err == nil {
|
||||
err = err1
|
||||
}
|
||||
}
|
||||
close(f)
|
||||
|
||||
if read_err == .EOF {
|
||||
break remove_contents
|
||||
}
|
||||
|
||||
if err == nil {
|
||||
err = read_err
|
||||
}
|
||||
if len(files) == 0 {
|
||||
break remove_contents
|
||||
}
|
||||
}
|
||||
|
||||
err1 := remove(path)
|
||||
if err1 == nil || err1 == .Not_Exist {
|
||||
return nil
|
||||
}
|
||||
|
||||
if ODIN_OS == .Windows && err1 == .Permission_Denied {
|
||||
if fi, err2 := stat(path, temp_allocator()); err2 == nil {
|
||||
if err2 = chmod(path, 0o200|fi.mode); err2 == nil {
|
||||
err1 = remove(path)
|
||||
}
|
||||
}
|
||||
}
|
||||
if err == nil {
|
||||
err = err1
|
||||
}
|
||||
return err
|
||||
}
|
||||
|
||||
_getwd :: proc(allocator: runtime.Allocator) -> (dir: string, err: Error) {
|
||||
// TODO(bill)
|
||||
return "", nil
|
||||
@private cwd_lock: win32.SRWLOCK // zero is initialized
|
||||
|
||||
_get_working_directory :: proc(allocator: runtime.Allocator) -> (dir: string, err: Error) {
|
||||
win32.AcquireSRWLockExclusive(&cwd_lock)
|
||||
|
||||
TEMP_ALLOCATOR_GUARD()
|
||||
|
||||
sz_utf16 := win32.GetCurrentDirectoryW(0, nil)
|
||||
dir_buf_wstr := make([]u16, sz_utf16, temp_allocator()) or_return
|
||||
|
||||
sz_utf16 = win32.GetCurrentDirectoryW(win32.DWORD(len(dir_buf_wstr)), raw_data(dir_buf_wstr))
|
||||
assert(int(sz_utf16)+1 == len(dir_buf_wstr)) // the second time, it _excludes_ the NUL.
|
||||
|
||||
win32.ReleaseSRWLockExclusive(&cwd_lock)
|
||||
|
||||
return win32_utf16_to_utf8(dir_buf_wstr, allocator)
|
||||
}
|
||||
|
||||
_setwd :: proc(dir: string) -> (err: Error) {
|
||||
// TODO(bill)
|
||||
return nil
|
||||
_set_working_directory :: proc(dir: string) -> (err: Error) {
|
||||
TEMP_ALLOCATOR_GUARD()
|
||||
wstr := win32_utf8_to_wstring(dir, temp_allocator()) or_return
|
||||
|
||||
win32.AcquireSRWLockExclusive(&cwd_lock)
|
||||
|
||||
if !win32.SetCurrentDirectoryW(wstr) {
|
||||
err = _get_platform_error()
|
||||
}
|
||||
|
||||
win32.ReleaseSRWLockExclusive(&cwd_lock)
|
||||
|
||||
return
|
||||
}
|
||||
|
||||
can_use_long_paths: bool
|
||||
|
||||
Reference in New Issue
Block a user