diff options
| author | jason <jkercher43@gmail.com> | 2025-01-10 20:54:09 -0500 |
|---|---|---|
| committer | jason <jkercher43@gmail.com> | 2025-01-10 20:54:09 -0500 |
| commit | fa7ef28acf6443073c1429c7e6df400eeb8f36af (patch) | |
| tree | 29660dbb71569b38526f008e6ddadbf29d9e486b /core/sys/linux | |
| parent | cd93e2f6f8bb971e1d33bfc783ce4ab4e7568a5b (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.odin | 28 |
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 +} |