Add directory stream wrappers
All checks were successful
libakstdlib CI Build / coverage (push) Successful in 2m47s
libakstdlib CI Build / sanitizers (push) Successful in 2m54s
libakstdlib CI Build / cmake_build (push) Successful in 2m59s
libakstdlib CI Build / mutation_test (push) Successful in 12m31s

This commit is contained in:
2026-08-03 13:04:33 -04:00
committed by Logikoma
parent 2b79aca103
commit d5e5e95c61
5 changed files with 285 additions and 1 deletions

View File

@@ -63,6 +63,7 @@
/*
* What this header needs in its own declarations, and no more:
* dirent.h DIR, struct dirent
* stdio.h FILE
* stddef.h size_t
* stdint.h uint32_t
@@ -72,11 +73,12 @@
* which every consumer then got whether it wanted them or not. stddef.h in place
* of stdlib.h is the same size_t at a fraction of the namespace.
*/
#include <dirent.h>
#include <fcntl.h>
#include <stdarg.h>
#include <stddef.h>
#include <stdint.h>
#include <stdio.h>
#include <fcntl.h>
#include <sys/stat.h>
#include <sys/statvfs.h>
/* off_t, for the aksl_fseeko/aksl_ftello pair. POSIX, like aksl_realpath. */
@@ -892,6 +894,69 @@ akerr_ErrorContext AKERR_NOIGNORE *aksl_statvfs(const char *path, struct statvfs
akerr_ErrorContext AKERR_NOIGNORE *aksl_fstatvfs(int fd, struct statvfs *dest);
/** @} */
/* ====================================================================== */
/** @name Directories
*
* Directory entries are copied into caller-owned storage. `d_type` may be
* `DT_UNKNOWN`; callers that require a type must fall back to aksl_stat or
* aksl_fstatat.
* @{
*/
/* ====================================================================== */
/**
* @brief Open a directory stream by path.
* @param[in] pathname Directory path. Required.
* @param[out] dest Open directory stream, or NULL on failure. Required.
* @throws AKERR_NULLPOINTER If pathname or dest is NULL.
* @throws AKERR_IO If opendir(3) fails without setting errno.
* @throws (errno) The errno opendir(3) set, reported directly as the status.
* @return NULL on success, an error context otherwise.
*/
akerr_ErrorContext AKERR_NOIGNORE *aksl_opendir(const char *pathname, DIR **dest);
/**
* @brief Open a directory stream from a file descriptor.
* @param[in] fd Open directory descriptor. Ownership transfers on success.
* @param[out] dest Open directory stream, or NULL on failure. Required.
* @throws AKERR_NULLPOINTER If dest is NULL.
* @throws AKERR_IO If fdopendir(3) fails without setting errno.
* @throws (errno) The errno fdopendir(3) set, reported directly as the status.
* @return NULL on success, an error context otherwise.
*/
akerr_ErrorContext AKERR_NOIGNORE *aksl_fdopendir(int fd, DIR **dest);
/**
* @brief Read and copy the next directory entry.
* @param[in] dirp Open directory stream. Required.
* @param[out] dest Caller-owned storage for the copied entry. Required.
* @throws AKERR_NULLPOINTER If dirp or dest is NULL.
* @throws AKERR_EOF At the end of the directory stream.
* @throws AKERR_IO If readdir(3) fails without setting errno.
* @throws (errno) The errno readdir(3) set, reported directly as the status.
* @return NULL on success, an error context otherwise.
*/
akerr_ErrorContext AKERR_NOIGNORE *aksl_readdir(DIR *dirp, struct dirent *dest);
/**
* @brief Close a directory stream.
* @param[in] dirp Open directory stream. Required.
* @throws AKERR_NULLPOINTER If dirp is NULL.
* @throws AKERR_IO If closedir(3) fails without setting errno.
* @throws (errno) The errno closedir(3) set, reported directly as the status.
* @return NULL on success, an error context otherwise.
*/
akerr_ErrorContext AKERR_NOIGNORE *aksl_closedir(DIR *dirp);
/**
* @brief Reset a directory stream to its beginning.
* @param[in] dirp Open directory stream. Required.
* @throws AKERR_NULLPOINTER If dirp is NULL.
* @return NULL on success, an error context otherwise.
*/
akerr_ErrorContext AKERR_NOIGNORE *aksl_rewinddir(DIR *dirp);
/** @} */
/* ====================================================================== */
/** @name Streams: open, read, write, close