basic: Move trivial cleanup/ref/unref macros from macro.h to memory-util.h

Let's keep macro.h for the extremely generic macros that don't fit anywhere
else. Since CLEANUP_ARRAY() is already in memory-util-fundamental.h, we can
make a good case for moving the other cleanup macros in there as well.
This commit is contained in:
Daan De Meyer
2025-04-18 13:59:04 +02:00
parent a4bff6ef8e
commit b14f74f9ab
27 changed files with 115 additions and 89 deletions
+1
View File
@@ -3,6 +3,7 @@
#include "sd-bus.h"
#include "memory-util.h"
#include "time-util.h"
#include "unit-def.h"
+1
View File
@@ -8,6 +8,7 @@
#include <sys/socket.h>
#include "macro.h"
#include "memory-util.h"
#include "missing_fcntl.h"
#include "stdio-util.h"
+1
View File
@@ -11,6 +11,7 @@
#include "dlfcn-util.h"
#include "macro.h"
#include "memory-util.h"
extern DLSYM_PROTOTYPE(gcry_md_close);
extern DLSYM_PROTOTYPE(gcry_md_copy);
+1
View File
@@ -5,6 +5,7 @@
#include <stddef.h>
#include "macro.h"
#include "memory-util.h"
/*
* The log context allows attaching extra metadata to log messages written to the journal via log.h. We keep
-53
View File
@@ -251,59 +251,6 @@ static inline int __coverity_check_and_return__(int condition) {
/* Pointers range from NULL to POINTER_MAX */
#define POINTER_MAX ((void*) UINTPTR_MAX)
#define _DEFINE_TRIVIAL_REF_FUNC(type, name, scope) \
scope type *name##_ref(type *p) { \
if (!p) \
return NULL; \
\
/* For type check. */ \
unsigned *q = &p->n_ref; \
assert(*q > 0); \
assert_se(*q < UINT_MAX); \
\
(*q)++; \
return p; \
}
#define _DEFINE_TRIVIAL_UNREF_FUNC(type, name, free_func, scope) \
scope type *name##_unref(type *p) { \
if (!p) \
return NULL; \
\
assert(p->n_ref > 0); \
p->n_ref--; \
if (p->n_ref > 0) \
return NULL; \
\
return free_func(p); \
}
#define DEFINE_TRIVIAL_REF_FUNC(type, name) \
_DEFINE_TRIVIAL_REF_FUNC(type, name,)
#define DEFINE_PRIVATE_TRIVIAL_REF_FUNC(type, name) \
_DEFINE_TRIVIAL_REF_FUNC(type, name, static)
#define DEFINE_PUBLIC_TRIVIAL_REF_FUNC(type, name) \
_DEFINE_TRIVIAL_REF_FUNC(type, name, _public_)
#define DEFINE_TRIVIAL_UNREF_FUNC(type, name, free_func) \
_DEFINE_TRIVIAL_UNREF_FUNC(type, name, free_func,)
#define DEFINE_PRIVATE_TRIVIAL_UNREF_FUNC(type, name, free_func) \
_DEFINE_TRIVIAL_UNREF_FUNC(type, name, free_func, static)
#define DEFINE_PUBLIC_TRIVIAL_UNREF_FUNC(type, name, free_func) \
_DEFINE_TRIVIAL_UNREF_FUNC(type, name, free_func, _public_)
#define DEFINE_TRIVIAL_REF_UNREF_FUNC(type, name, free_func) \
DEFINE_TRIVIAL_REF_FUNC(type, name); \
DEFINE_TRIVIAL_UNREF_FUNC(type, name, free_func);
#define DEFINE_PRIVATE_TRIVIAL_REF_UNREF_FUNC(type, name, free_func) \
DEFINE_PRIVATE_TRIVIAL_REF_FUNC(type, name); \
DEFINE_PRIVATE_TRIVIAL_UNREF_FUNC(type, name, free_func);
#define DEFINE_PUBLIC_TRIVIAL_REF_UNREF_FUNC(type, name, free_func) \
DEFINE_PUBLIC_TRIVIAL_REF_FUNC(type, name); \
DEFINE_PUBLIC_TRIVIAL_UNREF_FUNC(type, name, free_func);
/* A macro to force copying of a variable from memory. This is useful whenever we want to read something from
* memory and want to make sure the compiler won't optimize away the destination variable for us. It's not
* supposed to be a full CPU memory barrier, i.e. CPU is still allowed to reorder the reads, but it is not
+53
View File
@@ -120,3 +120,56 @@ static inline void erase_char(char *p) {
/* Makes a copy of the buffer with reversed order of bytes */
void* memdup_reverse(const void *mem, size_t size);
#define _DEFINE_TRIVIAL_REF_FUNC(type, name, scope) \
scope type *name##_ref(type *p) { \
if (!p) \
return NULL; \
\
/* For type check. */ \
unsigned *q = &p->n_ref; \
assert(*q > 0); \
assert_se(*q < UINT_MAX); \
\
(*q)++; \
return p; \
}
#define _DEFINE_TRIVIAL_UNREF_FUNC(type, name, free_func, scope) \
scope type *name##_unref(type *p) { \
if (!p) \
return NULL; \
\
assert(p->n_ref > 0); \
p->n_ref--; \
if (p->n_ref > 0) \
return NULL; \
\
return free_func(p); \
}
#define DEFINE_TRIVIAL_REF_FUNC(type, name) \
_DEFINE_TRIVIAL_REF_FUNC(type, name,)
#define DEFINE_PRIVATE_TRIVIAL_REF_FUNC(type, name) \
_DEFINE_TRIVIAL_REF_FUNC(type, name, static)
#define DEFINE_PUBLIC_TRIVIAL_REF_FUNC(type, name) \
_DEFINE_TRIVIAL_REF_FUNC(type, name, _public_)
#define DEFINE_TRIVIAL_UNREF_FUNC(type, name, free_func) \
_DEFINE_TRIVIAL_UNREF_FUNC(type, name, free_func,)
#define DEFINE_PRIVATE_TRIVIAL_UNREF_FUNC(type, name, free_func) \
_DEFINE_TRIVIAL_UNREF_FUNC(type, name, free_func, static)
#define DEFINE_PUBLIC_TRIVIAL_UNREF_FUNC(type, name, free_func) \
_DEFINE_TRIVIAL_UNREF_FUNC(type, name, free_func, _public_)
#define DEFINE_TRIVIAL_REF_UNREF_FUNC(type, name, free_func) \
DEFINE_TRIVIAL_REF_FUNC(type, name); \
DEFINE_TRIVIAL_UNREF_FUNC(type, name, free_func);
#define DEFINE_PRIVATE_TRIVIAL_REF_UNREF_FUNC(type, name, free_func) \
DEFINE_PRIVATE_TRIVIAL_REF_FUNC(type, name); \
DEFINE_PRIVATE_TRIVIAL_UNREF_FUNC(type, name, free_func);
#define DEFINE_PUBLIC_TRIVIAL_REF_UNREF_FUNC(type, name, free_func) \
DEFINE_PUBLIC_TRIVIAL_REF_FUNC(type, name); \
DEFINE_PUBLIC_TRIVIAL_UNREF_FUNC(type, name, free_func);
-36
View File
@@ -521,42 +521,6 @@ static inline uint64_t ALIGN_OFFSET_U64(uint64_t l, uint64_t ali) {
#define FLAGS_SET(v, flags) \
((~(v) & (flags)) == 0)
/* A wrapper for 'func' to return void.
* Only useful when a void-returning function is required by some API. */
#define DEFINE_TRIVIAL_DESTRUCTOR(name, type, func) \
static inline void name(type *p) { \
func(p); \
}
/* When func() returns the void value (NULL, -1, …) of the appropriate type */
#define DEFINE_TRIVIAL_CLEANUP_FUNC(type, func) \
static inline void func##p(type *p) { \
if (*p) \
*p = func(*p); \
}
/* When func() doesn't return the appropriate type, set variable to empty afterwards.
* The func() may be provided by a dynamically loaded shared library, hence add an assertion. */
#define DEFINE_TRIVIAL_CLEANUP_FUNC_FULL(type, func, empty) \
static inline void func##p(type *p) { \
if (*p != (empty)) { \
DISABLE_WARNING_ADDRESS; \
assert(func); \
REENABLE_WARNING; \
func(*p); \
*p = (empty); \
} \
}
/* When func() doesn't return the appropriate type, and is also a macro, set variable to empty afterwards. */
#define DEFINE_TRIVIAL_CLEANUP_FUNC_FULL_MACRO(type, func, empty) \
static inline void func##p(type *p) { \
if (*p != (empty)) { \
func(*p); \
*p = (empty); \
} \
}
/* Restriction/bug (see below) was fixed in GCC 15 and clang 19. */
#if __GNUC__ >= 15 || (defined(__clang__) && __clang_major__ >= 19)
#define DECLARE_FLEX_ARRAY(type, name) type name[]
+36
View File
@@ -106,3 +106,39 @@ static inline void array_cleanup(const ArrayCleanup *c) {
_f; \
}), \
}
/* A wrapper for 'func' to return void.
* Only useful when a void-returning function is required by some API. */
#define DEFINE_TRIVIAL_DESTRUCTOR(name, type, func) \
static inline void name(type *p) { \
func(p); \
}
/* When func() returns the void value (NULL, -1, …) of the appropriate type */
#define DEFINE_TRIVIAL_CLEANUP_FUNC(type, func) \
static inline void func##p(type *p) { \
if (*p) \
*p = func(*p); \
}
/* When func() doesn't return the appropriate type, set variable to empty afterwards.
* The func() may be provided by a dynamically loaded shared library, hence add an assertion. */
#define DEFINE_TRIVIAL_CLEANUP_FUNC_FULL(type, func, empty) \
static inline void func##p(type *p) { \
if (*p != (empty)) { \
DISABLE_WARNING_ADDRESS; \
assert(func); \
REENABLE_WARNING; \
func(*p); \
*p = (empty); \
} \
}
/* When func() doesn't return the appropriate type, and is also a macro, set variable to empty afterwards. */
#define DEFINE_TRIVIAL_CLEANUP_FUNC_FULL_MACRO(type, func, empty) \
static inline void func##p(type *p) { \
if (*p != (empty)) { \
func(*p); \
*p = (empty); \
} \
}
@@ -6,6 +6,7 @@
#include "sd-id128.h"
#include "macro.h"
#include "memory-util.h"
typedef struct KernelHibernateLocation KernelHibernateLocation;
+1
View File
@@ -5,6 +5,7 @@
#include <netinet/in.h>
#include "macro.h"
#include "memory-util.h"
#include "time-util.h"
typedef struct ICMP6Pakcet {
+1
View File
@@ -4,6 +4,7 @@
#include "libudev.h"
#include "macro.h"
#include "memory-util.h"
/* Cleanup functions */
DEFINE_TRIVIAL_CLEANUP_FUNC(struct udev*, udev_unref);
+1
View File
@@ -4,6 +4,7 @@
#include <stdbool.h>
#include "macro.h"
#include "memory-util.h"
#if HAVE_VMLINUX_H
#include "bpf/userns_restrict/userns-restrict-skel.h"
+1
View File
@@ -5,6 +5,7 @@
#include "list.h"
#include "macro.h"
#include "memory-util.h"
typedef struct DnsSearchDomain DnsSearchDomain;
typedef struct Link Link;
+1
View File
@@ -13,6 +13,7 @@ int fd_acl_make_writable_fallback(int fd);
#include <sys/acl.h>
#include "macro.h"
#include "memory-util.h"
int acl_find_uid(acl_t acl, uid_t uid, acl_entry_t *entry);
int calc_acl_mask_if_needed(acl_t *acl_p);
+2
View File
@@ -8,6 +8,8 @@
#if HAVE_APPARMOR
# include <sys/apparmor.h>
#include "memory-util.h"
extern DLSYM_PROTOTYPE(aa_change_onexec);
extern DLSYM_PROTOTYPE(aa_change_profile);
extern DLSYM_PROTOTYPE(aa_features_new_from_kernel);
+1
View File
@@ -5,6 +5,7 @@
#include <stdint.h>
#include <sys/types.h>
#include "memory-util.h"
#include "macro.h"
/* See source file for an API description. */
+1
View File
@@ -4,6 +4,7 @@
#include "sd-bus.h"
#include "macro.h"
#include "memory-util.h"
typedef struct BusWaitForJobs BusWaitForJobs;
+1
View File
@@ -2,6 +2,7 @@
#pragma once
#include "macro.h"
#include "memory-util.h"
#include "sd-bus.h"
typedef struct BusWaitForUnits BusWaitForUnits;
+1
View File
@@ -6,6 +6,7 @@
#include <stdbool.h>
#include "memory-util.h"
#include "time-util.h"
typedef struct CalendarComponent {
+1
View File
@@ -8,6 +8,7 @@
#include "sd-json.h"
#include "macro.h"
#include "memory-util.h"
#include "pager.h"
typedef enum TableDataType {
+2
View File
@@ -7,6 +7,8 @@
#include <archive.h>
#include <archive_entry.h>
#include "memory-util.h"
extern DLSYM_PROTOTYPE(archive_entry_free);
extern DLSYM_PROTOTYPE(archive_entry_new);
extern DLSYM_PROTOTYPE(archive_entry_set_ctime);
+1
View File
@@ -6,6 +6,7 @@
#include "fstab-util.h"
#include "macro.h"
#include "memory-util.h"
DEFINE_TRIVIAL_CLEANUP_FUNC_FULL(struct libmnt_table*, mnt_free_table, NULL);
DEFINE_TRIVIAL_CLEANUP_FUNC_FULL(struct libmnt_iter*, mnt_free_iter, NULL);
+1
View File
@@ -8,6 +8,7 @@
#include <libkmod.h>
#include "macro.h"
#include "memory-util.h"
extern DLSYM_PROTOTYPE(kmod_list_next);
extern DLSYM_PROTOTYPE(kmod_load_resources);
+1
View File
@@ -3,6 +3,7 @@
#include "list.h"
#include "macro.h"
#include "memory-util.h"
typedef enum OpenFileFlag {
OPENFILE_READ_ONLY = 1 << 0,
+2
View File
@@ -12,6 +12,8 @@
#if HAVE_SELINUX
#include <selinux/selinux.h>
#include "memory-util.h"
DEFINE_TRIVIAL_CLEANUP_FUNC_FULL(char*, freecon, NULL);
#else
static inline void freeconp(char **p) {
+1
View File
@@ -4,6 +4,7 @@
#include "sd-event.h"
#include "macro.h"
#include "memory-util.h"
#include "time-util.h"
typedef struct UdevCtrl UdevCtrl;
@@ -2,6 +2,7 @@
#pragma once
#include "macro.h"
#include "memory-util.h"
typedef struct XdgAutostartService {
char *name;