2010-08-17 05:33:07 +04:00
/*-*- Mode: C; c-basic-offset: 8; indent-tabs-mode: nil -*-*/
2009-11-18 02:42:52 +03:00
2012-07-18 21:07:51 +04:00
# pragma once
2009-11-18 02:42:52 +03:00
2010-02-03 15:03:47 +03:00
/***
This file is part of systemd .
Copyright 2010 Lennart Poettering
systemd is free software ; you can redistribute it and / or modify it
2012-04-12 02:20:58 +04:00
under the terms of the GNU Lesser General Public License as published by
the Free Software Foundation ; either version 2.1 of the License , or
2010-02-03 15:03:47 +03:00
( at your option ) any later version .
systemd is distributed in the hope that it will be useful , but
WITHOUT ANY WARRANTY ; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE . See the GNU
2012-04-12 02:20:58 +04:00
Lesser General Public License for more details .
2010-02-03 15:03:47 +03:00
2012-04-12 02:20:58 +04:00
You should have received a copy of the GNU Lesser General Public License
2010-02-03 15:03:47 +03:00
along with systemd ; If not , see < http : //www.gnu.org/licenses/>.
* * */
2009-11-18 02:42:52 +03:00
# include <assert.h>
2012-02-29 17:42:49 +04:00
# include <sys/param.h>
2009-11-18 02:42:52 +03:00
# include <sys/types.h>
2010-09-08 05:07:44 +04:00
# include <sys/uio.h>
# include <inttypes.h>
2009-11-18 02:42:52 +03:00
2010-06-02 23:34:03 +04:00
# define _printf_attr_(a,b) __attribute__ ((format (printf, a, b)))
2013-04-26 03:59:35 +04:00
# define _alloc_(...) __attribute__ ((alloc_size(__VA_ARGS__)))
2010-06-02 23:34:03 +04:00
# define _sentinel_ __attribute__ ((sentinel))
# define _noreturn_ __attribute__((noreturn))
# define _unused_ __attribute__ ((unused))
# define _destructor_ __attribute__ ((destructor))
# define _pure_ __attribute__ ((pure))
# define _const_ __attribute__ ((const))
# define _deprecated_ __attribute__ ((deprecated))
# define _packed_ __attribute__ ((packed))
# define _malloc_ __attribute__ ((malloc))
# define _weak_ __attribute__ ((weak))
# define _likely_(x) (__builtin_expect(!!(x),1))
# define _unlikely_(x) (__builtin_expect(!!(x),0))
2010-06-21 21:17:47 +04:00
# define _public_ __attribute__ ((visibility("default")))
# define _hidden_ __attribute__ ((visibility("hidden")))
2010-07-16 05:07:53 +04:00
# define _weakref_(x) __attribute__((weakref(#x)))
2010-11-23 23:12:11 +03:00
# define _introspect_(x) __attribute__((section("introspect." x)))
2012-07-15 16:58:29 +04:00
# define _alignas_(x) __attribute__((aligned(__alignof(x))))
2013-04-16 07:25:57 +04:00
# define _cleanup_(x) __attribute__((cleanup(x)))
2009-11-18 02:42:52 +03:00
2013-03-27 05:07:46 +04:00
/* automake test harness */
# define EXIT_TEST_SKIP 77
2011-01-04 03:58:38 +03:00
# define XSTRINGIFY(x) #x
# define STRINGIFY(x) XSTRINGIFY(x)
2009-11-18 02:42:52 +03:00
/* Rounds up */
2013-04-11 04:07:14 +04:00
# define ALIGN4(l) (((l) + 3) & ~3)
# define ALIGN8(l) (((l) + 7) & ~7)
# if __SIZEOF_POINTER__ == 8
# define ALIGN(l) ALIGN8(l)
# elif __SIZEOF_POINTER__ == 4
# define ALIGN(l) ALIGN4(l)
# else
# error "Wut? Pointers are neither 4 nor 8 bytes long?"
# endif
2013-04-16 16:50:05 +04:00
# define ALIGN_PTR(p) ((void*) ALIGN((unsigned long) p))
# define ALIGN4_PTR(p) ((void*) ALIGN4((unsigned long) p))
2013-04-12 23:43:50 +04:00
# define ALIGN8_PTR(p) ((void*) ALIGN8((unsigned long) p))
2011-03-18 05:03:41 +03:00
static inline size_t ALIGN_TO ( size_t l , size_t ali ) {
return ( ( l + ali - 1 ) & ~ ( ali - 1 ) ) ;
2010-09-23 17:01:41 +04:00
}
2013-04-16 16:50:05 +04:00
# define ALIGN_TO_PTR(p, ali) ((void*) ALIGN_TO((unsigned long) p))
2009-11-18 02:42:52 +03:00
# define ELEMENTSOF(x) (sizeof(x) / sizeof((x)[0]))
2012-05-07 23:06:55 +04:00
/*
* container_of - cast a member of a structure out to the containing structure
* @ ptr : the pointer to the member .
* @ type : the type of the container struct this is embedded in .
* @ member : the name of the member within the struct .
*
*/
2013-04-02 19:33:19 +04:00
# define container_of(ptr, type, member) \
__extension__ ( { \
const typeof ( ( ( type * ) 0 ) - > member ) * __mptr = ( ptr ) ; \
( type * ) ( ( char * ) __mptr - offsetof ( type , member ) ) ; \
} )
2012-05-07 23:06:55 +04:00
2013-04-01 10:08:05 +04:00
# undef MAX
# define MAX(a,b) \
__extension__ ( { \
typeof ( a ) _a = ( a ) ; \
typeof ( b ) _b = ( b ) ; \
_a > _b ? _a : _b ; \
2009-11-18 02:42:52 +03:00
} )
2013-04-01 10:08:05 +04:00
# define MAX3(x,y,z) \
__extension__ ( { \
typeof ( x ) _c = MAX ( x , y ) ; \
MAX ( _c , z ) ; \
} )
2010-10-19 00:38:41 +04:00
2013-04-01 10:08:05 +04:00
# undef MIN
2009-11-18 02:42:52 +03:00
# define MIN(a,b) \
__extension__ ( { \
typeof ( a ) _a = ( a ) ; \
typeof ( b ) _b = ( b ) ; \
_a < _b ? _a : _b ; \
} )
2013-03-19 23:00:29 +04:00
# ifndef CLAMP
2009-11-18 02:42:52 +03:00
# define CLAMP(x, low, high) \
__extension__ ( { \
typeof ( x ) _x = ( x ) ; \
typeof ( low ) _low = ( low ) ; \
typeof ( high ) _high = ( high ) ; \
( ( _x > _high ) ? _high : ( ( _x < _low ) ? _low : _x ) ) ; \
} )
2013-03-19 23:00:29 +04:00
# endif
2009-11-18 02:42:52 +03:00
2010-04-13 05:59:39 +04:00
# define assert_se(expr) \
do { \
2010-06-02 23:34:03 +04:00
if ( _unlikely_ ( ! ( expr ) ) ) \
2012-01-17 15:05:33 +04:00
log_assert_failed ( # expr , __FILE__ , __LINE__ , __PRETTY_FUNCTION__ ) ; \
2010-04-13 05:59:39 +04:00
} while ( false ) \
/* We override the glibc assert() here. */
# undef assert
# ifdef NDEBUG
# define assert(expr) do {} while(false)
# else
# define assert(expr) assert_se(expr)
# endif
2009-11-18 02:42:52 +03:00
2010-04-13 05:59:39 +04:00
# define assert_not_reached(t) \
do { \
2012-01-17 15:05:33 +04:00
log_assert_failed_unreachable ( t , __FILE__ , __LINE__ , __PRETTY_FUNCTION__ ) ; \
2010-04-13 05:59:39 +04:00
} while ( false )
2009-11-18 02:42:52 +03:00
2012-12-25 14:52:14 +04:00
# if defined(static_assert)
# define assert_cc(expr) \
do { \
static_assert ( expr , # expr ) ; \
2009-11-18 02:42:52 +03:00
} while ( false )
2012-12-25 14:52:14 +04:00
# else
# define assert_cc(expr) \
do { \
switch ( 0 ) { \
case 0 : \
case ! ! ( expr ) : \
; \
} \
} while ( false )
# endif
2009-11-18 02:42:52 +03:00
2013-05-14 18:13:52 +04:00
# define PTR_TO_INT(p) ((int) ((intptr_t) (p)))
# define INT_TO_PTR(u) ((void *) ((intptr_t) (u)))
2009-11-18 02:42:52 +03:00
# define PTR_TO_UINT(p) ((unsigned int) ((uintptr_t) (p)))
2013-05-14 18:13:52 +04:00
# define UINT_TO_PTR(u) ((void *) ((uintptr_t) (u)))
2009-11-18 02:42:52 +03:00
2013-05-14 18:13:52 +04:00
# define PTR_TO_LONG(p) ((long) ((intptr_t) (p)))
# define LONG_TO_PTR(u) ((void *) ((intptr_t) (u)))
2010-07-11 02:50:49 +04:00
# define PTR_TO_ULONG(p) ((unsigned long) ((uintptr_t) (p)))
2013-05-14 18:13:52 +04:00
# define ULONG_TO_PTR(u) ((void *) ((uintptr_t) (u)))
2010-07-11 02:50:49 +04:00
2013-05-14 18:13:52 +04:00
# define PTR_TO_INT32(p) ((int32_t) ((intptr_t) (p)))
# define INT32_TO_PTR(u) ((void *) ((intptr_t) (u)))
# define PTR_TO_UINT32(p) ((uint32_t) ((uintptr_t) (p)))
# define UINT32_TO_PTR(u) ((void *) ((uintptr_t) (u)))
2009-11-18 02:42:52 +03:00
2013-05-14 18:13:52 +04:00
# define PTR_TO_INT64(p) ((int64_t) ((intptr_t) (p)))
# define INT64_TO_PTR(u) ((void *) ((intptr_t) (u)))
# define PTR_TO_UINT64(p) ((uint64_t) ((uintptr_t) (p)))
# define UINT64_TO_PTR(u) ((void *) ((uintptr_t) (u)))
2010-07-11 02:50:49 +04:00
2010-01-24 02:38:51 +03:00
# define memzero(x,l) (memset((x), 0, (l)))
# define zero(x) (memzero(&(x), sizeof(x)))
2013-03-19 23:00:55 +04:00
# define CHAR_TO_STR(x) ((char[2]) { x, 0 })
2010-01-26 06:18:44 +03:00
# define char_array_0(x) x[sizeof(x)-1] = 0;
2013-06-21 06:40:10 +04:00
# define hasprefix(s, prefix) (memcmp(s, prefix, strlen(prefix)) == 0)
2010-05-15 19:22:58 +04:00
# define IOVEC_SET_STRING(i, s) \
2010-04-06 23:54:19 +04:00
do { \
2010-05-15 19:22:58 +04:00
struct iovec * _i = & ( i ) ; \
char * _s = ( char * ) ( s ) ; \
_i - > iov_base = _s ; \
_i - > iov_len = strlen ( _s ) ; \
2011-11-08 21:18:48 +04:00
} while ( false )
2010-04-06 23:54:19 +04:00
2010-09-08 05:07:44 +04:00
static inline size_t IOVEC_TOTAL_SIZE ( const struct iovec * i , unsigned n ) {
unsigned j ;
size_t r = 0 ;
for ( j = 0 ; j < n ; j + + )
r + = i [ j ] . iov_len ;
return r ;
}
static inline size_t IOVEC_INCREMENT ( struct iovec * i , unsigned n , size_t k ) {
unsigned j ;
for ( j = 0 ; j < n ; j + + ) {
size_t sub ;
if ( _unlikely_ ( k < = 0 ) )
break ;
sub = MIN ( i [ j ] . iov_len , k ) ;
i [ j ] . iov_len - = sub ;
i [ j ] . iov_base = ( uint8_t * ) i [ j ] . iov_base + sub ;
k - = sub ;
}
return k ;
}
2012-09-25 01:42:29 +04:00
# define VA_FORMAT_ADVANCE(format, ap) \
do { \
int _argtypes [ 128 ] ; \
2012-09-25 01:22:19 +04:00
size_t _i , _k ; \
_k = parse_printf_format ( ( format ) , ELEMENTSOF ( _argtypes ) , _argtypes ) ; \
2012-09-25 01:42:29 +04:00
assert ( _k < ELEMENTSOF ( _argtypes ) ) ; \
2012-09-25 01:22:19 +04:00
for ( _i = 0 ; _i < _k ; _i + + ) { \
if ( _argtypes [ _i ] & PA_FLAG_PTR ) { \
( void ) va_arg ( ap , void * ) ; \
continue ; \
} \
\
switch ( _argtypes [ _i ] ) { \
case PA_INT : \
case PA_INT | PA_FLAG_SHORT : \
case PA_CHAR : \
( void ) va_arg ( ap , int ) ; \
break ; \
case PA_INT | PA_FLAG_LONG : \
( void ) va_arg ( ap , long int ) ; \
break ; \
case PA_INT | PA_FLAG_LONG_LONG : \
( void ) va_arg ( ap , long long int ) ; \
break ; \
case PA_WCHAR : \
( void ) va_arg ( ap , wchar_t ) ; \
break ; \
case PA_WSTRING : \
case PA_STRING : \
case PA_POINTER : \
( void ) va_arg ( ap , void * ) ; \
break ; \
case PA_FLOAT : \
case PA_DOUBLE : \
( void ) va_arg ( ap , double ) ; \
break ; \
case PA_DOUBLE | PA_FLAG_LONG_DOUBLE : \
( void ) va_arg ( ap , long double ) ; \
break ; \
default : \
assert_not_reached ( " Unknown format string argument. " ) ; \
} \
} \
} while ( false )
Reintroduce f_type comparison macro
This reverts commit 4826f0b7b5c0aefa08b8cc7ef64d69027f84da2c.
Because statfs.t_type can be int on some architecures, we have to cast
the const magic to the type, otherwise the compiler warns about
signed/unsigned comparison, because the magic can be 32 bit unsigned.
statfs(2) man page is also wrong on some systems, because
f_type is not __SWORD_TYPE on some architecures.
The following program:
int main(int argc, char**argv)
{
struct statfs s;
statfs(argv[1], &s);
printf("sizeof(f_type) = %d\n", sizeof(s.f_type));
printf("sizeof(__SWORD_TYPE) = %d\n", sizeof(__SWORD_TYPE));
printf("sizeof(long) = %d\n", sizeof(long));
printf("sizeof(int) = %d\n", sizeof(int));
if (sizeof(s.f_type) == sizeof(int)) {
printf("f_type = 0x%x\n", s.f_type);
} else {
printf("f_type = 0x%lx\n", s.f_type);
}
return 0;
}
executed on s390x gives for a btrfs:
sizeof(f_type) = 4
sizeof(__SWORD_TYPE) = 8
sizeof(long) = 8
sizeof(int) = 4
f_type = 0x9123683e
2013-04-19 15:44:56 +04:00
/* Because statfs.t_type can be int on some architecures, we have to cast
* the const magic to the type , otherwise the compiler warns about
* signed / unsigned comparison , because the magic can be 32 bit unsigned .
*/
# define F_TYPE_CMP(a, b) (a == (typeof(a)) b)
2013-04-02 19:33:19 +04:00
/* Returns the number of chars needed to format variables of the
* specified type as a decimal string . Adds in extra space for a
* negative ' - ' prefix . */
# define DECIMAL_STR_MAX(type) \
( 1 + ( sizeof ( type ) < = 1 ? 3 : \
sizeof ( type ) < = 2 ? 5 : \
sizeof ( type ) < = 4 ? 10 : \
sizeof ( type ) < = 8 ? 20 : sizeof ( int [ - 2 * ( sizeof ( type ) > 8 ) ] ) ) )
2013-05-17 06:25:56 +04:00
# define SET_FLAG(v, flag, b) \
( v ) = ( b ) ? ( ( v ) | ( flag ) ) : ( ( v ) & ~ ( flag ) )
2010-04-13 05:59:39 +04:00
# include "log.h"