use sys/linux dirent instead of manual iteration

This commit is contained in:
jason
2024-07-30 10:19:09 -04:00
parent 792640df1f
commit c7eb2ae6bb
2 changed files with 12 additions and 32 deletions
+9 -24
View File
@@ -1,6 +1,7 @@
//+private //+private
package os2 package os2
import "core:strings"
import "core:strconv" import "core:strconv"
import "base:runtime" import "base:runtime"
import "core:sys/linux" import "core:sys/linux"
@@ -75,14 +76,6 @@ _mkdir_all :: proc(path: string, perm: int) -> Error {
return nil if has_created else .Exist return nil if has_created else .Exist
} }
dirent64 :: struct {
d_ino: u64,
d_off: u64,
d_reclen: u16,
d_type: u8,
d_name: [1]u8,
}
_remove_all :: proc(path: string) -> Error { _remove_all :: proc(path: string) -> Error {
DT_DIR :: 4 DT_DIR :: 4
@@ -105,26 +98,18 @@ _remove_all :: proc(path: string) -> Error {
return _get_platform_error(errno) return _get_platform_error(errno)
} }
d: ^dirent64 offset: int
for d in linux.dirent_iterate_buf(buf[:buflen], &offset) {
d_name_str := linux.dirent_name(d)
d_name_cstr := strings.unsafe_string_to_cstring(d_name_str)
for i := 0; i < buflen; i += int(d.d_reclen) { /* check for current or parent directory (. or ..) */
d = (^dirent64)(rawptr(&buf[i])) if d_name_str == "." || d_name_str == ".." {
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 continue
} }
/* check for parent directory (..) */ #partial switch d.type {
#no_bounds_check if buf_len > 2 && d.d_name[0] == '.' && d.d_name[1] == '.' && d.d_name[2] == 0 { case .DIR:
continue
}
switch d.d_type {
case DT_DIR:
new_dfd: linux.Fd new_dfd: linux.Fd
new_dfd, errno = linux.openat(dfd, d_name_cstr, _OPENDIR_FLAGS) new_dfd, errno = linux.openat(dfd, d_name_cstr, _OPENDIR_FLAGS)
if errno != .NONE { if errno != .NONE {
+3 -8
View File
@@ -80,17 +80,12 @@ _process_list :: proc(allocator: runtime.Allocator) -> (list: []int, err: Error)
return {}, _get_platform_error(errno) return {}, _get_platform_error(errno)
} }
d: ^dirent64 offset: int
for d in linux.dirent_iterate_buf(buf[:buflen], &offset) {
for i := 0; i < buflen; i += int(d.d_reclen) { d_name_str := linux.dirent_name(d)
d = (^dirent64)(rawptr(&buf[i]))
d_name_cstr := cstring(&d.d_name[0])
#no_bounds_check d_name_str := string(d.d_name[:len(d_name_cstr)])
if pid, ok := strconv.parse_int(d_name_str); ok { if pid, ok := strconv.parse_int(d_name_str); ok {
append(&dynamic_list, pid) append(&dynamic_list, pid)
} else {
return nil, .Invalid_File
} }
} }
} }