5 #ifndef SPA_UTILS_CLEANUP_H 6 #define SPA_UTILS_CLEANUP_H 8 #define spa_exchange(var, new_value) \ 10 __typeof__(var) *_ptr_ = &(var); \ 11 __typeof__(var) _old_value_ = *_ptr_; \ 12 *_ptr_ = (new_value); \ 18 #if __GNUC__ >= 10 || defined(__clang__) 19 #define spa_steal_ptr(ptr) ((__typeof__(*(ptr)) *) spa_exchange((ptr), NULL)) 21 #define spa_steal_ptr(ptr) spa_exchange((ptr), NULL) 24 #define spa_clear_ptr(ptr, destructor) \ 26 __typeof__(ptr) _old_value = spa_steal_ptr(ptr); \ 28 destructor(_old_value); \ 37 #define spa_steal_fd(fd) spa_exchange((fd), -1) 39 #define spa_clear_fd(fd) \ 41 int _old_value = spa_steal_fd(fd), _res = 0; \ 42 if (_old_value >= 0) \ 43 _res = close(_old_value); \ 49 #if defined(__has_attribute) && __has_attribute(__cleanup__) 51 #define spa_cleanup(func) __attribute__((__cleanup__(func))) 53 #define SPA_DEFINE_AUTO_CLEANUP(name, type, ...) \ 54 typedef __typeof__(type) _spa_auto_cleanup_type_ ## name; \ 55 static inline void _spa_auto_cleanup_func_ ## name (__typeof__(type) *thing) \ 57 int _save_errno = errno; \ 59 errno = _save_errno; \ 62 #define spa_auto(name) \ 63 spa_cleanup(_spa_auto_cleanup_func_ ## name) \ 64 _spa_auto_cleanup_type_ ## name 66 #define SPA_DEFINE_AUTOPTR_CLEANUP(name, type, ...) \ 67 typedef __typeof__(type) * _spa_autoptr_cleanup_type_ ## name; \ 68 static inline void _spa_autoptr_cleanup_func_ ## name (__typeof__(type) **thing) \ 70 int _save_errno = errno; \ 72 errno = _save_errno; \ 75 #define spa_autoptr(name) \ 76 spa_cleanup(_spa_autoptr_cleanup_func_ ## name) \ 77 _spa_autoptr_cleanup_type_ ## name 83 static inline void _spa_autofree_cleanup_func(
void *p)
85 int save_errno = errno;
89 #define spa_autofree spa_cleanup(_spa_autofree_cleanup_func) 93 static inline void _spa_autoclose_cleanup_func(
int *fd)
95 int save_errno = errno;
99 #define spa_autoclose spa_cleanup(_spa_autoclose_cleanup_func) 105 SPA_DEFINE_AUTOPTR_CLEANUP(FILE, FILE, {
106 spa_clear_ptr(*thing, fclose);
113 SPA_DEFINE_AUTOPTR_CLEANUP(DIR, DIR, {
114 spa_clear_ptr(*thing, closedir);
119 #define SPA_DEFINE_AUTO_CLEANUP(name, type, ...)
120 #define SPA_DEFINE_AUTOPTR_CLEANUP(name, type, ...)