]> git.ipfire.org Git - thirdparty/util-linux.git/blob - include/xalloc.h
c620a4921dd2998707c585b62b3cca23722b00d1
[thirdparty/util-linux.git] / include / xalloc.h
1 /*
2 * No copyright is claimed. This code is in the public domain; do with
3 * it what you wish.
4 *
5 * Authors 2010 Davidlohr Bueso <dave@gnu.org>
6 * 2010-2025 Karel Zak <kzak@redhat.com>
7 *
8 * General memory allocation wrappers for malloc, realloc, calloc and strdup
9 */
10
11 #ifndef UTIL_LINUX_XALLOC_H
12 #define UTIL_LINUX_XALLOC_H
13
14 #include <stdio.h>
15 #include <stdlib.h>
16 #include <string.h>
17
18 #include "c.h"
19 #include "strutils.h"
20
21 #ifndef XALLOC_EXIT_CODE
22 # define XALLOC_EXIT_CODE EXIT_FAILURE
23 #endif
24
25 static inline
26 __ul_alloc_size(1)
27 __ul_returns_nonnull
28 void *xmalloc(const size_t size)
29 {
30 void *ret = malloc(size);
31
32 if (!ret && size)
33 err(XALLOC_EXIT_CODE, "cannot allocate %zu bytes", size);
34 return ret;
35 }
36
37 static inline
38 __ul_alloc_size(2)
39 __ul_returns_nonnull
40 void *xrealloc(void *ptr, const size_t size)
41 {
42 void *ret = realloc(ptr, size);
43
44 if (!ret && size)
45 err(XALLOC_EXIT_CODE, "cannot allocate %zu bytes", size);
46 return ret;
47 }
48
49 static inline
50 __ul_calloc_size(2, 3)
51 __ul_returns_nonnull
52 void *xreallocarray(void *ptr, const size_t nelems, const size_t size)
53 {
54 void *ret = reallocarray(ptr, nelems, size);
55
56 if (!ret && size && nelems)
57 err(XALLOC_EXIT_CODE, "cannot allocate %zu bytes", size);
58 return ret;
59 }
60
61 static inline
62 __ul_calloc_size(1, 2)
63 __ul_returns_nonnull
64 void *xcalloc(const size_t nelems, const size_t size)
65 {
66 void *ret = calloc(nelems, size);
67
68 if (!ret && size && nelems)
69 err(XALLOC_EXIT_CODE, "cannot allocate %zu bytes", size);
70 return ret;
71 }
72
73 static inline
74 __attribute__((warn_unused_result))
75 __ul_alloc_size(2)
76 __ul_returns_nonnull
77 void *xmemdup(const void *ptr, size_t size)
78 {
79 void *ret = xmalloc(size);
80
81 memcpy(ret, ptr, size);
82 return ret;
83 }
84
85 static inline
86 __attribute__((warn_unused_result))
87 __ul_returns_nonnull
88 char *xstrdup(const char *str)
89 {
90 char *ret;
91
92 assert(str);
93 ret = strdup(str);
94 if (!ret)
95 err(XALLOC_EXIT_CODE, "cannot duplicate string");
96 return ret;
97 }
98
99 static inline
100 __attribute__((warn_unused_result))
101 __ul_returns_nonnull
102 char *xstrndup(const char *str, size_t size)
103 {
104 char *ret;
105
106 assert(str);
107 ret = strndup(str, size);
108 if (!ret)
109 err(XALLOC_EXIT_CODE, "cannot duplicate string");
110 return ret;
111 }
112
113
114 static inline
115 __attribute__((__format__(printf, 2, 3)))
116 int xasprintf(char **strp, const char *fmt, ...)
117 {
118 int ret;
119 va_list args;
120
121 va_start(args, fmt);
122 ret = vasprintf(&(*strp), fmt, args);
123 va_end(args);
124 if (ret < 0)
125 err(XALLOC_EXIT_CODE, "cannot allocate string");
126 return ret;
127 }
128
129 static inline
130 __attribute__((__format__(printf, 2, 0)))
131 int xvasprintf(char **strp, const char *fmt, va_list ap)
132 {
133 int ret = vasprintf(&(*strp), fmt, ap);
134
135 if (ret < 0)
136 err(XALLOC_EXIT_CODE, "cannot allocate string");
137 return ret;
138 }
139
140 static inline void xstrappend(char **a, const char *b)
141 {
142 if (ul_strappend(a, b) < 0)
143 err(XALLOC_EXIT_CODE, "cannot allocate string");
144 }
145
146 static inline void xstrputc(char **a, char c)
147 {
148 char b[] = {c, '\0'};
149 xstrappend(a, b);
150 }
151
152 static inline
153 __attribute__((__format__(printf, 2, 0)))
154 int xstrvfappend(char **a, const char *format, va_list ap)
155 {
156 int ret = ul_strvfappend(a, format, ap);
157
158 if (ret < 0)
159 err(XALLOC_EXIT_CODE, "cannot allocate string");
160 return ret;
161
162 }
163
164 static inline
165 __attribute__ ((__format__ (__printf__, 2, 3)))
166 int xstrfappend(char **a, const char *format, ...)
167 {
168 va_list ap;
169 int ret;
170
171 va_start(ap, format);
172 ret = xstrvfappend(a, format, ap);
173 va_end(ap);
174
175 return ret;
176 }
177
178 static inline
179 __attribute__((warn_unused_result))
180 char *xgethostname(void)
181 {
182 char *name;
183 size_t sz = get_hostname_max() + 1;
184
185 name = xmalloc(sizeof(char) * sz);
186 if (gethostname(name, sz) != 0) {
187 free(name);
188 return NULL;
189 }
190 name[sz - 1] = '\0';
191 return name;
192 }
193
194 static inline
195 __attribute__((warn_unused_result))
196 char *xgethosturi(const char *proto)
197 {
198 char *n = xgethostname();
199 char *uri = NULL;
200
201 if (!proto)
202 proto = "file://";
203 if (!n)
204 return xstrdup(proto);
205
206 xasprintf(&uri, "%s%s", proto, n);
207 free(n);
208 return uri;
209 }
210
211 #endif