Coverage Report

Created: 2025-06-13 06:25

/src/systemd/src/fundamental/cleanup-fundamental.h
Line
Count
Source (jump to first uncovered line)
1
/* SPDX-License-Identifier: LGPL-2.1-or-later */
2
#pragma once
3
4
#include "assert-fundamental.h"
5
6
/* A wrapper for 'func' to return void.
7
 * Only useful when a void-returning function is required by some API. */
8
#define DEFINE_TRIVIAL_DESTRUCTOR(name, type, func)     \
9
        static inline void name(type *p) {              \
10
                func(p);                                \
11
        }
12
13
/* When func() returns the void value (NULL, -1, …) of the appropriate type */
14
#define DEFINE_TRIVIAL_CLEANUP_FUNC(type, func)         \
15
        static inline void func##p(type *p) {           \
16
                if (*p)                                 \
17
                        *p = func(*p);                  \
18
        }
19
20
/* When func() doesn't return the appropriate type, set variable to empty afterwards.
21
 * The func() may be provided by a dynamically loaded shared library, hence add an assertion. */
22
#define DEFINE_TRIVIAL_CLEANUP_FUNC_FULL(type, func, empty)     \
23
        static inline void func##p(type *p) {                   \
24
                if (*p != (empty)) {                            \
25
                        DISABLE_WARNING_ADDRESS;                \
26
                        assert(func);                           \
27
                        REENABLE_WARNING;                       \
28
                        func(*p);                               \
29
                        *p = (empty);                           \
30
                }                                               \
31
        }
32
33
/* When func() doesn't return the appropriate type, and is also a macro, set variable to empty afterwards. */
34
#define DEFINE_TRIVIAL_CLEANUP_FUNC_FULL_MACRO(type, func, empty)       \
35
        static inline void func##p(type *p) {                           \
36
                if (*p != (empty)) {                                    \
37
                        func(*p);                                       \
38
                        *p = (empty);                                   \
39
                }                                                       \
40
        }
41
42
typedef void (*free_array_func_t)(void *p, size_t n);
43
44
/* An automatic _cleanup_-like logic for destroy arrays (i.e. pointers + size) when leaving scope */
45
typedef struct ArrayCleanup {
46
        void **parray;
47
        size_t *pn;
48
        free_array_func_t pfunc;
49
} ArrayCleanup;
50
51
0
static inline void array_cleanup(const ArrayCleanup *c) {
52
0
        assert(c);
53
0
        assert(!c->parray == !c->pn);
54
0
55
0
        if (!c->parray)
56
0
                return;
57
0
58
0
        if (*c->parray) {
59
0
                assert(c->pfunc);
60
0
                c->pfunc(*c->parray, *c->pn);
61
0
                *c->parray = NULL;
62
0
        }
63
0
64
0
        *c->pn = 0;
65
0
}
Unexecuted instantiation: fuzz-bcd.c:array_cleanup
Unexecuted instantiation: bcd.c:array_cleanup
Unexecuted instantiation: efi-string.c:array_cleanup
66
67
#define CLEANUP_ARRAY(array, n, func)                                   \
68
        _cleanup_(array_cleanup) _unused_ const ArrayCleanup CONCATENATE(_cleanup_array_, UNIQ) = { \
69
                .parray = (void**) &(array),                            \
70
                .pn = &(n),                                             \
71
                .pfunc = (free_array_func_t) ({                         \
72
                                void (*_f)(typeof(array[0]) *a, size_t b) = func; \
73
                                _f;                                     \
74
                         }),                                            \
75
        }