Merge pull request #5172 from krnowak/krnowak/sys-linux-dirent-docs

sys/linux: Improve documentation for Dirent and related procedures
This commit is contained in:
Laytan
2025-05-18 17:47:41 +02:00
committed by GitHub
2 changed files with 51 additions and 19 deletions

View File

@@ -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 {

View File

@@ -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: 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
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: A 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