2009-10-15 17:42:22 -05:00
|
|
|
/*
|
|
|
|
* Fundamental C definitions.
|
|
|
|
*/
|
|
|
|
|
|
|
|
#ifndef UTIL_LINUX_C_H
|
|
|
|
#define UTIL_LINUX_C_H
|
|
|
|
|
|
|
|
#include <limits.h>
|
2012-01-17 10:02:34 -06:00
|
|
|
#include <stddef.h>
|
2011-01-25 15:44:52 -06:00
|
|
|
#include <stdint.h>
|
|
|
|
#include <stdio.h>
|
2012-07-24 07:06:25 -05:00
|
|
|
#include <unistd.h>
|
2011-01-25 15:44:52 -06:00
|
|
|
#include <stdarg.h>
|
2011-07-31 05:47:20 -05:00
|
|
|
#include <stdlib.h>
|
2011-01-25 15:44:52 -06:00
|
|
|
#include <string.h>
|
|
|
|
#include <errno.h>
|
|
|
|
|
2015-08-04 06:40:44 -05:00
|
|
|
#include <assert.h>
|
|
|
|
|
2011-01-25 15:44:52 -06:00
|
|
|
#ifdef HAVE_ERR_H
|
|
|
|
# include <err.h>
|
|
|
|
#endif
|
2009-10-15 17:42:22 -05:00
|
|
|
|
2016-03-08 07:29:45 -06:00
|
|
|
#ifdef HAVE_SYS_SYSMACROS_H
|
|
|
|
# include <sys/sysmacros.h> /* for major, minor */
|
|
|
|
#endif
|
|
|
|
|
2017-03-27 07:54:39 -05:00
|
|
|
#ifndef LOGIN_NAME_MAX
|
|
|
|
# define LOGIN_NAME_MAX 256
|
|
|
|
#endif
|
|
|
|
|
2009-10-15 17:42:22 -05:00
|
|
|
/*
|
2014-04-28 10:52:42 -05:00
|
|
|
* Compiler-specific stuff
|
2009-10-15 17:42:22 -05:00
|
|
|
*/
|
2011-02-07 10:29:47 -06:00
|
|
|
#ifndef __GNUC_PREREQ
|
|
|
|
# if defined __GNUC__ && defined __GNUC_MINOR__
|
|
|
|
# define __GNUC_PREREQ(maj, min) \
|
|
|
|
((__GNUC__ << 16) + __GNUC_MINOR__ >= ((maj) << 16) + (min))
|
|
|
|
# else
|
|
|
|
# define __GNUC_PREREQ(maj, min) 0
|
|
|
|
# endif
|
|
|
|
#endif
|
|
|
|
|
2009-10-15 17:42:22 -05:00
|
|
|
#ifdef __GNUC__
|
|
|
|
|
|
|
|
/* &a[0] degrades to a pointer: a different type from an array */
|
|
|
|
# define __must_be_array(a) \
|
2011-10-01 06:58:51 -05:00
|
|
|
UL_BUILD_BUG_ON_ZERO(__builtin_types_compatible_p(__typeof__(a), __typeof__(&a[0])))
|
2009-10-15 17:42:22 -05:00
|
|
|
|
2014-09-28 14:51:43 -05:00
|
|
|
# define ignore_result(x) __extension__ ({ \
|
2011-02-27 06:05:09 -06:00
|
|
|
__typeof__(x) __dummy __attribute__((__unused__)) = (x); (void) __dummy; \
|
2011-02-09 13:37:08 -06:00
|
|
|
})
|
2011-02-07 08:52:21 -06:00
|
|
|
|
2009-10-15 17:42:22 -05:00
|
|
|
#else /* !__GNUC__ */
|
|
|
|
# define __must_be_array(a) 0
|
|
|
|
# define __attribute__(_arg_)
|
2011-02-07 08:52:21 -06:00
|
|
|
# define ignore_result(x) ((void) (x))
|
2009-10-15 17:42:22 -05:00
|
|
|
#endif /* !__GNUC__ */
|
|
|
|
|
2011-02-07 10:29:47 -06:00
|
|
|
/*
|
|
|
|
* Function attributes
|
|
|
|
*/
|
|
|
|
#ifndef __ul_alloc_size
|
2011-02-08 09:35:41 -06:00
|
|
|
# if __GNUC_PREREQ (4, 3)
|
2013-07-09 03:44:06 -05:00
|
|
|
# define __ul_alloc_size(s) __attribute__((alloc_size(s), warn_unused_result))
|
2011-02-07 10:29:47 -06:00
|
|
|
# else
|
|
|
|
# define __ul_alloc_size(s)
|
|
|
|
# endif
|
|
|
|
#endif
|
|
|
|
|
|
|
|
#ifndef __ul_calloc_size
|
2011-02-08 09:35:41 -06:00
|
|
|
# if __GNUC_PREREQ (4, 3)
|
2013-07-09 03:44:06 -05:00
|
|
|
# define __ul_calloc_size(n, s) __attribute__((alloc_size(n, s), warn_unused_result))
|
2011-02-07 10:29:47 -06:00
|
|
|
# else
|
|
|
|
# define __ul_calloc_size(n, s)
|
|
|
|
# endif
|
|
|
|
#endif
|
2009-10-15 17:42:22 -05:00
|
|
|
|
2014-04-28 10:52:42 -05:00
|
|
|
/*
|
|
|
|
* Force a compilation error if condition is true, but also produce a
|
2009-10-15 17:42:22 -05:00
|
|
|
* result (of value 0 and type size_t), so the expression can be used
|
2014-04-28 10:52:42 -05:00
|
|
|
* e.g. in a structure initializer (or wherever else comma expressions
|
2009-10-15 17:42:22 -05:00
|
|
|
* aren't permitted).
|
|
|
|
*/
|
2014-09-28 14:51:43 -05:00
|
|
|
#define UL_BUILD_BUG_ON_ZERO(e) __extension__ (sizeof(struct { int:-!!(e); }))
|
2009-10-15 17:42:22 -05:00
|
|
|
#define BUILD_BUG_ON_NULL(e) ((void *)sizeof(struct { int:-!!(e); }))
|
|
|
|
|
|
|
|
#ifndef ARRAY_SIZE
|
|
|
|
# define ARRAY_SIZE(arr) (sizeof(arr) / sizeof((arr)[0]) + __must_be_array(arr))
|
|
|
|
#endif
|
|
|
|
|
|
|
|
#ifndef PATH_MAX
|
|
|
|
# define PATH_MAX 4096
|
|
|
|
#endif
|
|
|
|
|
|
|
|
#ifndef TRUE
|
|
|
|
# define TRUE 1
|
|
|
|
#endif
|
|
|
|
|
|
|
|
#ifndef FALSE
|
|
|
|
# define FALSE 0
|
|
|
|
#endif
|
|
|
|
|
2010-03-16 09:24:04 -05:00
|
|
|
#ifndef min
|
2014-09-28 14:51:43 -05:00
|
|
|
# define min(x, y) __extension__ ({ \
|
2011-02-27 06:05:09 -06:00
|
|
|
__typeof__(x) _min1 = (x); \
|
|
|
|
__typeof__(y) _min2 = (y); \
|
2010-02-12 14:42:46 -06:00
|
|
|
(void) (&_min1 == &_min2); \
|
|
|
|
_min1 < _min2 ? _min1 : _min2; })
|
2010-03-16 09:24:04 -05:00
|
|
|
#endif
|
2010-02-12 14:42:46 -06:00
|
|
|
|
2010-03-16 09:24:04 -05:00
|
|
|
#ifndef max
|
2014-09-28 14:51:43 -05:00
|
|
|
# define max(x, y) __extension__ ({ \
|
2011-02-27 06:05:09 -06:00
|
|
|
__typeof__(x) _max1 = (x); \
|
|
|
|
__typeof__(y) _max2 = (y); \
|
2010-02-12 14:42:46 -06:00
|
|
|
(void) (&_max1 == &_max2); \
|
|
|
|
_max1 > _max2 ? _max1 : _max2; })
|
2010-03-16 09:24:04 -05:00
|
|
|
#endif
|
2010-02-12 14:42:46 -06:00
|
|
|
|
2014-12-04 03:27:39 -06:00
|
|
|
#ifndef cmp_numbers
|
|
|
|
# define cmp_numbers(x, y) __extension__ ({ \
|
|
|
|
__typeof__(x) _a = (x); \
|
|
|
|
__typeof__(y) _b = (y); \
|
|
|
|
(void) (&_a == &_b); \
|
2014-12-04 06:06:03 -06:00
|
|
|
_a == _b ? 0 : _a > _b ? 1 : -1; })
|
2014-12-04 03:27:39 -06:00
|
|
|
#endif
|
|
|
|
|
2011-12-12 16:52:26 -06:00
|
|
|
#ifndef offsetof
|
|
|
|
#define offsetof(TYPE, MEMBER) ((size_t) &((TYPE *)0)->MEMBER)
|
|
|
|
#endif
|
|
|
|
|
2012-05-22 09:20:42 -05:00
|
|
|
#ifndef container_of
|
2014-09-28 14:51:43 -05:00
|
|
|
#define container_of(ptr, type, member) __extension__ ({ \
|
2011-12-12 16:52:26 -06:00
|
|
|
const __typeof__( ((type *)0)->member ) *__mptr = (ptr); \
|
|
|
|
(type *)( (char *)__mptr - offsetof(type,member) );})
|
2012-05-22 09:20:42 -05:00
|
|
|
#endif
|
2011-12-12 16:52:26 -06:00
|
|
|
|
2011-07-31 05:47:19 -05:00
|
|
|
#ifndef HAVE_PROGRAM_INVOCATION_SHORT_NAME
|
|
|
|
# ifdef HAVE___PROGNAME
|
|
|
|
extern char *__progname;
|
|
|
|
# define program_invocation_short_name __progname
|
|
|
|
# else
|
|
|
|
# ifdef HAVE_GETEXECNAME
|
|
|
|
# define program_invocation_short_name \
|
|
|
|
prog_inv_sh_nm_from_file(getexecname(), 0)
|
|
|
|
# else
|
|
|
|
# define program_invocation_short_name \
|
|
|
|
prog_inv_sh_nm_from_file(__FILE__, 1)
|
|
|
|
# endif
|
|
|
|
static char prog_inv_sh_nm_buf[256];
|
|
|
|
static inline char *
|
|
|
|
prog_inv_sh_nm_from_file(char *f, char stripext)
|
|
|
|
{
|
|
|
|
char *t;
|
|
|
|
|
|
|
|
if ((t = strrchr(f, '/')) != NULL)
|
|
|
|
t++;
|
|
|
|
else
|
|
|
|
t = f;
|
|
|
|
|
|
|
|
strncpy(prog_inv_sh_nm_buf, t, sizeof(prog_inv_sh_nm_buf) - 1);
|
|
|
|
prog_inv_sh_nm_buf[sizeof(prog_inv_sh_nm_buf) - 1] = '\0';
|
|
|
|
|
|
|
|
if (stripext && (t = strrchr(prog_inv_sh_nm_buf, '.')) != NULL)
|
|
|
|
*t = '\0';
|
|
|
|
|
|
|
|
return prog_inv_sh_nm_buf;
|
|
|
|
}
|
|
|
|
# endif
|
|
|
|
#endif
|
|
|
|
|
2011-01-04 14:34:45 -06:00
|
|
|
|
2011-01-25 15:44:52 -06:00
|
|
|
#ifndef HAVE_ERR_H
|
|
|
|
static inline void
|
|
|
|
errmsg(char doexit, int excode, char adderr, const char *fmt, ...)
|
|
|
|
{
|
|
|
|
fprintf(stderr, "%s: ", program_invocation_short_name);
|
|
|
|
if (fmt != NULL) {
|
|
|
|
va_list argp;
|
|
|
|
va_start(argp, fmt);
|
|
|
|
vfprintf(stderr, fmt, argp);
|
|
|
|
va_end(argp);
|
|
|
|
if (adderr)
|
|
|
|
fprintf(stderr, ": ");
|
|
|
|
}
|
|
|
|
if (adderr)
|
2011-09-22 05:12:37 -05:00
|
|
|
fprintf(stderr, "%m");
|
2011-01-25 15:44:52 -06:00
|
|
|
fprintf(stderr, "\n");
|
|
|
|
if (doexit)
|
|
|
|
exit(excode);
|
|
|
|
}
|
|
|
|
|
|
|
|
#ifndef HAVE_ERR
|
|
|
|
# define err(E, FMT...) errmsg(1, E, 1, FMT)
|
|
|
|
#endif
|
|
|
|
|
|
|
|
#ifndef HAVE_ERRX
|
|
|
|
# define errx(E, FMT...) errmsg(1, E, 0, FMT)
|
|
|
|
#endif
|
|
|
|
|
|
|
|
#ifndef HAVE_WARN
|
|
|
|
# define warn(FMT...) errmsg(0, 0, 1, FMT)
|
|
|
|
#endif
|
|
|
|
|
|
|
|
#ifndef HAVE_WARNX
|
|
|
|
# define warnx(FMT...) errmsg(0, 0, 0, FMT)
|
|
|
|
#endif
|
|
|
|
#endif /* !HAVE_ERR_H */
|
|
|
|
|
|
|
|
|
2016-12-19 04:33:40 -06:00
|
|
|
/* Don't use inline function to avoid '#include "nls.h"' in c.h
|
|
|
|
*/
|
|
|
|
#define errtryhelp(eval) __extension__ ({ \
|
|
|
|
fprintf(stderr, _("Try '%s --help' for more information.\n"), \
|
|
|
|
program_invocation_short_name); \
|
|
|
|
exit(eval); \
|
|
|
|
})
|
|
|
|
|
2016-12-19 06:13:34 -06:00
|
|
|
#define errtryh(eval) __extension__ ({ \
|
|
|
|
fprintf(stderr, _("Try '%s -h' for more information.\n"), \
|
|
|
|
program_invocation_short_name); \
|
|
|
|
exit(eval); \
|
|
|
|
})
|
|
|
|
|
2016-12-19 04:33:40 -06:00
|
|
|
|
2010-10-14 18:33:28 -05:00
|
|
|
static inline __attribute__((const)) int is_power_of_2(unsigned long num)
|
|
|
|
{
|
|
|
|
return (num != 0 && ((num & (num - 1)) == 0));
|
|
|
|
}
|
|
|
|
|
2011-01-17 14:04:04 -06:00
|
|
|
#ifndef HAVE_LOFF_T
|
|
|
|
typedef int64_t loff_t;
|
|
|
|
#endif
|
|
|
|
|
2011-01-21 10:48:14 -06:00
|
|
|
#if !defined(HAVE_DIRFD) && (!defined(HAVE_DECL_DIRFD) || HAVE_DECL_DIRFD == 0) && defined(HAVE_DIR_DD_FD)
|
|
|
|
#include <sys/types.h>
|
|
|
|
#include <dirent.h>
|
|
|
|
static inline int dirfd(DIR *d)
|
|
|
|
{
|
|
|
|
return d->dd_fd;
|
|
|
|
}
|
|
|
|
#endif
|
|
|
|
|
2011-03-22 08:42:09 -05:00
|
|
|
/*
|
|
|
|
* Fallback defines for old versions of glibc
|
|
|
|
*/
|
2011-09-12 06:53:10 -05:00
|
|
|
#include <fcntl.h>
|
2013-04-03 09:11:19 -05:00
|
|
|
|
|
|
|
#ifdef O_CLOEXEC
|
|
|
|
#define UL_CLOEXECSTR "e"
|
|
|
|
#else
|
|
|
|
#define UL_CLOEXECSTR ""
|
|
|
|
#endif
|
|
|
|
|
2011-02-11 03:49:50 -06:00
|
|
|
#ifndef O_CLOEXEC
|
|
|
|
#define O_CLOEXEC 0
|
|
|
|
#endif
|
2010-10-14 18:33:28 -05:00
|
|
|
|
2015-06-05 23:19:07 -05:00
|
|
|
#ifdef __FreeBSD_kernel__
|
|
|
|
#ifndef F_DUPFD_CLOEXEC
|
|
|
|
#define F_DUPFD_CLOEXEC 17 /* Like F_DUPFD, but FD_CLOEXEC is set */
|
|
|
|
#endif
|
|
|
|
#endif
|
|
|
|
|
2013-04-03 09:11:19 -05:00
|
|
|
|
2011-03-22 08:42:09 -05:00
|
|
|
#ifndef AI_ADDRCONFIG
|
|
|
|
#define AI_ADDRCONFIG 0x0020
|
|
|
|
#endif
|
|
|
|
|
|
|
|
#ifndef IUTF8
|
|
|
|
#define IUTF8 0040000
|
|
|
|
#endif
|
|
|
|
|
2012-10-17 14:16:06 -05:00
|
|
|
/*
|
|
|
|
* MAXHOSTNAMELEN replacement
|
|
|
|
*/
|
|
|
|
static inline size_t get_hostname_max(void)
|
|
|
|
{
|
|
|
|
long len = sysconf(_SC_HOST_NAME_MAX);
|
|
|
|
|
|
|
|
if (0 < len)
|
|
|
|
return len;
|
|
|
|
|
|
|
|
#ifdef MAXHOSTNAMELEN
|
|
|
|
return MAXHOSTNAMELEN;
|
|
|
|
#elif HOST_NAME_MAX
|
|
|
|
return HOST_NAME_MAX;
|
|
|
|
#endif
|
|
|
|
return 64;
|
|
|
|
}
|
|
|
|
|
2012-10-22 04:03:09 -05:00
|
|
|
/*
|
2014-04-28 10:52:42 -05:00
|
|
|
* The usleep function was marked obsolete in POSIX.1-2001 and was removed
|
|
|
|
* in POSIX.1-2008. It was replaced with nanosleep() that provides more
|
|
|
|
* advantages (like no interaction with signals and other timer functions).
|
2012-10-22 04:03:09 -05:00
|
|
|
*/
|
2014-01-24 06:04:14 -06:00
|
|
|
#include <time.h>
|
|
|
|
|
|
|
|
static inline int xusleep(useconds_t usec)
|
2012-10-22 04:03:09 -05:00
|
|
|
{
|
2014-01-24 06:04:14 -06:00
|
|
|
#ifdef HAVE_NANOSLEEP
|
2012-10-22 04:03:09 -05:00
|
|
|
struct timespec waittime = {
|
|
|
|
.tv_sec = usec / 1000000L,
|
|
|
|
.tv_nsec = (usec % 1000000L) * 1000
|
2012-12-07 02:00:55 -06:00
|
|
|
};
|
|
|
|
return nanosleep(&waittime, NULL);
|
2014-01-24 06:04:14 -06:00
|
|
|
#elif defined(HAVE_USLEEP)
|
|
|
|
return usleep(usec);
|
|
|
|
#else
|
|
|
|
# error "System with usleep() or nanosleep() required!"
|
2012-10-22 04:03:09 -05:00
|
|
|
#endif
|
2014-01-24 06:04:14 -06:00
|
|
|
}
|
2012-10-22 04:03:09 -05:00
|
|
|
|
2011-08-20 12:25:46 -05:00
|
|
|
/*
|
|
|
|
* Constant strings for usage() functions. For more info see
|
2013-03-21 16:47:15 -05:00
|
|
|
* Documentation/howto-usage-function.txt and disk-utils/delpart.c
|
2011-08-20 12:25:46 -05:00
|
|
|
*/
|
|
|
|
#define USAGE_HEADER _("\nUsage:\n")
|
|
|
|
#define USAGE_OPTIONS _("\nOptions:\n")
|
2017-06-17 14:32:28 -05:00
|
|
|
#define USAGE_FUNCTIONS _("\nFunctions:\n")
|
2014-04-28 11:15:00 -05:00
|
|
|
#define USAGE_SEPARATOR "\n"
|
2011-08-20 12:25:46 -05:00
|
|
|
#define USAGE_HELP _(" -h, --help display this help and exit\n")
|
|
|
|
#define USAGE_VERSION _(" -V, --version output version information and exit\n")
|
2011-09-17 05:52:32 -05:00
|
|
|
#define USAGE_MAN_TAIL(_man) _("\nFor more details see %s.\n"), _man
|
2011-08-20 12:25:46 -05:00
|
|
|
|
|
|
|
#define UTIL_LINUX_VERSION _("%s from %s\n"), program_invocation_short_name, PACKAGE_STRING
|
|
|
|
|
2011-10-01 08:33:53 -05:00
|
|
|
/*
|
|
|
|
* scanf modifiers for "strings allocation"
|
|
|
|
*/
|
|
|
|
#ifdef HAVE_SCANF_MS_MODIFIER
|
|
|
|
#define UL_SCNsA "%ms"
|
|
|
|
#elif defined(HAVE_SCANF_AS_MODIFIER)
|
|
|
|
#define UL_SCNsA "%as"
|
|
|
|
#endif
|
|
|
|
|
2012-07-24 07:06:25 -05:00
|
|
|
/*
|
|
|
|
* seek stuff
|
|
|
|
*/
|
|
|
|
#ifndef SEEK_DATA
|
|
|
|
# define SEEK_DATA 3
|
|
|
|
#endif
|
|
|
|
#ifndef SEEK_HOLE
|
|
|
|
# define SEEK_HOLE 4
|
|
|
|
#endif
|
|
|
|
|
2014-04-25 15:36:58 -05:00
|
|
|
|
|
|
|
/*
|
|
|
|
* Macros to convert #define'itions to strings, for example
|
|
|
|
* #define XYXXY 42
|
|
|
|
* printf ("%s=%s\n", stringify(XYXXY), stringify_value(XYXXY));
|
|
|
|
*/
|
|
|
|
#define stringify_value(s) stringify(s)
|
|
|
|
#define stringify(s) #s
|
|
|
|
|
2014-11-22 02:49:34 -06:00
|
|
|
/*
|
|
|
|
* UL_ASAN_BLACKLIST is a macro to tell AddressSanitizer (a compile-time
|
|
|
|
* instrumentation shipped with Clang and GCC) to not instrument the
|
|
|
|
* annotated function. Furthermore, it will prevent the compiler from
|
|
|
|
* inlining the function because inlining currently breaks the blacklisting
|
|
|
|
* mechanism of AddressSanitizer.
|
|
|
|
*/
|
|
|
|
#if defined(__has_feature)
|
|
|
|
# if __has_feature(address_sanitizer)
|
|
|
|
# define UL_ASAN_BLACKLIST __attribute__((noinline)) __attribute__((no_sanitize_memory)) __attribute__((no_sanitize_address))
|
|
|
|
# else
|
|
|
|
# define UL_ASAN_BLACKLIST /* nothing */
|
|
|
|
# endif
|
|
|
|
#else
|
|
|
|
# define UL_ASAN_BLACKLIST /* nothing */
|
|
|
|
#endif
|
|
|
|
|
2015-12-15 05:25:56 -06:00
|
|
|
|
|
|
|
|
|
|
|
/*
|
|
|
|
* Note that sysconf(_SC_GETPW_R_SIZE_MAX) returns *initial* suggested size for
|
|
|
|
* pwd buffer and in some cases it is not large enough. See POSIX and
|
|
|
|
* getpwnam_r man page for more details.
|
|
|
|
*/
|
|
|
|
#define UL_GETPW_BUFSIZ (16 * 1024)
|
|
|
|
|
2016-02-18 09:37:13 -06:00
|
|
|
/*
|
|
|
|
* Darwin or other BSDs may only have MAP_ANON. To get it on Darwin we must
|
|
|
|
* define _DARWIN_C_SOURCE before including sys/mman.h. We do this in config.h.
|
|
|
|
*/
|
|
|
|
#if !defined MAP_ANONYMOUS && defined MAP_ANON
|
|
|
|
# define MAP_ANONYMOUS (MAP_ANON)
|
|
|
|
#endif
|
|
|
|
|
2009-10-15 17:42:22 -05:00
|
|
|
#endif /* UTIL_LINUX_C_H */
|