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