1 /*
2 * SPDX-License-Identifier: LGPL-2.1-or-later
3 *
4 * Copyright (C) 2010 Davidlohr Bueso <dave@gnu.org>
5 * Copyright (C) 2010-2022 Karel Zak <kzak@redhat.com>
6 *
7 * This file may be redistributed under the terms of the
8 * GNU Lesser General Public License.
9 *
10 * General memory allocation wrappers for malloc, realloc, calloc and strdup
11 */
12
13 #ifndef UTIL_LINUX_XALLOC_H
14 #define UTIL_LINUX_XALLOC_H
15
16 #include <stdlib.h>
17 #include <string.h>
18
19 #include "c.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(1, 2)
51 __ul_returns_nonnull
52 void *xcalloc(const size_t nelems, const size_t size)
53 {
54 void *ret = calloc(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 __attribute__((warn_unused_result))
63 __ul_returns_nonnull
64 char *xstrdup(const char *str)
65 {
66 char *ret;
67
68 assert(str);
69 ret = strdup(str);
70 if (!ret)
71 err(XALLOC_EXIT_CODE, "cannot duplicate string");
72 return ret;
73 }
74
75 static inline
76 __attribute__((warn_unused_result))
77 __ul_returns_nonnull
78 char *xstrndup(const char *str, size_t size)
79 {
80 char *ret;
81
82 assert(str);
83 ret = strndup(str, size);
84 if (!ret)
85 err(XALLOC_EXIT_CODE, "cannot duplicate string");
86 return ret;
87 }
88
89
90 static inline
91 __attribute__((__format__(printf, 2, 3)))
92 int xasprintf(char **strp, const char *fmt, ...)
93 {
94 int ret;
95 va_list args;
96
97 va_start(args, fmt);
98 ret = vasprintf(&(*strp), fmt, args);
99 va_end(args);
100 if (ret < 0)
101 err(XALLOC_EXIT_CODE, "cannot allocate string");
102 return ret;
103 }
104
105 static inline
106 __attribute__((__format__(printf, 2, 0)))
107 int xvasprintf(char **strp, const char *fmt, va_list ap)
108 {
109 int ret = vasprintf(&(*strp), fmt, ap);
110
111 if (ret < 0)
112 err(XALLOC_EXIT_CODE, "cannot allocate string");
113 return ret;
114 }
115
116
117 static inline
118 __attribute__((warn_unused_result))
119 char *xgethostname(void)
120 {
121 char *name;
122 size_t sz = get_hostname_max() + 1;
123
124 name = xmalloc(sizeof(char) * sz);
125 if (gethostname(name, sz) != 0) {
126 free(name);
127 return NULL;
128 }
129 name[sz - 1] = '\0';
130 return name;
131 }
132
133 #endif