util.h: add new UNPROTECT_ERRNO macro

THis is inspired by #11395, but much simpler.
This commit is contained in:
Lennart Poettering 2019-01-18 20:04:13 +01:00
parent 1cae151d8e
commit 840f606d88
3 changed files with 37 additions and 3 deletions

View File

@ -174,12 +174,21 @@ static inline void *mempset(void *s, int c, size_t n) {
}
static inline void _reset_errno_(int *saved_errno) {
if (*saved_errno < 0) /* Invalidated by UNPROTECT_ERRNO? */
return;
errno = *saved_errno;
}
#define PROTECT_ERRNO \
_cleanup_(_reset_errno_) _unused_ int _saved_errno_ = errno
#define UNPROTECT_ERRNO \
do { \
errno = _saved_errno_; \
_saved_errno_ = -1; \
} while (false)
static inline int negative_errno(void) {
/* This helper should be used to shut up gcc if you know 'errno' is
* negative. Instead of "return -errno;", use "return negative_errno();"

View File

@ -361,11 +361,11 @@ static void test_unlink_noerrno(void) {
{
PROTECT_ERRNO;
errno = -42;
errno = 42;
assert_se(unlink_noerrno(name) >= 0);
assert_se(errno == -42);
assert_se(errno == 42);
assert_se(unlink_noerrno(name) < 0);
assert_se(errno == -42);
assert_se(errno == 42);
}
}

View File

@ -213,6 +213,30 @@ static void test_protect_errno(void) {
assert_se(errno == 12);
}
static void test_unprotect_errno_inner_function(void) {
PROTECT_ERRNO;
errno = 2222;
}
static void test_unprotect_errno(void) {
log_info("/* %s */", __func__);
errno = 4711;
PROTECT_ERRNO;
errno = 815;
UNPROTECT_ERRNO;
assert_se(errno == 4711);
test_unprotect_errno_inner_function();
assert_se(errno == 4711);
}
static void test_in_set(void) {
log_info("/* %s */", __func__);
@ -383,6 +407,7 @@ int main(int argc, char *argv[]) {
test_div_round_up();
test_u64log2();
test_protect_errno();
test_unprotect_errno();
test_in_set();
test_log2i();
test_eqzero();