10 #include <sys/types.h>
14 #include <shared/macro.h>
16 /* string handling functions and memory allocations */
17 /* ************************************************************************ */
18 #define streq(a, b) (strcmp((a), (b)) == 0)
19 #define strstartswith(a, b) (strncmp(a, b, strlen(b)) == 0)
20 char *strchr_replace(char *s
, char c
, char r
);
21 _nonnull_all_
void *memdup(const void *p
, size_t n
);
23 /* module-related functions */
24 /* ************************************************************************ */
25 #define KMOD_EXTENSION_UNCOMPRESSED ".ko"
27 _must_check_
_nonnull_(1, 2) int alias_normalize(const char *alias
,
28 char buf
[static PATH_MAX
], size_t *len
);
29 _must_check_
int underscores(char *s
);
30 _nonnull_(1, 2) char *modname_normalize(const char *modname
, char buf
[static PATH_MAX
],
32 _nonnull_(2) char *path_to_modname(const char *path
, char buf
[static PATH_MAX
],
34 _nonnull_all_
bool path_ends_with_kmod_ext(const char *path
, size_t len
);
36 /* read-like and fread-like functions */
37 /* ************************************************************************ */
38 _must_check_
_nonnull_(2) ssize_t
pread_str_safe(int fd
, char *buf
, size_t buflen
,
40 _must_check_
_nonnull_(2) ssize_t
read_str_safe(int fd
, char *buf
, size_t buflen
);
41 _nonnull_(2) ssize_t
write_str_safe(int fd
, const char *buf
, size_t buflen
);
42 _must_check_
_nonnull_(2) int read_str_long(int fd
, long *value
, int base
);
43 _must_check_
_nonnull_(2) int read_str_ulong(int fd
, unsigned long *value
, int base
);
44 _nonnull_(1) char *freadline_wrapped(FILE *fp
, unsigned int *linenum
);
46 /* path handling functions */
47 /* ************************************************************************ */
48 _must_check_ _nonnull_all_
char *path_make_absolute_cwd(const char *p
);
49 static inline _must_check_ _nonnull_all_
bool path_is_absolute(const char *p
)
54 int mkdir_p(const char *path
, int len
, mode_t mode
);
55 int mkdir_parents(const char *path
, mode_t mode
);
56 unsigned long long stat_mstamp(const struct stat
*st
);
57 _nonnull_all_
int fd_lookup_path(int fd
, char *path
, size_t pathlen
);
59 /* time-related functions
60 * ************************************************************************ */
61 #define USEC_PER_SEC 1000000ULL
62 #define USEC_PER_MSEC 1000ULL
63 #define MSEC_PER_SEC 1000ULL
64 #define NSEC_PER_MSEC 1000000ULL
66 unsigned long long ts_usec(const struct timespec
*ts
);
67 unsigned long long now_usec(void);
68 unsigned long long now_msec(void);
69 int sleep_until_msec(unsigned long long msec
);
70 unsigned long long get_backoff_delta_msec(unsigned long long tend
,
71 unsigned long long *delta
);
73 /* endianness and alignments */
74 /* ************************************************************************ */
75 #define get_unaligned(ptr) \
77 struct __attribute__((packed)) { \
79 } *__p = (typeof(__p))(ptr); \
83 #define put_unaligned(val, ptr) \
85 struct __attribute__((packed)) { \
87 } *__p = (typeof(__p))(ptr); \
91 static inline unsigned int align_power2(unsigned int u
)
93 return 1 << ((sizeof(u
) * 8) - __builtin_clz(u
- 1));
97 /* ************************************************************************ */
99 static inline bool uadd32_overflow(uint32_t a
, uint32_t b
, uint32_t *res
)
101 #if (HAVE___BUILTIN_UADD_OVERFLOW && __SIZEOF_INT__ == 4)
102 return __builtin_uadd_overflow(a
, b
, res
);
105 return UINT32_MAX
- a
< b
;
109 static inline bool uadd64_overflow(uint64_t a
, uint64_t b
, uint64_t *res
)
111 #if (HAVE___BUILTIN_UADDL_OVERFLOW && __SIZEOF_LONG__ == 8)
112 return __builtin_uaddl_overflow(a
, b
, res
);
113 #elif (HAVE___BUILTIN_UADDLL_OVERFLOW && __SIZEOF_LONG_LONG__ == 8)
114 return __builtin_uaddll_overflow(a
, b
, res
);
117 return UINT64_MAX
- a
< b
;
121 static inline bool uaddsz_overflow(size_t a
, size_t b
, size_t *res
)
123 #if __SIZEOF_SIZE_T__ == 8
124 return uadd64_overflow(a
, b
, res
);
125 #elif __SIZEOF_SIZE_T__ == 4
126 return uadd32_overflow(a
, b
, res
);
128 #error "Unknown sizeof(size_t)"
132 static inline bool umul32_overflow(uint32_t a
, uint32_t b
, uint32_t *res
)
134 #if (HAVE___BUILTIN_UMUL_OVERFLOW && __SIZEOF_INT__ == 4)
135 return __builtin_umul_overflow(a
, b
, res
);
138 return UINT32_MAX
/ a
< b
;
142 static inline bool umul64_overflow(uint64_t a
, uint64_t b
, uint64_t *res
)
144 #if (HAVE___BUILTIN_UMULL_OVERFLOW && __SIZEOF_LONG__ == 8)
145 return __builtin_umull_overflow(a
, b
, res
);
146 #elif (HAVE___BUILTIN_UMULLL_OVERFLOW && __SIZEOF_LONG_LONG__ == 8)
147 return __builtin_umulll_overflow(a
, b
, res
);
150 return UINT64_MAX
/ a
< b
;
154 static inline bool umulll_overflow(unsigned long long a
, unsigned long long b
,
155 unsigned long long *res
)
157 #if (HAVE___BUILTIN_UMULLL_OVERFLOW)
158 return __builtin_umulll_overflow(a
, b
, res
);
161 return UINT64_MAX
/ a
< b
;
165 static inline bool umulsz_overflow(size_t a
, size_t b
, size_t *res
)
167 #if __SIZEOF_SIZE_T__ == 8
168 return umul64_overflow(a
, b
, res
);
169 #elif __SIZEOF_SIZE_T__ == 4
170 return umul32_overflow(a
, b
, res
);
172 #error "Unknown sizeof(size_t)"
176 #define TAKE_PTR(x) \
184 /* ************************************************************************ */
187 * Load many various symbols from @filename.
188 * @dlp: pointer to the previous results of this call: it's set when it succeeds
189 * @filename: the library to dlopen() and look for symbols
190 * @...: or 1 more tuples created by DLSYM_ARG() with ( &var, "symbol name" ).
192 _sentinel_
int dlsym_many(void **dlp
, const char *filename
, ...);
195 * Helper to create tuples passed as arguments to dlsym_many().
196 * @symbol__: symbol to create arguments for. Example: DLSYM_ARG(foo) expands to
199 #define DLSYM_ARG(symbol__) &sym_##symbol__, STRINGIFY(symbol__),
201 /* For symbols being dynamically loaded */
202 #define DECLARE_DLSYM(symbol) static typeof(symbol) *sym_##symbol
204 /* Pointer indirection to support linking directly */
205 #define DECLARE_PTRSYM(symbol) static typeof(symbol) *sym_##symbol = symbol
208 * Helper defines, to be done locally before including this header to switch between
211 #if defined(DLSYM_LOCALLY_ENABLED) && DLSYM_LOCALLY_ENABLED
212 #define DECLARE_SYM(sym__) DECLARE_DLSYM(sym__);
214 #define DECLARE_SYM(sym__) DECLARE_PTRSYM(sym__);