blob: 6fcbc6da4849392597730a316f12dbf3a8446227 [file] [log] [blame]
bigbiff bigbiffe60683a2013-02-22 20:55:50 -05001/*
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#include "blkid.h"
18#ifdef HAVE_ERR_H
19# include <err.h>
20#endif
21
22#ifndef HAVE_USLEEP
23# include <time.h>
24#endif
25
26/*
27 * Compiler specific stuff
28 */
29#ifndef __GNUC_PREREQ
30# if defined __GNUC__ && defined __GNUC_MINOR__
31# define __GNUC_PREREQ(maj, min) \
32 ((__GNUC__ << 16) + __GNUC_MINOR__ >= ((maj) << 16) + (min))
33# else
34# define __GNUC_PREREQ(maj, min) 0
35# endif
36#endif
37
38#ifdef __GNUC__
39
40/* &a[0] degrades to a pointer: a different type from an array */
41# define __must_be_array(a) \
42 UL_BUILD_BUG_ON_ZERO(__builtin_types_compatible_p(__typeof__(a), __typeof__(&a[0])))
43
44# define ignore_result(x) ({ \
45 __typeof__(x) __dummy __attribute__((__unused__)) = (x); (void) __dummy; \
46})
47
48#else /* !__GNUC__ */
49# define __must_be_array(a) 0
50# define __attribute__(_arg_)
51# define ignore_result(x) ((void) (x))
52#endif /* !__GNUC__ */
53
54/*
55 * Function attributes
56 */
57#ifndef __ul_alloc_size
58# if __GNUC_PREREQ (4, 3)
59# define __ul_alloc_size(s) __attribute__((alloc_size(s)))
60# else
61# define __ul_alloc_size(s)
62# endif
63#endif
64
65#ifndef __ul_calloc_size
66# if __GNUC_PREREQ (4, 3)
67# define __ul_calloc_size(n, s) __attribute__((alloc_size(n, s)))
68# else
69# define __ul_calloc_size(n, s)
70# endif
71#endif
72
73/* Force a compilation error if condition is true, but also produce a
74 * result (of value 0 and type size_t), so the expression can be used
75 * e.g. in a structure initializer (or where-ever else comma expressions
76 * aren't permitted).
77 */
78#define UL_BUILD_BUG_ON_ZERO(e) (sizeof(struct { int:-!!(e); }))
79#define BUILD_BUG_ON_NULL(e) ((void *)sizeof(struct { int:-!!(e); }))
80
81#ifndef ARRAY_SIZE
82# define ARRAY_SIZE(arr) (sizeof(arr) / sizeof((arr)[0]) + __must_be_array(arr))
83#endif
84
85#ifndef PATH_MAX
86# define PATH_MAX 4096
87#endif
88
89#ifndef TRUE
90# define TRUE 1
91#endif
92
93#ifndef FALSE
94# define FALSE 0
95#endif
96
97#ifndef min
98# define min(x, y) ({ \
99 __typeof__(x) _min1 = (x); \
100 __typeof__(y) _min2 = (y); \
101 (void) (&_min1 == &_min2); \
102 _min1 < _min2 ? _min1 : _min2; })
103#endif
104
105#ifndef max
106# define max(x, y) ({ \
107 __typeof__(x) _max1 = (x); \
108 __typeof__(y) _max2 = (y); \
109 (void) (&_max1 == &_max2); \
110 _max1 > _max2 ? _max1 : _max2; })
111#endif
112
bigbiff7b4c7a62015-01-01 19:44:14 -0500113#ifndef cmp_numbers
114# define cmp_numbers(x, y) __extension__ ({ \
115 __typeof__(x) _a = (x); \
116 __typeof__(y) _b = (y); \
117 (void) (&_a == &_b); \
118 _a == _b ? 0 : _a > _b ? 1 : -1; })
119#endif
120
bigbiff bigbiffe60683a2013-02-22 20:55:50 -0500121#ifndef offsetof
122#define offsetof(TYPE, MEMBER) ((size_t) &((TYPE *)0)->MEMBER)
123#endif
124
125#ifndef container_of
126#define container_of(ptr, type, member) ({ \
127 const __typeof__( ((type *)0)->member ) *__mptr = (ptr); \
128 (type *)( (char *)__mptr - offsetof(type,member) );})
129#endif
130
131#ifndef HAVE_PROGRAM_INVOCATION_SHORT_NAME
132# ifdef HAVE___PROGNAME
133extern char *__progname;
134# define program_invocation_short_name __progname
135# else
136# ifdef HAVE_GETEXECNAME
137# define program_invocation_short_name \
138 prog_inv_sh_nm_from_file(getexecname(), 0)
139# else
140# define program_invocation_short_name \
141 prog_inv_sh_nm_from_file(__FILE__, 1)
142# endif
143static char prog_inv_sh_nm_buf[256];
144static inline char *
145prog_inv_sh_nm_from_file(char *f, char stripext)
146{
147 char *t;
148
149 if ((t = strrchr(f, '/')) != NULL)
150 t++;
151 else
152 t = f;
153
154 strncpy(prog_inv_sh_nm_buf, t, sizeof(prog_inv_sh_nm_buf) - 1);
155 prog_inv_sh_nm_buf[sizeof(prog_inv_sh_nm_buf) - 1] = '\0';
156
157 if (stripext && (t = strrchr(prog_inv_sh_nm_buf, '.')) != NULL)
158 *t = '\0';
159
160 return prog_inv_sh_nm_buf;
161}
162# endif
163#endif
164
165
166#ifndef HAVE_ERR_H
167static inline void
168errmsg(char doexit, int excode, char adderr, const char *fmt, ...)
169{
170 fprintf(stderr, "%s: ", program_invocation_short_name);
171 if (fmt != NULL) {
172 va_list argp;
173 va_start(argp, fmt);
174 vfprintf(stderr, fmt, argp);
175 va_end(argp);
176 if (adderr)
177 fprintf(stderr, ": ");
178 }
179 if (adderr)
180 fprintf(stderr, "%m");
181 fprintf(stderr, "\n");
182 if (doexit)
183 exit(excode);
184}
185
186#ifndef HAVE_ERR
187# define err(E, FMT...) errmsg(1, E, 1, FMT)
188#endif
189
190#ifndef HAVE_ERRX
191# define errx(E, FMT...) errmsg(1, E, 0, FMT)
192#endif
193
194#ifndef HAVE_WARN
195# define warn(FMT...) errmsg(0, 0, 1, FMT)
196#endif
197
198#ifndef HAVE_WARNX
199# define warnx(FMT...) errmsg(0, 0, 0, FMT)
200#endif
201#endif /* !HAVE_ERR_H */
202
203
204static inline __attribute__((const)) int is_power_of_2(unsigned long num)
205{
206 return (num != 0 && ((num & (num - 1)) == 0));
207}
208
209#ifndef HAVE_LOFF_T
210typedef int64_t loff_t;
211#endif
212
213#if !defined(HAVE_DIRFD) && (!defined(HAVE_DECL_DIRFD) || HAVE_DECL_DIRFD == 0) && defined(HAVE_DIR_DD_FD)
214#include <sys/types.h>
215#include <dirent.h>
216static inline int dirfd(DIR *d)
217{
218 return d->dd_fd;
219}
220#endif
221
222/*
223 * Fallback defines for old versions of glibc
224 */
225#include <fcntl.h>
bigbiff7b4c7a62015-01-01 19:44:14 -0500226
227#ifdef O_CLOEXEC
228#define UL_CLOEXECSTR "e"
229#else
230#define UL_CLOEXECSTR ""
231#endif
232
bigbiff bigbiffe60683a2013-02-22 20:55:50 -0500233#ifndef O_CLOEXEC
234#define O_CLOEXEC 0
235#endif
236
237#ifndef AI_ADDRCONFIG
238#define AI_ADDRCONFIG 0x0020
239#endif
240
241#ifndef IUTF8
242#define IUTF8 0040000
243#endif
244
245/*
246 * MAXHOSTNAMELEN replacement
247 */
248static inline size_t get_hostname_max(void)
249{
bigbiff7b4c7a62015-01-01 19:44:14 -0500250 long len = sysconf(255);
bigbiff bigbiffe60683a2013-02-22 20:55:50 -0500251
252 if (0 < len)
253 return len;
254
255#ifdef MAXHOSTNAMELEN
256 return MAXHOSTNAMELEN;
257#elif HOST_NAME_MAX
258 return HOST_NAME_MAX;
259#endif
260 return 64;
261}
262
263/*
264 * Constant strings for usage() functions. For more info see
265 * Documentation/howto-usage-function.txt and sys-utils/arch.c
266 */
267#define USAGE_HEADER _("\nUsage:\n")
268#define USAGE_OPTIONS _("\nOptions:\n")
269#define USAGE_SEPARATOR _("\n")
270#define USAGE_HELP _(" -h, --help display this help and exit\n")
271#define USAGE_VERSION _(" -V, --version output version information and exit\n")
272#define USAGE_MAN_TAIL(_man) _("\nFor more details see %s.\n"), _man
273
274#define UTIL_LINUX_VERSION _("%s from %s\n"), program_invocation_short_name, PACKAGE_STRING
275
276/*
277 * scanf modifiers for "strings allocation"
278 */
279#ifdef HAVE_SCANF_MS_MODIFIER
280#define UL_SCNsA "%ms"
281#elif defined(HAVE_SCANF_AS_MODIFIER)
282#define UL_SCNsA "%as"
283#endif
284
285/*
286 * seek stuff
287 */
288#ifndef SEEK_DATA
289# define SEEK_DATA 3
290#endif
291#ifndef SEEK_HOLE
292# define SEEK_HOLE 4
293#endif
294
295#endif /* UTIL_LINUX_C_H */