libc: Add the internal TRY_OR_SET_ERRNO macro
All checks were successful
continuous-integration/drone/push Build is passing

Similar mechanism to TRY(), but propagating C-like errors instead of Results on failure.
This commit is contained in:
apio 2023-06-03 20:20:01 +02:00
parent 6b4d41529e
commit e10cc2d954
Signed by: apio
GPG Key ID: B8A7D06E42258954
5 changed files with 26 additions and 47 deletions

View File

@ -5,6 +5,7 @@
#include <errno.h>
// Set errno after a failed system call, otherwise extract the successful value.
#define __errno_return(value, type) \
do { \
if (value < 0) \
@ -15,4 +16,18 @@
return (type)value; \
} while (0)
// If expr has a value, evaluates to that value. Otherwise, short-circuits, sets errno to expr's error, and returns
// failval (casted to rtype) from the calling function. Similar to TRY() in luna/Result.h, but used for transforming
// errors from luna functions to libc functions.
#define TRY_OR_SET_ERRNO(expr, rtype, failval) \
({ \
auto _expr_rc = (expr); \
if (!_expr_rc.has_value()) \
{ \
errno = _expr_rc.error(); \
return (rtype)failval; \
} \
_expr_rc.release_value(); \
})
#endif

View File

@ -1,3 +1,4 @@
#include <bits/errno-return.h>
#include <errno.h>
#include <luna/ScopeGuard.h>
#include <luna/Vector.h>
@ -83,12 +84,8 @@ static Result<void> _try_move_env()
static int _move_env()
{
auto rc = _try_move_env();
if (rc.has_error())
{
errno = rc.error();
return -1;
}
TRY_OR_SET_ERRNO(_try_move_env(), int, -1);
return 0;
}
@ -178,12 +175,7 @@ extern "C"
// Add a new NULL at the end of the array and replace the previous one with our string.
index = g_dynamic_env.size() - 1;
auto rc = g_dynamic_env.try_append(nullptr);
if (rc.has_error())
{
errno = rc.error();
return -1;
}
TRY_OR_SET_ERRNO(g_dynamic_env.try_append(nullptr), int, -1);
guard.deactivate();
_update_env();

View File

@ -1,3 +1,4 @@
#include <bits/errno-return.h>
#include <errno.h>
#include <fcntl.h>
#include <grp.h>
@ -67,13 +68,7 @@ extern "C"
struct group* getgrent()
{
auto rc = try_getgrent();
if (rc.has_error())
{
errno = rc.error();
return nullptr;
}
return rc.value();
return TRY_OR_SET_ERRNO(try_getgrent(), group*, nullptr);
}
struct group* getgrnam(const char* name)

View File

@ -1,3 +1,4 @@
#include <bits/errno-return.h>
#include <errno.h>
#include <fcntl.h>
#include <limits.h>
@ -144,35 +145,17 @@ extern "C"
void* malloc(size_t size)
{
auto rc = malloc_impl(size);
if (rc.has_error())
{
errno = rc.error();
return nullptr;
}
return rc.value();
return TRY_OR_SET_ERRNO(malloc_impl(size), void*, nullptr);
}
void* calloc(size_t nmemb, size_t size)
{
auto rc = calloc_impl(nmemb, size);
if (rc.has_error())
{
errno = rc.error();
return nullptr;
}
return rc.value();
return TRY_OR_SET_ERRNO(calloc_impl(nmemb, size), void*, nullptr);
}
void* realloc(void* ptr, size_t size)
{
auto rc = realloc_impl(ptr, size);
if (rc.has_error())
{
errno = rc.error();
return nullptr;
}
return rc.value();
return TRY_OR_SET_ERRNO(realloc_impl(ptr, size), void*, nullptr);
}
void free(void* ptr)

View File

@ -169,13 +169,7 @@ extern "C"
int execvpe(const char* name, char* const* argv, char* const* envp)
{
auto rc = try_execvpe(name, argv, envp);
if (rc.has_error())
{
errno = rc.error();
return -1;
}
return rc.value();
return TRY_OR_SET_ERRNO(try_execvpe(name, argv, envp), int, -1);
}
int execvp(const char* name, char* const* argv)