mirror of
https://github.com/Ed94/Odin.git
synced 2026-08-06 07:38:48 +00:00
added _remove_all
This commit is contained in:
+22
-22
@@ -25,23 +25,23 @@ _std_handle :: proc(kind: Std_Handle_Kind) -> Handle {
|
|||||||
unreachable()
|
unreachable()
|
||||||
}
|
}
|
||||||
|
|
||||||
_O_RDONLY :: 0o0
|
__O_RDONLY :: 0o0
|
||||||
_O_WRONLY :: 0o1
|
__O_WRONLY :: 0o1
|
||||||
_O_RDWR :: 0o2
|
__O_RDWR :: 0o2
|
||||||
_O_CREAT :: 0o100
|
__O_CREAT :: 0o100
|
||||||
_O_EXCL :: 0o200
|
__O_EXCL :: 0o200
|
||||||
_O_TRUNC :: 0o1000
|
__O_TRUNC :: 0o1000
|
||||||
_O_APPEND :: 0o2000
|
__O_APPEND :: 0o2000
|
||||||
_O_NONBLOCK :: 0o4000
|
__O_NONBLOCK :: 0o4000
|
||||||
_O_LARGEFILE :: 0o100000
|
__O_LARGEFILE :: 0o100000
|
||||||
_O_DIRECTORY :: 0o200000
|
__O_DIRECTORY :: 0o200000
|
||||||
_O_SYNC :: 0o4010000
|
__O_SYNC :: 0o4010000
|
||||||
_O_CLOEXEC :: 0o2000000
|
__O_CLOEXEC :: 0o2000000
|
||||||
|
|
||||||
_opendir :: proc(name: string) -> (Handle, Error) {
|
_opendir :: proc(name: string) -> (Handle, Error) {
|
||||||
cstr := strings.clone_to_cstring(name, context.temp_allocator)
|
cstr := strings.clone_to_cstring(name, context.temp_allocator)
|
||||||
|
|
||||||
flags := _O_RDONLY|_O_NONBLOCK|_O_DIRECTORY|_O_LARGEFILE|_O_CLOEXEC
|
flags := __O_RDONLY|__O_NONBLOCK|__O_DIRECTORY|__O_LARGEFILE|__O_CLOEXEC
|
||||||
|
|
||||||
handle_i := unix.sys_open(cstr, flags)
|
handle_i := unix.sys_open(cstr, flags)
|
||||||
if handle_i < 0 {
|
if handle_i < 0 {
|
||||||
@@ -56,17 +56,17 @@ _open :: proc(name: string, flags: File_Flags, perm: File_Mode) -> (Handle, Erro
|
|||||||
|
|
||||||
flags_i: int
|
flags_i: int
|
||||||
switch flags & O_RDONLY|O_WRONLY|O_RDWR {
|
switch flags & O_RDONLY|O_WRONLY|O_RDWR {
|
||||||
case O_RDONLY: flags_i = _O_RDONLY
|
case O_RDONLY: flags_i = __O_RDONLY
|
||||||
case O_WRONLY: flags_i = _O_WRONLY
|
case O_WRONLY: flags_i = __O_WRONLY
|
||||||
case O_RDWR: flags_i = _O_RDWR
|
case O_RDWR: flags_i = __O_RDWR
|
||||||
}
|
}
|
||||||
|
|
||||||
flags_i |= (_O_APPEND * int(.Append in flags))
|
flags_i |= (__O_APPEND * int(.Append in flags))
|
||||||
flags_i |= (_O_CREAT * int(.Create in flags))
|
flags_i |= (__O_CREAT * int(.Create in flags))
|
||||||
flags_i |= (_O_EXCL * int(.Excl in flags))
|
flags_i |= (__O_EXCL * int(.Excl in flags))
|
||||||
flags_i |= (_O_SYNC * int(.Sync in flags))
|
flags_i |= (__O_SYNC * int(.Sync in flags))
|
||||||
flags_i |= (_O_TRUNC * int(.Trunc in flags))
|
flags_i |= (__O_TRUNC * int(.Trunc in flags))
|
||||||
flags_i |= (_O_CLOEXEC * int(.Close_On_Exec in flags))
|
flags_i |= (__O_CLOEXEC * int(.Close_On_Exec in flags))
|
||||||
|
|
||||||
handle_i := unix.sys_open(cstr, flags_i, int(perm))
|
handle_i := unix.sys_open(cstr, flags_i, int(perm))
|
||||||
if handle_i < 0 {
|
if handle_i < 0 {
|
||||||
|
|||||||
@@ -1,7 +1,6 @@
|
|||||||
//+private
|
//+private
|
||||||
package os2
|
package os2
|
||||||
|
|
||||||
import "core:fmt"
|
|
||||||
import "core:strings"
|
import "core:strings"
|
||||||
import "core:sys/unix"
|
import "core:sys/unix"
|
||||||
import "core:path/filepath"
|
import "core:path/filepath"
|
||||||
@@ -9,6 +8,8 @@ import "core:path/filepath"
|
|||||||
_Path_Separator :: '/'
|
_Path_Separator :: '/'
|
||||||
_Path_List_Separator :: ':'
|
_Path_List_Separator :: ':'
|
||||||
|
|
||||||
|
DIRECTORY_FLAGS :: __O_RDONLY|__O_NONBLOCK|__O_DIRECTORY|__O_LARGEFILE|__O_CLOEXEC
|
||||||
|
|
||||||
_is_path_separator :: proc(c: byte) -> bool {
|
_is_path_separator :: proc(c: byte) -> bool {
|
||||||
return c == '/'
|
return c == '/'
|
||||||
}
|
}
|
||||||
@@ -53,9 +54,99 @@ _mkdir_all :: proc(path: string, perm: File_Mode) -> Error {
|
|||||||
return _mkdir_all_stat(path, &s, perm)
|
return _mkdir_all_stat(path, &s, perm)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
dirent64 :: struct {
|
||||||
|
d_ino: u64,
|
||||||
|
d_off: u64,
|
||||||
|
d_reclen: u16,
|
||||||
|
d_type: u8,
|
||||||
|
d_name: [1]u8,
|
||||||
|
}
|
||||||
|
|
||||||
|
DT_UNKNOWN :: 0
|
||||||
|
DT_FIFO :: 1
|
||||||
|
DT_CHR :: 2
|
||||||
|
DT_DIR :: 4
|
||||||
|
DT_BLK :: 6
|
||||||
|
DT_REG :: 8
|
||||||
|
DT_LNK :: 10
|
||||||
|
DT_SOCK :: 12
|
||||||
|
DT_WHT :: 14
|
||||||
|
|
||||||
_remove_all :: proc(path: string) -> Error {
|
_remove_all :: proc(path: string) -> Error {
|
||||||
// TODO
|
_remove_all_dir :: proc(dfd: Handle) -> Error {
|
||||||
return nil
|
n := 64
|
||||||
|
buf := make([]u8, n)
|
||||||
|
defer delete(buf)
|
||||||
|
|
||||||
|
loop: for {
|
||||||
|
res := unix.sys_getdents64(int(dfd), &buf[0], n)
|
||||||
|
switch res {
|
||||||
|
case -22: //-EINVAL
|
||||||
|
n *= 2
|
||||||
|
buf = make([]u8, n)
|
||||||
|
continue loop
|
||||||
|
case -4096..<0:
|
||||||
|
return _get_platform_error(res)
|
||||||
|
case 0:
|
||||||
|
break loop
|
||||||
|
}
|
||||||
|
|
||||||
|
d: ^dirent64
|
||||||
|
|
||||||
|
for i := 0; i < res; i += int(d.d_reclen) {
|
||||||
|
description: string
|
||||||
|
d = (^dirent64)(rawptr(&buf[i]))
|
||||||
|
d_name_cstr := cstring(&d.d_name[0])
|
||||||
|
|
||||||
|
buf_len := uintptr(d.d_reclen) - offset_of(d.d_name)
|
||||||
|
|
||||||
|
/* check for current directory (.) */
|
||||||
|
#no_bounds_check if buf_len > 1 && d.d_name[0] == '.' && d.d_name[1] == 0 {
|
||||||
|
continue
|
||||||
|
}
|
||||||
|
|
||||||
|
/* check for parent directory (..) */
|
||||||
|
#no_bounds_check if buf_len > 2 && d.d_name[0] == '.' && d.d_name[1] == '.' && d.d_name[2] == 0 {
|
||||||
|
continue
|
||||||
|
}
|
||||||
|
|
||||||
|
res: int
|
||||||
|
|
||||||
|
switch d.d_type {
|
||||||
|
case DT_DIR:
|
||||||
|
handle_i := unix.sys_openat(int(dfd), d_name_cstr, DIRECTORY_FLAGS)
|
||||||
|
if handle_i < 0 {
|
||||||
|
return _get_platform_error(handle_i)
|
||||||
|
}
|
||||||
|
defer unix.sys_close(handle_i)
|
||||||
|
_remove_all_dir(Handle(handle_i)) or_return
|
||||||
|
res = unix.sys_unlinkat(int(dfd), d_name_cstr, int(unix.AT_REMOVEDIR))
|
||||||
|
case:
|
||||||
|
res = unix.sys_unlinkat(int(dfd), d_name_cstr)
|
||||||
|
}
|
||||||
|
|
||||||
|
if res < 0 {
|
||||||
|
return _get_platform_error(res)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
|
cstr := strings.clone_to_cstring(path, context.temp_allocator)
|
||||||
|
|
||||||
|
handle_i := unix.sys_open(cstr, DIRECTORY_FLAGS)
|
||||||
|
switch handle_i {
|
||||||
|
case -ENOTDIR:
|
||||||
|
return _ok_or_error(unix.sys_unlink(cstr))
|
||||||
|
case -4096..<0:
|
||||||
|
return _get_platform_error(handle_i)
|
||||||
|
}
|
||||||
|
|
||||||
|
fd := Handle(handle_i)
|
||||||
|
defer close(fd)
|
||||||
|
_remove_all_dir(fd) or_return
|
||||||
|
return _ok_or_error(unix.sys_rmdir(cstr))
|
||||||
}
|
}
|
||||||
|
|
||||||
_getwd :: proc(allocator := context.allocator) -> (dir: string, err: Error) {
|
_getwd :: proc(allocator := context.allocator) -> (dir: string, err: Error) {
|
||||||
@@ -71,8 +162,8 @@ _getwd :: proc(allocator := context.allocator) -> (dir: string, err: Error) {
|
|||||||
if res >= 0 {
|
if res >= 0 {
|
||||||
return strings.string_from_nul_terminated_ptr(&buf[0], len(buf)), nil
|
return strings.string_from_nul_terminated_ptr(&buf[0], len(buf)), nil
|
||||||
}
|
}
|
||||||
if errno := int(unix.get_errno(res)); errno != ERANGE {
|
if res != -ERANGE {
|
||||||
return "", _get_platform_error(errno)
|
return "", _get_platform_error(res)
|
||||||
}
|
}
|
||||||
resize(&buf, len(buf)+PATH_MAX)
|
resize(&buf, len(buf)+PATH_MAX)
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1537,6 +1537,10 @@ sys_open :: proc(path: cstring, flags: int, mode: int = 0o000) -> int {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
sys_openat :: proc(dfd: int, path: cstring, flags: int, mode: int = 0o000) -> int {
|
||||||
|
return int(intrinsics.syscall(SYS_openat, uintptr(dfd), uintptr(rawptr(path)), uintptr(flags), uintptr(mode)))
|
||||||
|
}
|
||||||
|
|
||||||
sys_close :: proc(fd: int) -> int {
|
sys_close :: proc(fd: int) -> int {
|
||||||
return int(intrinsics.syscall(SYS_close, uintptr(fd)))
|
return int(intrinsics.syscall(SYS_close, uintptr(fd)))
|
||||||
}
|
}
|
||||||
@@ -1701,6 +1705,10 @@ sys_unlink :: proc(path: cstring) -> int {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
sys_unlinkat :: proc(dfd: int, path: cstring, flag: int = 0) -> int {
|
||||||
|
return int(intrinsics.syscall(SYS_unlinkat, uintptr(dfd), uintptr(rawptr(path)), flag))
|
||||||
|
}
|
||||||
|
|
||||||
sys_rmdir :: proc(path: cstring) -> int {
|
sys_rmdir :: proc(path: cstring) -> int {
|
||||||
when ODIN_ARCH != .arm64 {
|
when ODIN_ARCH != .arm64 {
|
||||||
return int(intrinsics.syscall(SYS_rmdir, uintptr(rawptr(path))))
|
return int(intrinsics.syscall(SYS_rmdir, uintptr(rawptr(path))))
|
||||||
|
|||||||
Reference in New Issue
Block a user