(root)/
util-linux-2.39/
include/
c.h
       1  /*
       2   * Fundamental C definitions.
       3   *
       4   * No copyright is claimed.  This code is in the public domain; do with
       5   * it what you wish.
       6   */
       7  #ifndef UTIL_LINUX_C_H
       8  #define UTIL_LINUX_C_H
       9  
      10  #include <limits.h>
      11  #include <stddef.h>
      12  #include <stdint.h>
      13  #include <stdio.h>
      14  #include <unistd.h>
      15  #include <stdarg.h>
      16  #include <stdlib.h>
      17  #include <string.h>
      18  #include <errno.h>
      19  #include <sys/types.h>
      20  #include <grp.h>
      21  
      22  #include <assert.h>
      23  
      24  #ifdef HAVE_ERR_H
      25  # include <err.h>
      26  #endif
      27  
      28  #ifdef HAVE_SYS_SYSMACROS_H
      29  # include <sys/sysmacros.h>     /* for major, minor */
      30  #endif
      31  
      32  #ifndef LOGIN_NAME_MAX
      33  # define LOGIN_NAME_MAX 256
      34  #endif
      35  
      36  #ifndef NAME_MAX
      37  # define NAME_MAX PATH_MAX
      38  #endif
      39  
      40  /*
      41   * __GNUC_PREREQ is deprecated in favour of __has_attribute() and
      42   * __has_feature(). The __has macros are supported by clang and gcc>=5.
      43   */
      44  #ifndef __GNUC_PREREQ
      45  # if defined __GNUC__ && defined __GNUC_MINOR__
      46  #  define __GNUC_PREREQ(maj, min) \
      47  	((__GNUC__ << 16) + __GNUC_MINOR__ >= ((maj) << 16) + (min))
      48  # else
      49  #  define __GNUC_PREREQ(maj, min) 0
      50  # endif
      51  #endif
      52  
      53  #ifdef __GNUC__
      54  
      55  /* &a[0] degrades to a pointer: a different type from an array */
      56  # define __must_be_array(a) \
      57  	UL_BUILD_BUG_ON_ZERO(__builtin_types_compatible_p(__typeof__(a), __typeof__(&a[0])))
      58  
      59  # define ignore_result(x) __extension__ ({ \
      60  	__typeof__(x) __dummy __attribute__((__unused__)) = (x); (void) __dummy; \
      61  })
      62  
      63  #else /* !__GNUC__ */
      64  # define __must_be_array(a)	0
      65  # define __attribute__(_arg_)
      66  # define ignore_result(x) ((void) (x))
      67  #endif /* !__GNUC__ */
      68  
      69  
      70  /* "restrict" keyword fallback */
      71  #if __STDC__ != 1
      72  # define restrict __restrict /* use implementation __ format */
      73  #else
      74  # ifndef __STDC_VERSION__
      75  #  define restrict __restrict /* use implementation __ format */
      76  # else
      77  #  if __STDC_VERSION__ < 199901L
      78  #   define restrict __restrict /* use implementation __ format */
      79  #  endif
      80  # endif
      81  #endif
      82  
      83  
      84  /*
      85   * It evaluates to 1 if the attribute/feature is supported by the current
      86   * compilation target. Fallback for old compilers.
      87   */
      88  #ifndef __has_attribute
      89    #define __has_attribute(x) 0
      90  #endif
      91  
      92  #ifndef __has_feature
      93    #define __has_feature(x) 0
      94  #endif
      95  
      96  /*
      97   * Function attributes
      98   */
      99  #ifndef __ul_alloc_size
     100  # if (__has_attribute(alloc_size) && __has_attribute(warn_unused_result)) || __GNUC_PREREQ (4, 3)
     101  #  define __ul_alloc_size(s) __attribute__((alloc_size(s), warn_unused_result))
     102  # else
     103  #  define __ul_alloc_size(s)
     104  # endif
     105  #endif
     106  
     107  #ifndef __ul_calloc_size
     108  # if (__has_attribute(alloc_size) && __has_attribute(warn_unused_result)) || __GNUC_PREREQ (4, 3)
     109  #  define __ul_calloc_size(n, s) __attribute__((alloc_size(n, s), warn_unused_result))
     110  # else
     111  #  define __ul_calloc_size(n, s)
     112  # endif
     113  #endif
     114  
     115  #if __has_attribute(returns_nonnull) || __GNUC_PREREQ (4, 9)
     116  # define __ul_returns_nonnull __attribute__((returns_nonnull))
     117  #else
     118  # define __ul_returns_nonnull
     119  #endif
     120  
     121  /*
     122   * Force a compilation error if condition is true, but also produce a
     123   * result (of value 0 and type size_t), so the expression can be used
     124   * e.g. in a structure initializer (or wherever else comma expressions
     125   * aren't permitted).
     126   */
     127  #define UL_BUILD_BUG_ON_ZERO(e) __extension__ (sizeof(struct { int:-!!(e); }))
     128  #define BUILD_BUG_ON_NULL(e) ((void *)sizeof(struct { int:-!!(e); }))
     129  
     130  #ifndef ARRAY_SIZE
     131  # define ARRAY_SIZE(arr) (sizeof(arr) / sizeof((arr)[0]) + __must_be_array(arr))
     132  #endif
     133  
     134  #ifndef PATH_MAX
     135  # define PATH_MAX 4096
     136  #endif
     137  
     138  #ifndef TRUE
     139  # define TRUE 1
     140  #endif
     141  
     142  #ifndef FALSE
     143  # define FALSE 0
     144  #endif
     145  
     146  #ifndef min
     147  # define min(x, y) __extension__ ({		\
     148  	__typeof__(x) _min1 = (x);		\
     149  	__typeof__(y) _min2 = (y);		\
     150  	(void) (&_min1 == &_min2);		\
     151  	_min1 < _min2 ? _min1 : _min2; })
     152  #endif
     153  
     154  #ifndef max
     155  # define max(x, y) __extension__ ({		\
     156  	__typeof__(x) _max1 = (x);		\
     157  	__typeof__(y) _max2 = (y);		\
     158  	(void) (&_max1 == &_max2);		\
     159  	_max1 > _max2 ? _max1 : _max2; })
     160  #endif
     161  
     162  #ifndef abs_diff
     163  # define abs_diff(x, y) __extension__ ({        \
     164  	__typeof__(x) _a = (x);			\
     165  	__typeof__(y) _b = (y);			\
     166  	(void) (&_a == &_b);			\
     167  	_a > _b ? _a - _b : _b - _a; })
     168  #endif
     169  
     170  #ifndef cmp_numbers
     171  # define cmp_numbers(x, y) __extension__ ({	\
     172  	__typeof__(x) _a = (x);			\
     173  	__typeof__(y) _b = (y);			\
     174  	(void) (&_a == &_b);			\
     175  	_a == _b ? 0 : _a > _b ? 1 : -1; })
     176  #endif
     177  
     178  
     179  #ifndef cmp_timespec
     180  # define cmp_timespec(a, b, CMP)		\
     181  	(((a)->tv_sec == (b)->tv_sec)		\
     182  	? ((a)->tv_nsec CMP (b)->tv_nsec)	\
     183  	: ((a)->tv_sec CMP (b)->tv_sec))
     184  #endif
     185  
     186  
     187  #ifndef cmp_stat_mtime
     188  # ifdef HAVE_STRUCT_STAT_ST_MTIM_TV_NSEC
     189  #  define cmp_stat_mtime(_a, _b, CMP)	cmp_timespec(&(_a)->st_mtim, &(_b)->st_mtim, CMP)
     190  # else
     191  #  define cmp_stat_mtime(_a, _b, CMP)	((_a)->st_mtime CMP (_b)->st_mtime)
     192  # endif
     193  #endif
     194  
     195  
     196  #ifndef offsetof
     197  #define offsetof(TYPE, MEMBER) ((size_t) &((TYPE *)0)->MEMBER)
     198  #endif
     199  
     200  #ifndef sizeof_member
     201  #define sizeof_member(TYPE, MEMBER) sizeof(((TYPE *)0)->MEMBER)
     202  #endif
     203  
     204  /*
     205   * container_of - cast a member of a structure out to the containing structure
     206   * @ptr:	the pointer to the member.
     207   * @type:	the type of the container struct this is embedded in.
     208   * @member:	the name of the member within the struct.
     209   */
     210  #ifndef container_of
     211  #define container_of(ptr, type, member) __extension__ ({	\
     212  	const __typeof__( ((type *)0)->member ) *__mptr = (ptr); \
     213  	(type *)( (char *)__mptr - offsetof(type,member) );})
     214  #endif
     215  
     216  #ifndef HAVE_PROGRAM_INVOCATION_SHORT_NAME
     217  # ifdef HAVE___PROGNAME
     218  extern char *__progname;
     219  #  define program_invocation_short_name __progname
     220  # else
     221  #  ifdef HAVE_GETEXECNAME
     222  #   define program_invocation_short_name \
     223  		prog_inv_sh_nm_from_file(getexecname(), 0)
     224  #  else
     225  #   define program_invocation_short_name \
     226  		prog_inv_sh_nm_from_file(__FILE__, 1)
     227  #  endif
     228  static char prog_inv_sh_nm_buf[256];
     229  static inline char *
     230  prog_inv_sh_nm_from_file(char *f, char stripext)
     231  {
     232  	char *t;
     233  
     234  	if ((t = strrchr(f, '/')) != NULL)
     235  		t++;
     236  	else
     237  		t = f;
     238  
     239  	strncpy(prog_inv_sh_nm_buf, t, sizeof(prog_inv_sh_nm_buf) - 1);
     240  	prog_inv_sh_nm_buf[sizeof(prog_inv_sh_nm_buf) - 1] = '\0';
     241  
     242  	if (stripext && (t = strrchr(prog_inv_sh_nm_buf, '.')) != NULL)
     243  		*t = '\0';
     244  
     245  	return prog_inv_sh_nm_buf;
     246  }
     247  # endif
     248  #endif
     249  
     250  
     251  #ifndef HAVE_ERR_H
     252  static inline void __attribute__ ((__format__ (__printf__, 4, 5)))
     253  errmsg(char doexit, int excode, char adderr, const char *fmt, ...)
     254  {
     255  	fprintf(stderr, "%s: ", program_invocation_short_name);
     256  	if (fmt != NULL) {
     257  		va_list argp;
     258  		va_start(argp, fmt);
     259  		vfprintf(stderr, fmt, argp);
     260  		va_end(argp);
     261  		if (adderr)
     262  			fprintf(stderr, ": ");
     263  	}
     264  	if (adderr)
     265  		fprintf(stderr, "%m");
     266  	fprintf(stderr, "\n");
     267  	if (doexit)
     268  		exit(excode);
     269  }
     270  
     271  #ifndef HAVE_ERR
     272  # define err(E, FMT...) errmsg(1, E, 1, FMT)
     273  #endif
     274  
     275  #ifndef HAVE_ERRX
     276  # define errx(E, FMT...) errmsg(1, E, 0, FMT)
     277  #endif
     278  
     279  #ifndef HAVE_WARN
     280  # define warn(FMT...) errmsg(0, 0, 1, FMT)
     281  #endif
     282  
     283  #ifndef HAVE_WARNX
     284  # define warnx(FMT...) errmsg(0, 0, 0, FMT)
     285  #endif
     286  #endif /* !HAVE_ERR_H */
     287  
     288  
     289  static inline
     290  __attribute__((__noreturn__))
     291  void __err_oom(const char *file, unsigned int line)
     292  {
     293  	err(EXIT_FAILURE, "%s: %u: cannot allocate memory", file, line);
     294  }
     295  #define err_oom()	__err_oom(__FILE__, __LINE__)
     296  
     297  
     298  /* Don't use inline function to avoid '#include "nls.h"' in c.h
     299   */
     300  #define errtryhelp(eval) __extension__ ({ \
     301  	fprintf(stderr, _("Try '%s --help' for more information.\n"), \
     302  			program_invocation_short_name); \
     303  	exit(eval); \
     304  })
     305  
     306  /* After failed execvp() */
     307  #define EX_EXEC_FAILED		126	/* Program located, but not usable. */
     308  #define EX_EXEC_ENOENT		127	/* Could not find program to exec.  */
     309  #define errexec(name)	err(errno == ENOENT ? EX_EXEC_ENOENT : EX_EXEC_FAILED, \
     310  			_("failed to execute %s"), name)
     311  
     312  static inline __attribute__((const)) int is_power_of_2(unsigned long num)
     313  {
     314  	return (num != 0 && ((num & (num - 1)) == 0));
     315  }
     316  
     317  #ifndef HAVE_LOFF_T
     318  typedef int64_t loff_t;
     319  #endif
     320  
     321  #if !defined(HAVE_DIRFD) \
     322      && (!defined(HAVE_DECL_DIRFD) || HAVE_DECL_DIRFD == 0) \
     323      && defined(HAVE_DIR_DD_FD)
     324  #include <dirent.h>
     325  static inline int dirfd(DIR *d)
     326  {
     327  	return d->dd_fd;
     328  }
     329  #endif
     330  
     331  /*
     332   * Fallback defines for old versions of glibc
     333   */
     334  #include <fcntl.h>
     335  
     336  #ifdef O_CLOEXEC
     337  #define UL_CLOEXECSTR	"e"
     338  #else
     339  #define UL_CLOEXECSTR	""
     340  #endif
     341  
     342  #ifndef O_CLOEXEC
     343  #define O_CLOEXEC 0
     344  #endif
     345  
     346  #ifdef __FreeBSD_kernel__
     347  #ifndef F_DUPFD_CLOEXEC
     348  #define F_DUPFD_CLOEXEC	17	/* Like F_DUPFD, but FD_CLOEXEC is set */
     349  #endif
     350  #endif
     351  
     352  
     353  #ifndef AI_ADDRCONFIG
     354  #define AI_ADDRCONFIG 0x0020
     355  #endif
     356  
     357  #ifndef IUTF8
     358  #define IUTF8 0040000
     359  #endif
     360  
     361  /*
     362   * MAXHOSTNAMELEN replacement
     363   */
     364  static inline size_t get_hostname_max(void)
     365  {
     366  	long len = sysconf(_SC_HOST_NAME_MAX);
     367  
     368  	if (0 < len)
     369  		return len;
     370  
     371  #ifdef MAXHOSTNAMELEN
     372  	return MAXHOSTNAMELEN;
     373  #elif HOST_NAME_MAX
     374  	return HOST_NAME_MAX;
     375  #endif
     376  	return 64;
     377  }
     378  
     379  
     380  static inline int drop_permissions(void)
     381  {
     382  	errno = 0;
     383  
     384  	/* drop GID */
     385  	if (setgid(getgid()) < 0)
     386  		goto fail;
     387  
     388  	/* drop UID */
     389  	if (setuid(getuid()) < 0)
     390  		goto fail;
     391  
     392  	return 0;
     393  fail:
     394  	return errno ? -errno : -1;
     395  }
     396  
     397  /*
     398   * The usleep function was marked obsolete in POSIX.1-2001 and was removed
     399   * in POSIX.1-2008.  It was replaced with nanosleep() that provides more
     400   * advantages (like no interaction with signals and other timer functions).
     401   */
     402  #include <time.h>
     403  
     404  static inline int xusleep(useconds_t usec)
     405  {
     406  #ifdef HAVE_NANOSLEEP
     407  	struct timespec waittime = {
     408  		.tv_sec   =  usec / 1000000L,
     409  		.tv_nsec  = (usec % 1000000L) * 1000
     410  	};
     411  	return nanosleep(&waittime, NULL);
     412  #elif defined(HAVE_USLEEP)
     413  	return usleep(usec);
     414  #else
     415  # error	"System with usleep() or nanosleep() required!"
     416  #endif
     417  }
     418  
     419  
     420  #define ul_err_write(_m) ignore_result( write(STDERR_FILENO, _m, strlen(_m)) )
     421  
     422  /*
     423   * warn() for signal handlers
     424   */
     425  static inline void ul_sig_warn(const char *mesg)
     426  {
     427  	ul_err_write(program_invocation_short_name);
     428  	ul_err_write(": ");
     429  	ul_err_write(mesg);
     430  	ul_err_write("\n");
     431  }
     432  
     433  /*
     434   * err() for signal handlers
     435   */
     436  static inline void __attribute__((__noreturn__)) ul_sig_err(int excode, const char *mesg)
     437  {
     438  	ul_sig_warn(mesg);
     439  	_exit(excode);
     440  }
     441  
     442  /*
     443   * Constant strings for usage() functions. For more info see
     444   * Documentation/{howto-usage-function.txt,boilerplate.c}
     445   */
     446  #define USAGE_HEADER     _("\nUsage:\n")
     447  #define USAGE_OPTIONS    _("\nOptions:\n")
     448  #define USAGE_FUNCTIONS  _("\nFunctions:\n")
     449  #define USAGE_COMMANDS   _("\nCommands:\n")
     450  #define USAGE_ARGUMENTS   _("\nArguments:\n")
     451  #define USAGE_COLUMNS    _("\nAvailable output columns:\n")
     452  #define USAGE_SEPARATOR    "\n"
     453  
     454  #define USAGE_OPTSTR_HELP     _("display this help")
     455  #define USAGE_OPTSTR_VERSION  _("display version")
     456  
     457  #define USAGE_HELP_OPTIONS(marg_dsc) \
     458  		"%-" #marg_dsc "s%s\n" \
     459  		"%-" #marg_dsc "s%s\n" \
     460  		, " -h, --help",    USAGE_OPTSTR_HELP \
     461  		, " -V, --version", USAGE_OPTSTR_VERSION
     462  
     463  #define USAGE_ARG_SEPARATOR    "\n"
     464  #define USAGE_ARG_SIZE(_name) \
     465  		_(" %s arguments may be followed by the suffixes for\n" \
     466  		  "   GiB, TiB, PiB, EiB, ZiB, and YiB (the \"iB\" is optional)\n"), _name
     467  
     468  #define USAGE_MAN_TAIL(_man)   _("\nFor more details see %s.\n"), _man
     469  
     470  #define UTIL_LINUX_VERSION _("%s from %s\n"), program_invocation_short_name, PACKAGE_STRING
     471  
     472  #define print_version(eval) __extension__ ({ \
     473  		printf(UTIL_LINUX_VERSION); \
     474  		exit(eval); \
     475  })
     476  
     477  static inline void print_features(const char **features, const char *prefix)
     478  {
     479  	if (features && *features) {
     480  		const char **p = features;
     481  		while (p && *p) {
     482  			if (prefix && p == features)
     483  				printf(" (%s ", prefix);
     484  			else
     485  				fputs(p == features ? " (" : ", ", stdout);
     486  			fputs(*p++, stdout);
     487  		}
     488  		fputc(')', stdout);
     489  	}
     490  }
     491  
     492  #define UTIL_LINUX_VERSION_NOBREAK _("%s from %s"), program_invocation_short_name, PACKAGE_STRING
     493  
     494  #define print_version_with_features(eval, features) __extension__ ({ \
     495  		printf(UTIL_LINUX_VERSION_NOBREAK); \
     496  		print_features(features, _("features:")); \
     497  		fputc('\n', stdout); \
     498  		exit(eval); \
     499  })
     500  
     501  /*
     502   * seek stuff
     503   */
     504  #ifndef SEEK_DATA
     505  # define SEEK_DATA	3
     506  #endif
     507  #ifndef SEEK_HOLE
     508  # define SEEK_HOLE	4
     509  #endif
     510  
     511  
     512  /*
     513   * Macros to convert #define'itions to strings, for example
     514   * #define XYXXY 42
     515   * printf ("%s=%s\n", stringify(XYXXY), stringify_value(XYXXY));
     516   */
     517  #define stringify_value(s) stringify(s)
     518  #define stringify(s) #s
     519  
     520  /* Detect if we're compiled with Address Sanitizer
     521   *  - gcc (__SANITIZE_ADDRESS__)
     522   *  - clang (__has_feature(address_sanitizer))
     523   */
     524  #if !defined(HAS_FEATURE_ADDRESS_SANITIZER)
     525  #  ifdef __SANITIZE_ADDRESS__
     526  #      define HAS_FEATURE_ADDRESS_SANITIZER 1
     527  #  elif defined(__has_feature)
     528  #    if __has_feature(address_sanitizer)
     529  #      define HAS_FEATURE_ADDRESS_SANITIZER 1
     530  #    endif
     531  #  endif
     532  #  if !defined(HAS_FEATURE_ADDRESS_SANITIZER)
     533  #    define HAS_FEATURE_ADDRESS_SANITIZER 0
     534  #  endif
     535  #endif
     536  
     537  /*
     538   * UL_ASAN_BLACKLIST is a macro to tell AddressSanitizer (a compile-time
     539   * instrumentation shipped with Clang and GCC) to not instrument the
     540   * annotated function.  Furthermore, it will prevent the compiler from
     541   * inlining the function because inlining currently breaks the blacklisting
     542   * mechanism of AddressSanitizer.
     543   */
     544  #if __has_feature(address_sanitizer) && __has_attribute(no_sanitize_memory) && __has_attribute(no_sanitize_address)
     545  # define UL_ASAN_BLACKLIST __attribute__((noinline)) __attribute__((no_sanitize_memory)) __attribute__((no_sanitize_address))
     546  #else
     547  # define UL_ASAN_BLACKLIST	/* nothing */
     548  #endif
     549  
     550  /*
     551   * Note that sysconf(_SC_GETPW_R_SIZE_MAX) returns *initial* suggested size for
     552   * pwd buffer and in some cases it is not large enough. See POSIX and
     553   * getpwnam_r man page for more details.
     554   */
     555  #define UL_GETPW_BUFSIZ	(16 * 1024)
     556  
     557  /*
     558   * Darwin or other BSDs may only have MAP_ANON. To get it on Darwin we must
     559   * define _DARWIN_C_SOURCE before including sys/mman.h. We do this in config.h.
     560   */
     561  #if !defined MAP_ANONYMOUS && defined MAP_ANON
     562  # define MAP_ANONYMOUS  (MAP_ANON)
     563  #endif
     564  
     565  #define SINT_MAX(t) (((t)1 << (sizeof(t) * 8 - 2)) - (t)1 + ((t)1 << (sizeof(t) * 8 - 2)))
     566  
     567  #endif /* UTIL_LINUX_C_H */