mirror of
https://github.com/Ed94/Odin.git
synced 2026-08-07 16:18:52 +00:00
Mock out os2.remove_all for Windows
This commit is contained in:
@@ -31,11 +31,11 @@ getwd :: get_working_directory
|
|||||||
|
|
||||||
@(require_results)
|
@(require_results)
|
||||||
get_working_directory :: proc(allocator: runtime.Allocator) -> (dir: string, err: Error) {
|
get_working_directory :: proc(allocator: runtime.Allocator) -> (dir: string, err: Error) {
|
||||||
return _getwd(allocator)
|
return _get_working_directory(allocator)
|
||||||
}
|
}
|
||||||
|
|
||||||
setwd :: set_working_directory
|
setwd :: set_working_directory
|
||||||
|
|
||||||
set_working_directory :: proc(dir: string) -> (err: Error) {
|
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))
|
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
|
// NOTE(tetra): I would use PATH_MAX here, but I was not able to find
|
||||||
// an authoritative value for it across all systems.
|
// an authoritative value for it across all systems.
|
||||||
// The largest value I could find was 4096, so might as well use the page size.
|
// 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()
|
unreachable()
|
||||||
}
|
}
|
||||||
|
|
||||||
_setwd :: proc(dir: string) -> Error {
|
_set_working_directory :: proc(dir: string) -> Error {
|
||||||
dir_cstr := temp_cstring(dir) or_return
|
dir_cstr := temp_cstring(dir) or_return
|
||||||
return _get_platform_error(linux.chdir(dir_cstr))
|
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 {
|
_remove_all :: proc(path: string) -> Error {
|
||||||
// TODO(bill): _remove_all for windows
|
if path == "" {
|
||||||
return nil
|
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) {
|
@private cwd_lock: win32.SRWLOCK // zero is initialized
|
||||||
// TODO(bill)
|
|
||||||
return "", nil
|
_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) {
|
_set_working_directory :: proc(dir: string) -> (err: Error) {
|
||||||
// TODO(bill)
|
TEMP_ALLOCATOR_GUARD()
|
||||||
return nil
|
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
|
can_use_long_paths: bool
|
||||||
|
|||||||
Reference in New Issue
Block a user