Address directory wrapper review
All checks were successful
libakstdlib CI Build / cmake_build (push) Successful in 2m58s
libakstdlib CI Build / sanitizers (push) Successful in 2m57s
libakstdlib CI Build / coverage (push) Successful in 2m47s
libakstdlib CI Build / mutation_test (push) Successful in 13m26s

This commit is contained in:
2026-08-03 15:00:56 -04:00
parent d5e5e95c61
commit 83ff77608f
2 changed files with 31 additions and 1 deletions

View File

@@ -1,10 +1,20 @@
/* POSIX directory-stream wrappers. */
/*
* POSIX directory-stream wrappers.
*
* opendir(3), fdopendir(3), readdir(3), closedir(3), and rewinddir(3) expose
* three different failure conventions between them. These wrappers turn all
* three into error contexts and make end-of-directory an explicit AKERR_EOF.
*/
#include <akstdlib.h>
#include <errno.h>
#include "aksl_internal.h"
/*
* opendir(3) returns NULL for failure. Clear *dest first so a failed open
* cannot leave the caller holding a stale directory stream.
*/
akerr_ErrorContext AKERR_NOIGNORE *aksl_opendir(const char *pathname, DIR **dest)
{
PREPARE_ERROR(e);
@@ -19,6 +29,10 @@ akerr_ErrorContext AKERR_NOIGNORE *aksl_opendir(const char *pathname, DIR **dest
SUCCEED_RETURN(e);
}
/*
* fdopendir(3) takes ownership of fd only when it succeeds. On success the
* matching aksl_closedir call closes both the stream and its descriptor.
*/
akerr_ErrorContext AKERR_NOIGNORE *aksl_fdopendir(int fd, DIR **dest)
{
PREPARE_ERROR(e);
@@ -30,6 +44,10 @@ akerr_ErrorContext AKERR_NOIGNORE *aksl_fdopendir(int fd, DIR **dest)
SUCCEED_RETURN(e);
}
/*
* readdir(3) owns and may reuse its returned storage. Copy the entry into the
* caller's destination, and use errno to distinguish failure from exhaustion.
*/
akerr_ErrorContext AKERR_NOIGNORE *aksl_readdir(DIR *dirp, struct dirent *dest)
{
struct dirent *entry = NULL;
@@ -50,6 +68,7 @@ akerr_ErrorContext AKERR_NOIGNORE *aksl_readdir(DIR *dirp, struct dirent *dest)
SUCCEED_RETURN(e);
}
/* closedir(3) reports its failure directly and invalidates dirp on success. */
akerr_ErrorContext AKERR_NOIGNORE *aksl_closedir(DIR *dirp)
{
PREPARE_ERROR(e);
@@ -60,6 +79,10 @@ akerr_ErrorContext AKERR_NOIGNORE *aksl_closedir(DIR *dirp)
SUCCEED_RETURN(e);
}
/*
* rewinddir(3) has no failure return. Preserve that contract after rejecting
* a NULL stream, which would otherwise be undefined behaviour.
*/
akerr_ErrorContext AKERR_NOIGNORE *aksl_rewinddir(DIR *dirp)
{
PREPARE_ERROR(e);