aboutsummaryrefslogtreecommitdiff
path: root/core/sys/linux
diff options
context:
space:
mode:
authorjason <jkercher43@gmail.com>2025-01-10 20:54:09 -0500
committerjason <jkercher43@gmail.com>2025-01-10 20:54:09 -0500
commitfa7ef28acf6443073c1429c7e6df400eeb8f36af (patch)
tree29660dbb71569b38526f008e6ddadbf29d9e486b /core/sys/linux
parentcd93e2f6f8bb971e1d33bfc783ce4ab4e7568a5b (diff)
Implement _read_directory_iterator in os2.
Also, fix minor bug in linux.dirent_name.
Diffstat (limited to 'core/sys/linux')
-rw-r--r--core/sys/linux/wrappers.odin28
1 files changed, 12 insertions, 16 deletions
diff --git a/core/sys/linux/wrappers.odin b/core/sys/linux/wrappers.odin
index 4f6118c80..e367a4db4 100644
--- a/core/sys/linux/wrappers.odin
+++ b/core/sys/linux/wrappers.odin
@@ -86,22 +86,18 @@ dirent_iterate_buf :: proc "contextless" (buf: []u8, offs: ^int) -> (d: ^Dirent,
/// The lifetime of the string is bound to the lifetime of the provided dirent structure
dirent_name :: proc "contextless" (dirent: ^Dirent) -> string #no_bounds_check {
str := ([^]u8)(&dirent.name)
- // Note(flysand): The string size calculated above applies only to the ideal case
- // we subtract 1 byte from the string size, because a null terminator is guaranteed
- // to be present. But! That said, the dirents are aligned to 8 bytes and the padding
- // between the null terminator and the start of the next struct may be not initialized
- // which means we also have to scan these garbage bytes.
- str_size := int(dirent.reclen) - 1 - cast(int)offset_of(Dirent, name)
- // This skips *only* over the garbage, since if we're not garbage we're at nul terminator,
- // which skips this loop
- for str[str_size] != 0 {
- str_size -= 1
- }
- for str[str_size-1] == 0 {
- str_size -= 1
+ // Dirents are aligned to 8 bytes, so there is guaranteed to be a null
+ // terminator in the last 8 bytes.
+ str_size := int(dirent.reclen) - cast(int)offset_of(Dirent, name)
+
+ trunc := min(str_size, 8)
+ str_size -= trunc
+ for i in 0..<trunc {
+ str_size += 1
+ if str[str_size] == 0 {
+ break
+ }
}
- // Oh yeah btw i could also just `repne scasb` this thing, but honestly I started doing
- // it the painful way, might as well finish doing it that way
return string(str[:str_size])
}
@@ -117,4 +113,4 @@ perf_cache_config :: #force_inline proc "contextless" (id: Perf_Hardware_Cache_I
op: Perf_Hardware_Cache_Op_Id,
res: Perf_Hardware_Cache_Result_Id) -> u64 {
return u64(id) | (u64(op) << 8) | (u64(res) << 16)
-} \ No newline at end of file
+}