blob: 037a0992862fd5bdccb346d80872749fad017d30 [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
113#ifndef offsetof
114#define offsetof(TYPE, MEMBER) ((size_t) &((TYPE *)0)->MEMBER)
115#endif
116
117#ifndef container_of
118#define container_of(ptr, type, member) ({ \
119 const __typeof__( ((type *)0)->member ) *__mptr = (ptr); \
120 (type *)( (char *)__mptr - offsetof(type,member) );})
121#endif
122
123#ifndef HAVE_PROGRAM_INVOCATION_SHORT_NAME
124# ifdef HAVE___PROGNAME
125extern char *__progname;
126# define program_invocation_short_name __progname
127# else
128# ifdef HAVE_GETEXECNAME
129# define program_invocation_short_name \
130 prog_inv_sh_nm_from_file(getexecname(), 0)
131# else
132# define program_invocation_short_name \
133 prog_inv_sh_nm_from_file(__FILE__, 1)
134# endif
135static char prog_inv_sh_nm_buf[256];
136static inline char *
137prog_inv_sh_nm_from_file(char *f, char stripext)
138{
139 char *t;
140
141 if ((t = strrchr(f, '/')) != NULL)
142 t++;
143 else
144 t = f;
145
146 strncpy(prog_inv_sh_nm_buf, t, sizeof(prog_inv_sh_nm_buf) - 1);
147 prog_inv_sh_nm_buf[sizeof(prog_inv_sh_nm_buf) - 1] = '\0';
148
149 if (stripext && (t = strrchr(prog_inv_sh_nm_buf, '.')) != NULL)
150 *t = '\0';
151
152 return prog_inv_sh_nm_buf;
153}
154# endif
155#endif
156
157
158#ifndef HAVE_ERR_H
159static inline void
160errmsg(char doexit, int excode, char adderr, const char *fmt, ...)
161{
162 fprintf(stderr, "%s: ", program_invocation_short_name);
163 if (fmt != NULL) {
164 va_list argp;
165 va_start(argp, fmt);
166 vfprintf(stderr, fmt, argp);
167 va_end(argp);
168 if (adderr)
169 fprintf(stderr, ": ");
170 }
171 if (adderr)
172 fprintf(stderr, "%m");
173 fprintf(stderr, "\n");
174 if (doexit)
175 exit(excode);
176}
177
178#ifndef HAVE_ERR
179# define err(E, FMT...) errmsg(1, E, 1, FMT)
180#endif
181
182#ifndef HAVE_ERRX
183# define errx(E, FMT...) errmsg(1, E, 0, FMT)
184#endif
185
186#ifndef HAVE_WARN
187# define warn(FMT...) errmsg(0, 0, 1, FMT)
188#endif
189
190#ifndef HAVE_WARNX
191# define warnx(FMT...) errmsg(0, 0, 0, FMT)
192#endif
193#endif /* !HAVE_ERR_H */
194
195
196static inline __attribute__((const)) int is_power_of_2(unsigned long num)
197{
198 return (num != 0 && ((num & (num - 1)) == 0));
199}
200
201#ifndef HAVE_LOFF_T
202typedef int64_t loff_t;
203#endif
204
205#if !defined(HAVE_DIRFD) && (!defined(HAVE_DECL_DIRFD) || HAVE_DECL_DIRFD == 0) && defined(HAVE_DIR_DD_FD)
206#include <sys/types.h>
207#include <dirent.h>
208static inline int dirfd(DIR *d)
209{
210 return d->dd_fd;
211}
212#endif
213
214/*
215 * Fallback defines for old versions of glibc
216 */
217#include <fcntl.h>
218#ifndef O_CLOEXEC
219#define O_CLOEXEC 0
220#endif
221
222#ifndef AI_ADDRCONFIG
223#define AI_ADDRCONFIG 0x0020
224#endif
225
226#ifndef IUTF8
227#define IUTF8 0040000
228#endif
229
230/*
231 * MAXHOSTNAMELEN replacement
232 */
233static inline size_t get_hostname_max(void)
234{
235 long len = sysconf(_SC_HOST_NAME_MAX);
236
237 if (0 < len)
238 return len;
239
240#ifdef MAXHOSTNAMELEN
241 return MAXHOSTNAMELEN;
242#elif HOST_NAME_MAX
243 return HOST_NAME_MAX;
244#endif
245 return 64;
246}
247
248/*
249 * Constant strings for usage() functions. For more info see
250 * Documentation/howto-usage-function.txt and sys-utils/arch.c
251 */
252#define USAGE_HEADER _("\nUsage:\n")
253#define USAGE_OPTIONS _("\nOptions:\n")
254#define USAGE_SEPARATOR _("\n")
255#define USAGE_HELP _(" -h, --help display this help and exit\n")
256#define USAGE_VERSION _(" -V, --version output version information and exit\n")
257#define USAGE_MAN_TAIL(_man) _("\nFor more details see %s.\n"), _man
258
259#define UTIL_LINUX_VERSION _("%s from %s\n"), program_invocation_short_name, PACKAGE_STRING
260
261/*
262 * scanf modifiers for "strings allocation"
263 */
264#ifdef HAVE_SCANF_MS_MODIFIER
265#define UL_SCNsA "%ms"
266#elif defined(HAVE_SCANF_AS_MODIFIER)
267#define UL_SCNsA "%as"
268#endif
269
270/*
271 * seek stuff
272 */
273#ifndef SEEK_DATA
274# define SEEK_DATA 3
275#endif
276#ifndef SEEK_HOLE
277# define SEEK_HOLE 4
278#endif
279
280#endif /* UTIL_LINUX_C_H */