]> git.ipfire.org Git - thirdparty/util-linux.git/blob - include/c.h
include/c: use returns_nonnull function attribute in xalloc.h
[thirdparty/util-linux.git] / include / c.h
1 /*
2 * Fundamental C definitions.
3 */
4
5 #ifndef UTIL_LINUX_C_H
6 #define UTIL_LINUX_C_H
7
8 #include <limits.h>
9 #include <stddef.h>
10 #include <stdint.h>
11 #include <stdio.h>
12 #include <unistd.h>
13 #include <stdarg.h>
14 #include <stdlib.h>
15 #include <string.h>
16 #include <errno.h>
17
18 #include <assert.h>
19
20 #ifdef HAVE_ERR_H
21 # include <err.h>
22 #endif
23
24 #ifdef HAVE_SYS_SYSMACROS_H
25 # include <sys/sysmacros.h> /* for major, minor */
26 #endif
27
28 #ifndef LOGIN_NAME_MAX
29 # define LOGIN_NAME_MAX 256
30 #endif
31
32 #ifndef NAME_MAX
33 # define NAME_MAX PATH_MAX
34 #endif
35
36 /*
37 * Compiler-specific stuff
38 */
39 #ifndef __GNUC_PREREQ
40 # if defined __GNUC__ && defined __GNUC_MINOR__
41 # define __GNUC_PREREQ(maj, min) \
42 ((__GNUC__ << 16) + __GNUC_MINOR__ >= ((maj) << 16) + (min))
43 # else
44 # define __GNUC_PREREQ(maj, min) 0
45 # endif
46 #endif
47
48 #ifdef __GNUC__
49
50 /* &a[0] degrades to a pointer: a different type from an array */
51 # define __must_be_array(a) \
52 UL_BUILD_BUG_ON_ZERO(__builtin_types_compatible_p(__typeof__(a), __typeof__(&a[0])))
53
54 # define ignore_result(x) __extension__ ({ \
55 __typeof__(x) __dummy __attribute__((__unused__)) = (x); (void) __dummy; \
56 })
57
58 #else /* !__GNUC__ */
59 # define __must_be_array(a) 0
60 # define __attribute__(_arg_)
61 # define ignore_result(x) ((void) (x))
62 #endif /* !__GNUC__ */
63
64 /*
65 * Function attributes
66 */
67 #ifndef __ul_alloc_size
68 # if __GNUC_PREREQ (4, 3)
69 # define __ul_alloc_size(s) __attribute__((alloc_size(s), warn_unused_result))
70 # else
71 # define __ul_alloc_size(s)
72 # endif
73 #endif
74
75 #ifndef __ul_calloc_size
76 # if __GNUC_PREREQ (4, 3)
77 # define __ul_calloc_size(n, s) __attribute__((alloc_size(n, s), warn_unused_result))
78 # else
79 # define __ul_calloc_size(n, s)
80 # endif
81 #endif
82
83 #if (__GNUC__ >= 5) || ((__GNUC__ >= 4) && (__GNUC_MINOR__ >= 9))
84 # define __ul_returns_nonnull __attribute__((returns_nonnull))
85 #else
86 # define __ul_returns_nonnull
87 #endif
88
89 /*
90 * Force a compilation error if condition is true, but also produce a
91 * result (of value 0 and type size_t), so the expression can be used
92 * e.g. in a structure initializer (or wherever else comma expressions
93 * aren't permitted).
94 */
95 #define UL_BUILD_BUG_ON_ZERO(e) __extension__ (sizeof(struct { int:-!!(e); }))
96 #define BUILD_BUG_ON_NULL(e) ((void *)sizeof(struct { int:-!!(e); }))
97
98 #ifndef ARRAY_SIZE
99 # define ARRAY_SIZE(arr) (sizeof(arr) / sizeof((arr)[0]) + __must_be_array(arr))
100 #endif
101
102 #ifndef PATH_MAX
103 # define PATH_MAX 4096
104 #endif
105
106 #ifndef TRUE
107 # define TRUE 1
108 #endif
109
110 #ifndef FALSE
111 # define FALSE 0
112 #endif
113
114 #ifndef min
115 # define min(x, y) __extension__ ({ \
116 __typeof__(x) _min1 = (x); \
117 __typeof__(y) _min2 = (y); \
118 (void) (&_min1 == &_min2); \
119 _min1 < _min2 ? _min1 : _min2; })
120 #endif
121
122 #ifndef max
123 # define max(x, y) __extension__ ({ \
124 __typeof__(x) _max1 = (x); \
125 __typeof__(y) _max2 = (y); \
126 (void) (&_max1 == &_max2); \
127 _max1 > _max2 ? _max1 : _max2; })
128 #endif
129
130 #ifndef cmp_numbers
131 # define cmp_numbers(x, y) __extension__ ({ \
132 __typeof__(x) _a = (x); \
133 __typeof__(y) _b = (y); \
134 (void) (&_a == &_b); \
135 _a == _b ? 0 : _a > _b ? 1 : -1; })
136 #endif
137
138 #ifndef offsetof
139 #define offsetof(TYPE, MEMBER) ((size_t) &((TYPE *)0)->MEMBER)
140 #endif
141
142 /*
143 * container_of - cast a member of a structure out to the containing structure
144 * @ptr: the pointer to the member.
145 * @type: the type of the container struct this is embedded in.
146 * @member: the name of the member within the struct.
147 */
148 #ifndef container_of
149 #define container_of(ptr, type, member) __extension__ ({ \
150 void *__mptr = (void *)(ptr); \
151 ((type *)(__mptr - offsetof(type, member))); })
152 #endif
153
154 #ifndef HAVE_PROGRAM_INVOCATION_SHORT_NAME
155 # ifdef HAVE___PROGNAME
156 extern char *__progname;
157 # define program_invocation_short_name __progname
158 # else
159 # ifdef HAVE_GETEXECNAME
160 # define program_invocation_short_name \
161 prog_inv_sh_nm_from_file(getexecname(), 0)
162 # else
163 # define program_invocation_short_name \
164 prog_inv_sh_nm_from_file(__FILE__, 1)
165 # endif
166 static char prog_inv_sh_nm_buf[256];
167 static inline char *
168 prog_inv_sh_nm_from_file(char *f, char stripext)
169 {
170 char *t;
171
172 if ((t = strrchr(f, '/')) != NULL)
173 t++;
174 else
175 t = f;
176
177 strncpy(prog_inv_sh_nm_buf, t, sizeof(prog_inv_sh_nm_buf) - 1);
178 prog_inv_sh_nm_buf[sizeof(prog_inv_sh_nm_buf) - 1] = '\0';
179
180 if (stripext && (t = strrchr(prog_inv_sh_nm_buf, '.')) != NULL)
181 *t = '\0';
182
183 return prog_inv_sh_nm_buf;
184 }
185 # endif
186 #endif
187
188
189 #ifndef HAVE_ERR_H
190 static inline void
191 errmsg(char doexit, int excode, char adderr, const char *fmt, ...)
192 {
193 fprintf(stderr, "%s: ", program_invocation_short_name);
194 if (fmt != NULL) {
195 va_list argp;
196 va_start(argp, fmt);
197 vfprintf(stderr, fmt, argp);
198 va_end(argp);
199 if (adderr)
200 fprintf(stderr, ": ");
201 }
202 if (adderr)
203 fprintf(stderr, "%m");
204 fprintf(stderr, "\n");
205 if (doexit)
206 exit(excode);
207 }
208
209 #ifndef HAVE_ERR
210 # define err(E, FMT...) errmsg(1, E, 1, FMT)
211 #endif
212
213 #ifndef HAVE_ERRX
214 # define errx(E, FMT...) errmsg(1, E, 0, FMT)
215 #endif
216
217 #ifndef HAVE_WARN
218 # define warn(FMT...) errmsg(0, 0, 1, FMT)
219 #endif
220
221 #ifndef HAVE_WARNX
222 # define warnx(FMT...) errmsg(0, 0, 0, FMT)
223 #endif
224 #endif /* !HAVE_ERR_H */
225
226
227 /* Don't use inline function to avoid '#include "nls.h"' in c.h
228 */
229 #define errtryhelp(eval) __extension__ ({ \
230 fprintf(stderr, _("Try '%s --help' for more information.\n"), \
231 program_invocation_short_name); \
232 exit(eval); \
233 })
234
235 /* After failed execvp() */
236 #define EX_EXEC_FAILED 126 /* Program located, but not usable. */
237 #define EX_EXEC_ENOENT 127 /* Could not find program to exec. */
238 #define errexec(name) err(errno == ENOENT ? EX_EXEC_ENOENT : EX_EXEC_FAILED, \
239 _("failed to execute %s"), name)
240
241
242 static inline __attribute__((const)) int is_power_of_2(unsigned long num)
243 {
244 return (num != 0 && ((num & (num - 1)) == 0));
245 }
246
247 #ifndef HAVE_LOFF_T
248 typedef int64_t loff_t;
249 #endif
250
251 #if !defined(HAVE_DIRFD) && (!defined(HAVE_DECL_DIRFD) || HAVE_DECL_DIRFD == 0) && defined(HAVE_DIR_DD_FD)
252 #include <sys/types.h>
253 #include <dirent.h>
254 static inline int dirfd(DIR *d)
255 {
256 return d->dd_fd;
257 }
258 #endif
259
260 /*
261 * Fallback defines for old versions of glibc
262 */
263 #include <fcntl.h>
264
265 #ifdef O_CLOEXEC
266 #define UL_CLOEXECSTR "e"
267 #else
268 #define UL_CLOEXECSTR ""
269 #endif
270
271 #ifndef O_CLOEXEC
272 #define O_CLOEXEC 0
273 #endif
274
275 #ifdef __FreeBSD_kernel__
276 #ifndef F_DUPFD_CLOEXEC
277 #define F_DUPFD_CLOEXEC 17 /* Like F_DUPFD, but FD_CLOEXEC is set */
278 #endif
279 #endif
280
281
282 #ifndef AI_ADDRCONFIG
283 #define AI_ADDRCONFIG 0x0020
284 #endif
285
286 #ifndef IUTF8
287 #define IUTF8 0040000
288 #endif
289
290 /*
291 * MAXHOSTNAMELEN replacement
292 */
293 static inline size_t get_hostname_max(void)
294 {
295 long len = sysconf(_SC_HOST_NAME_MAX);
296
297 if (0 < len)
298 return len;
299
300 #ifdef MAXHOSTNAMELEN
301 return MAXHOSTNAMELEN;
302 #elif HOST_NAME_MAX
303 return HOST_NAME_MAX;
304 #endif
305 return 64;
306 }
307
308 /*
309 * The usleep function was marked obsolete in POSIX.1-2001 and was removed
310 * in POSIX.1-2008. It was replaced with nanosleep() that provides more
311 * advantages (like no interaction with signals and other timer functions).
312 */
313 #include <time.h>
314
315 static inline int xusleep(useconds_t usec)
316 {
317 #ifdef HAVE_NANOSLEEP
318 struct timespec waittime = {
319 .tv_sec = usec / 1000000L,
320 .tv_nsec = (usec % 1000000L) * 1000
321 };
322 return nanosleep(&waittime, NULL);
323 #elif defined(HAVE_USLEEP)
324 return usleep(usec);
325 #else
326 # error "System with usleep() or nanosleep() required!"
327 #endif
328 }
329
330 /*
331 * Constant strings for usage() functions. For more info see
332 * Documentation/{howto-usage-function.txt,boilerplate.c}
333 */
334 #define USAGE_HEADER _("\nUsage:\n")
335 #define USAGE_OPTIONS _("\nOptions:\n")
336 #define USAGE_FUNCTIONS _("\nFunctions:\n")
337 #define USAGE_COMMANDS _("\nCommands:\n")
338 #define USAGE_COLUMNS _("\nAvailable output columns:\n")
339 #define USAGE_SEPARATOR "\n"
340
341 #define USAGE_OPTSTR_HELP _("display this help")
342 #define USAGE_OPTSTR_VERSION _("display version")
343
344 #define USAGE_HELP_OPTIONS(marg_dsc) \
345 "%-" #marg_dsc "s%s\n" \
346 "%-" #marg_dsc "s%s\n" \
347 , " -h, --help", USAGE_OPTSTR_HELP \
348 , " -V, --version", USAGE_OPTSTR_VERSION
349
350 #define USAGE_MAN_TAIL(_man) _("\nFor more details see %s.\n"), _man
351
352 #define UTIL_LINUX_VERSION _("%s from %s\n"), program_invocation_short_name, PACKAGE_STRING
353
354 /*
355 * scanf modifiers for "strings allocation"
356 */
357 #ifdef HAVE_SCANF_MS_MODIFIER
358 #define UL_SCNsA "%ms"
359 #elif defined(HAVE_SCANF_AS_MODIFIER)
360 #define UL_SCNsA "%as"
361 #endif
362
363 /*
364 * seek stuff
365 */
366 #ifndef SEEK_DATA
367 # define SEEK_DATA 3
368 #endif
369 #ifndef SEEK_HOLE
370 # define SEEK_HOLE 4
371 #endif
372
373
374 /*
375 * Macros to convert #define'itions to strings, for example
376 * #define XYXXY 42
377 * printf ("%s=%s\n", stringify(XYXXY), stringify_value(XYXXY));
378 */
379 #define stringify_value(s) stringify(s)
380 #define stringify(s) #s
381
382 /*
383 * UL_ASAN_BLACKLIST is a macro to tell AddressSanitizer (a compile-time
384 * instrumentation shipped with Clang and GCC) to not instrument the
385 * annotated function. Furthermore, it will prevent the compiler from
386 * inlining the function because inlining currently breaks the blacklisting
387 * mechanism of AddressSanitizer.
388 */
389 #if defined(__has_feature)
390 # if __has_feature(address_sanitizer)
391 # define UL_ASAN_BLACKLIST __attribute__((noinline)) __attribute__((no_sanitize_memory)) __attribute__((no_sanitize_address))
392 # else
393 # define UL_ASAN_BLACKLIST /* nothing */
394 # endif
395 #else
396 # define UL_ASAN_BLACKLIST /* nothing */
397 #endif
398
399
400
401 /*
402 * Note that sysconf(_SC_GETPW_R_SIZE_MAX) returns *initial* suggested size for
403 * pwd buffer and in some cases it is not large enough. See POSIX and
404 * getpwnam_r man page for more details.
405 */
406 #define UL_GETPW_BUFSIZ (16 * 1024)
407
408 /*
409 * Darwin or other BSDs may only have MAP_ANON. To get it on Darwin we must
410 * define _DARWIN_C_SOURCE before including sys/mman.h. We do this in config.h.
411 */
412 #if !defined MAP_ANONYMOUS && defined MAP_ANON
413 # define MAP_ANONYMOUS (MAP_ANON)
414 #endif
415
416 #endif /* UTIL_LINUX_C_H */