]> git.ipfire.org Git - thirdparty/util-linux.git/blame - include/c.h
include: add no return function attribute
[thirdparty/util-linux.git] / include / c.h
CommitLineData
4d0dbb8b
KZ
1/*
2 * Fundamental C definitions.
3 */
4
5#ifndef UTIL_LINUX_C_H
6#define UTIL_LINUX_C_H
7
8#include <limits.h>
aa1f95c3 9#include <stddef.h>
eb76ca98
FG
10#include <stdint.h>
11#include <stdio.h>
9199f5cd 12#include <unistd.h>
eb76ca98 13#include <stdarg.h>
4d498513 14#include <stdlib.h>
eb76ca98
FG
15#include <string.h>
16#include <errno.h>
17
2c656779
KZ
18#include <assert.h>
19
eb76ca98
FG
20#ifdef HAVE_ERR_H
21# include <err.h>
22#endif
4d0dbb8b 23
075d2c07
KZ
24#ifdef HAVE_SYS_SYSMACROS_H
25# include <sys/sysmacros.h> /* for major, minor */
26#endif
27
790119b8
KZ
28#ifndef LOGIN_NAME_MAX
29# define LOGIN_NAME_MAX 256
30#endif
31
7d5976f8
SJ
32#ifndef NAME_MAX
33# define NAME_MAX PATH_MAX
34#endif
35
4d0dbb8b 36/*
68411ba2 37 * Compiler-specific stuff
4d0dbb8b 38 */
40084d0d
KZ
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
4d0dbb8b
KZ
48#ifdef __GNUC__
49
50/* &a[0] degrades to a pointer: a different type from an array */
51# define __must_be_array(a) \
bfda68fd 52 UL_BUILD_BUG_ON_ZERO(__builtin_types_compatible_p(__typeof__(a), __typeof__(&a[0])))
4d0dbb8b 53
2a0d2a8e 54# define ignore_result(x) __extension__ ({ \
c764e1a4 55 __typeof__(x) __dummy __attribute__((__unused__)) = (x); (void) __dummy; \
c25dc28d 56})
2dd570ec 57
4d0dbb8b
KZ
58#else /* !__GNUC__ */
59# define __must_be_array(a) 0
60# define __attribute__(_arg_)
2dd570ec 61# define ignore_result(x) ((void) (x))
4d0dbb8b
KZ
62#endif /* !__GNUC__ */
63
40084d0d
KZ
64/*
65 * Function attributes
66 */
67#ifndef __ul_alloc_size
50a1e0cf 68# if __GNUC_PREREQ (4, 3)
c9678832 69# define __ul_alloc_size(s) __attribute__((alloc_size(s), warn_unused_result))
40084d0d
KZ
70# else
71# define __ul_alloc_size(s)
72# endif
73#endif
74
75#ifndef __ul_calloc_size
50a1e0cf 76# if __GNUC_PREREQ (4, 3)
c9678832 77# define __ul_calloc_size(n, s) __attribute__((alloc_size(n, s), warn_unused_result))
40084d0d
KZ
78# else
79# define __ul_calloc_size(n, s)
80# endif
81#endif
4d0dbb8b 82
3ccbdf7a 83#if __GNUC_PREREQ (4, 9)
f1b327f8
SK
84# define __ul_returns_nonnull __attribute__((returns_nonnull))
85#else
86# define __ul_returns_nonnull
87#endif
88
68411ba2
BS
89/*
90 * Force a compilation error if condition is true, but also produce a
4d0dbb8b 91 * result (of value 0 and type size_t), so the expression can be used
68411ba2 92 * e.g. in a structure initializer (or wherever else comma expressions
4d0dbb8b
KZ
93 * aren't permitted).
94 */
2a0d2a8e 95#define UL_BUILD_BUG_ON_ZERO(e) __extension__ (sizeof(struct { int:-!!(e); }))
4d0dbb8b
KZ
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
70502c52 114#ifndef min
2a0d2a8e 115# define min(x, y) __extension__ ({ \
c764e1a4
SK
116 __typeof__(x) _min1 = (x); \
117 __typeof__(y) _min2 = (y); \
1cb1641d
KZ
118 (void) (&_min1 == &_min2); \
119 _min1 < _min2 ? _min1 : _min2; })
70502c52 120#endif
1cb1641d 121
70502c52 122#ifndef max
2a0d2a8e 123# define max(x, y) __extension__ ({ \
c764e1a4
SK
124 __typeof__(x) _max1 = (x); \
125 __typeof__(y) _max2 = (y); \
1cb1641d
KZ
126 (void) (&_max1 == &_max2); \
127 _max1 > _max2 ? _max1 : _max2; })
70502c52 128#endif
1cb1641d 129
19ff8ff7
KZ
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); \
764b697c 135 _a == _b ? 0 : _a > _b ? 1 : -1; })
19ff8ff7
KZ
136#endif
137
5b9df028
DB
138#ifndef offsetof
139#define offsetof(TYPE, MEMBER) ((size_t) &((TYPE *)0)->MEMBER)
140#endif
141
eb06d5d4
KZ
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 */
ae278c88 148#ifndef container_of
eb06d5d4 149#define container_of(ptr, type, member) __extension__ ({ \
1866fa6a
RM
150 const __typeof__( ((type *)0)->member ) *__mptr = (ptr); \
151 (type *)( (char *)__mptr - offsetof(type,member) );})
ae278c88 152#endif
5b9df028 153
4b2b6716 154#ifndef HAVE_PROGRAM_INVOCATION_SHORT_NAME
155# ifdef HAVE___PROGNAME
156extern char *__progname;
157# define program_invocation_short_name __progname
158# else
159# ifdef HAVE_GETEXECNAME
4b2b6716 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
166static char prog_inv_sh_nm_buf[256];
167static inline char *
168prog_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
06ceeef8 188
eb76ca98
FG
189#ifndef HAVE_ERR_H
190static inline void
191errmsg(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)
960cf573 203 fprintf(stderr, "%m");
eb76ca98
FG
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
3077b371
KZ
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
cf654e1c
KZ
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
3077b371 241
973af806
KZ
242static inline __attribute__((const)) int is_power_of_2(unsigned long num)
243{
244 return (num != 0 && ((num & (num - 1)) == 0));
245}
246
5be1c033
FG
247#ifndef HAVE_LOFF_T
248typedef int64_t loff_t;
249#endif
250
d58c47d9
FG
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>
254static inline int dirfd(DIR *d)
255{
256 return d->dd_fd;
257}
258#endif
259
7cf78990
DB
260/*
261 * Fallback defines for old versions of glibc
262 */
e9d00e66 263#include <fcntl.h>
2ffad204
KZ
264
265#ifdef O_CLOEXEC
266#define UL_CLOEXECSTR "e"
267#else
268#define UL_CLOEXECSTR ""
269#endif
270
4799c95f
KZ
271#ifndef O_CLOEXEC
272#define O_CLOEXEC 0
273#endif
973af806 274
f51275ee
GJ
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
2ffad204 281
7cf78990
DB
282#ifndef AI_ADDRCONFIG
283#define AI_ADDRCONFIG 0x0020
284#endif
285
286#ifndef IUTF8
287#define IUTF8 0040000
288#endif
289
1ee4dff7
SK
290/*
291 * MAXHOSTNAMELEN replacement
292 */
293static 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
2a31396a 308/*
68411ba2
BS
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).
2a31396a 312 */
a5bd7939
KZ
313#include <time.h>
314
315static inline int xusleep(useconds_t usec)
2a31396a 316{
a5bd7939 317#ifdef HAVE_NANOSLEEP
2a31396a
KZ
318 struct timespec waittime = {
319 .tv_sec = usec / 1000000L,
320 .tv_nsec = (usec % 1000000L) * 1000
b33f24b2
WF
321 };
322 return nanosleep(&waittime, NULL);
a5bd7939
KZ
323#elif defined(HAVE_USLEEP)
324 return usleep(usec);
325#else
326# error "System with usleep() or nanosleep() required!"
2a31396a 327#endif
a5bd7939 328}
2a31396a 329
cd7accd4
SK
330/*
331 * Constant strings for usage() functions. For more info see
6e2d5a44 332 * Documentation/{howto-usage-function.txt,boilerplate.c}
cd7accd4
SK
333 */
334#define USAGE_HEADER _("\nUsage:\n")
335#define USAGE_OPTIONS _("\nOptions:\n")
513bfbef 336#define USAGE_FUNCTIONS _("\nFunctions:\n")
6e2d5a44 337#define USAGE_COMMANDS _("\nCommands:\n")
c3a4cfc5 338#define USAGE_COLUMNS _("\nAvailable output columns:\n")
82b219f7 339#define USAGE_SEPARATOR "\n"
b1a294c4 340
551b9cd3 341#define USAGE_OPTSTR_HELP _("display this help")
08e3c9e6 342#define USAGE_OPTSTR_VERSION _("display version")
b1a294c4 343
f45f3ec3 344#define USAGE_HELP_OPTIONS(marg_dsc) \
b1a294c4
RM
345 "%-" #marg_dsc "s%s\n" \
346 "%-" #marg_dsc "s%s\n" \
347 , " -h, --help", USAGE_OPTSTR_HELP \
f45f3ec3 348 , " -V, --version", USAGE_OPTSTR_VERSION
b1a294c4 349
6f162034 350#define USAGE_MAN_TAIL(_man) _("\nFor more details see %s.\n"), _man
cd7accd4
SK
351
352#define UTIL_LINUX_VERSION _("%s from %s\n"), program_invocation_short_name, PACKAGE_STRING
353
640fc1b8
KZ
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
9199f5cd
KZ
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
ff1aaf99
SK
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
d763c230
SK
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
f7ac9e71
KZ
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
40733239
RM
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
4d0dbb8b 416#endif /* UTIL_LINUX_C_H */