]> git.proxmox.com Git - mirror_lxc.git/blob - src/lxc/memory_utils.h
start: check event loop type before closing fd
[mirror_lxc.git] / src / lxc / memory_utils.h
1 /* SPDX-License-Identifier: LGPL-2.1+ */
2
3 #ifndef __LXC_MEMORY_UTILS_H
4 #define __LXC_MEMORY_UTILS_H
5
6 #include "config.h"
7
8 #include <dirent.h>
9 #include <errno.h>
10 #include <stdio.h>
11 #include <stdlib.h>
12 #include <sys/types.h>
13 #include <unistd.h>
14
15 #include "macro.h"
16 #include "error_utils.h"
17
18 #define define_cleanup_function(type, cleaner) \
19 static inline void cleaner##_function(type *ptr) \
20 { \
21 if (*ptr) \
22 cleaner(*ptr); \
23 }
24
25 #define call_cleaner(cleaner) \
26 __attribute__((__cleanup__(cleaner##_function))) __attribute__((unused))
27
28 #define close_prot_errno_disarm(fd) \
29 if (fd >= 0) { \
30 int _e_ = errno; \
31 close(fd); \
32 errno = _e_; \
33 fd = -EBADF; \
34 }
35
36 #define close_prot_errno_move(fd, new_fd) \
37 if (fd >= 0) { \
38 int _e_ = errno; \
39 close(fd); \
40 errno = _e_; \
41 fd = new_fd; \
42 new_fd = -EBADF; \
43 }
44
45 static inline void close_prot_errno_disarm_function(int *fd)
46 {
47 close_prot_errno_disarm(*fd);
48 }
49 #define __do_close call_cleaner(close_prot_errno_disarm)
50
51 define_cleanup_function(FILE *, fclose);
52 #define __do_fclose call_cleaner(fclose)
53
54 define_cleanup_function(DIR *, closedir);
55 #define __do_closedir call_cleaner(closedir)
56
57 #define free_disarm(ptr) \
58 ({ \
59 if (!IS_ERR_OR_NULL(ptr)) { \
60 free(ptr); \
61 ptr = NULL; \
62 } \
63 })
64
65 static inline void free_disarm_function(void *ptr)
66 {
67 free_disarm(*(void **)ptr);
68 }
69 #define __do_free call_cleaner(free_disarm)
70
71 static inline void free_string_list(char **list)
72 {
73 if (list && !IS_ERR(list)) {
74 for (int i = 0; list[i]; i++)
75 free(list[i]);
76 free_disarm(list);
77 }
78 }
79 define_cleanup_function(char **, free_string_list);
80 #define __do_free_string_list call_cleaner(free_string_list)
81
82 static inline void *memdup(const void *data, size_t len)
83 {
84 void *copy = NULL;
85
86 copy = len ? malloc(len) : NULL;
87 return copy ? memcpy(copy, data, len) : NULL;
88 }
89
90 #define zalloc(__size__) (calloc(1, __size__))
91
92 #define free_move_ptr(a, b) \
93 ({ \
94 free(a); \
95 (a) = move_ptr((b)); \
96 })
97
98 #define close_move_fd(a, b) \
99 ({ \
100 close(a); \
101 (a) = move_fd((b)); \
102 })
103
104 #define close_equal(a, b) \
105 ({ \
106 if (a >= 0 && a != b) \
107 close(a); \
108 if (b >= 0) \
109 close(b); \
110 a = b = -EBADF; \
111 })
112
113 #define free_equal(a, b) \
114 ({ \
115 if (a != b) \
116 free(a); \
117 free(b); \
118 a = b = NULL; \
119 })
120
121 #endif /* __LXC_MEMORY_UTILS_H */