From 306d3a16c4935dbb0f68735de01773800d1bad87 Mon Sep 17 00:00:00 2001 From: Krzesimir Nowak Date: Sat, 17 May 2025 19:40:57 +0200 Subject: [PATCH 1/2] sys/linux: Improve documentation for Dirent and related procedures --- core/sys/linux/types.odin | 2 +- core/sys/linux/wrappers.odin | 68 ++++++++++++++++++++++++++---------- 2 files changed, 51 insertions(+), 19 deletions(-) diff --git a/core/sys/linux/types.odin b/core/sys/linux/types.odin index b5670cf87..08e0026d3 100644 --- a/core/sys/linux/types.odin +++ b/core/sys/linux/types.odin @@ -288,7 +288,7 @@ Rename_Flags :: bit_set[Rename_Flags_Bits; u32] /* Directory entry record. - Recommended iterate these with `dirent_iterator()`, + Recommended to iterate these with `dirent_iterate_buf()`, and obtain the name via `dirent_name()`. */ Dirent :: struct { diff --git a/core/sys/linux/wrappers.odin b/core/sys/linux/wrappers.odin index 7b0dc61e2..d93928364 100644 --- a/core/sys/linux/wrappers.odin +++ b/core/sys/linux/wrappers.odin @@ -54,22 +54,45 @@ WCOREDUMP :: #force_inline proc "contextless" (s: u32) -> bool { // TODO: sigaddset etc -/// Iterate the results of getdents -/// Only iterates as much data as loaded in the buffer -/// In case you need to iterate *all* files in a directory -/// consider using dirent_get_iterate -/// -/// Example of using dirent_iterate_buf -/// // Get dirents into a buffer -/// buf: [128]u8 -/// sys.getdents(dirfd, buf[:]) -/// // Print the names of the files -/// for dir in sys.dirent_iterate_buf(buf[:], &offs) { -/// name := sys.dirent_name(dir) -/// fmt.println(name) -/// } -/// This function doesn't automatically make a request -/// for the buffer to be refilled +/* +Iterate the results of `getdents()`. + +This procedure extracts a directory entry from `buf` at the offset `offs`. +`offs` will be modified to store an offset to the possible next directory entry +in `buf`. The procedure only iterates as much data as loaded in the buffer and +does not automatically make a request for the buffer to be refilled. + +**Inputs**: +- `buf` - byte buffer with data from `getdents()` +- `offs` - offset to the next possible directory entry in `buf` + +**Returns**: +- A pointer to a directory entry in `buf`, or `nil`. +- A bool value denoting if a valid directory entry is returned. + +**Example**: + + import "core:fmt" + import "core:sys/linux" + + print_names :: proc(dirfd: linux.Fd) { + // Get dirents into a buffer. + buf: [128]u8 + // Loop until there are no more entries. + for { + written, err := linux.getdents(dirfd, buf[:]) + if err != .NONE || written == 0 { + break + } + // Print the names of the files. + offset : int + for dir in linux.dirent_iterate_buf(buf[:written], &offset) { + name := linux.dirent_name(dir) + fmt.println(name) + } + } + } +*/ dirent_iterate_buf :: proc "contextless" (buf: []u8, offs: ^int) -> (d: ^Dirent, cont: bool) { // Stopped iterating when there's no space left if offs^ >= len(buf) { @@ -82,8 +105,17 @@ dirent_iterate_buf :: proc "contextless" (buf: []u8, offs: ^int) -> (d: ^Dirent, return dirent, true } -/// Obtain the name of dirent as a string -/// The lifetime of the string is bound to the lifetime of the provided dirent structure +/* +Obtain the name of dirent as a string. + +The lifetime of the returned string is bound to the lifetime of the provided dirent structure. + +**Inputs**: +- `dirent` - directory entry + +**Returns**: +- A name of the entry +*/ dirent_name :: proc "contextless" (dirent: ^Dirent) -> string #no_bounds_check { str := ([^]u8)(&dirent.name) // Dirents are aligned to 8 bytes, so there is guaranteed to be a null From 3519cecb7c59d0e803369464e555c0c38f9b1268 Mon Sep 17 00:00:00 2001 From: Krzesimir Nowak Date: Sun, 18 May 2025 15:25:17 +0200 Subject: [PATCH 2/2] Formatting fixes --- core/sys/linux/wrappers.odin | 20 ++++++++++---------- 1 file changed, 10 insertions(+), 10 deletions(-) diff --git a/core/sys/linux/wrappers.odin b/core/sys/linux/wrappers.odin index d93928364..53eb80f86 100644 --- a/core/sys/linux/wrappers.odin +++ b/core/sys/linux/wrappers.odin @@ -62,15 +62,15 @@ This procedure extracts a directory entry from `buf` at the offset `offs`. in `buf`. The procedure only iterates as much data as loaded in the buffer and does not automatically make a request for the buffer to be refilled. -**Inputs**: -- `buf` - byte buffer with data from `getdents()` -- `offs` - offset to the next possible directory entry in `buf` +Inputs: +- buf: A byte buffer with data from `getdents()` +- offs: An offset to the next possible directory entry in `buf` -**Returns**: -- A pointer to a directory entry in `buf`, or `nil`. -- A bool value denoting if a valid directory entry is returned. +Returns: +- A pointer to a directory entry in `buf`, or `nil` +- A bool value denoting if a valid directory entry is returned -**Example**: +Example: import "core:fmt" import "core:sys/linux" @@ -110,10 +110,10 @@ Obtain the name of dirent as a string. The lifetime of the returned string is bound to the lifetime of the provided dirent structure. -**Inputs**: -- `dirent` - directory entry +Inputs: +- dirent: A directory entry -**Returns**: +Returns: - A name of the entry */ dirent_name :: proc "contextless" (dirent: ^Dirent) -> string #no_bounds_check {