spatch = find_program('spatch', required : false)
if spatch.found()
- # Directories excluded from coccinelle checks until their warnings are fixed.
- # Remove directories from this list as they are cleaned up.
coccinelle_exclude = [
- 'src/basic/',
# libc/ has no assert() or systemd-headers so leave it
'src/libc/',
# test/ has some deliberate wonky pointers, just leave excluded
}
size_t malloc_sizeof_safe(void **xp) {
+ POINTER_MAY_BE_NULL(xp);
+
if (_unlikely_(!xp || !*xp))
return 0;
size_t n;
int r;
+ assert(ret);
+
n = strspn(s, DIGITS);
if (n == 0)
return -EINVAL;
assert(p);
assert(ret);
+ assert(eight_bit);
/* Unescapes C style. Returns the unescaped character in ret.
* Sets *eight_bit to true if the escaped sequence either fits in
}
int ether_addr_compare(const struct ether_addr *a, const struct ether_addr *b) {
+ assert(a);
+ assert(b);
+
return memcmp(a, b, ETH_ALEN);
}
static void ether_addr_hash_func(const struct ether_addr *p, struct siphash *state) {
+ assert(p);
+
siphash24_compress_typesafe(*p, state);
}
const char *save;
int r;
+ assert(p);
+ assert(ret);
+
save = *p;
r = extract_first_word(p, ret, separators, flags);
if (r >= 0)
assert(fd >= 0);
assert(!FLAGS_SET(flags, O_CREAT));
+ assert(ret_new_fd);
/* Invokes fd_reopen(fd, flags), but only if the existing F_GETFL flags don't match the specified
* flags (masked by the specified mask). This is useful for converting O_PATH fds into real fds if
#ifndef __GLIBC__
static bool safe_glob_verify(const char *p, const char *prefix) {
+ POINTER_MAY_BE_NULL(p);
+ POINTER_MAY_BE_NULL(prefix);
+
if (isempty(p))
return false; /* should not happen, but for safey. */
}
int glob_non_glob_prefix(const char *path, char **ret) {
+ assert(path);
+ assert(ret);
+
/* Return the path of the path that has no glob characters. */
size_t n = strcspn(path, GLOB_CHARS);
char *
utf8_prev_char (const char *p)
{
+ assert(p);
+
for (;;)
{
p--;
void, free);
void uint64_hash_func(const uint64_t *p, struct siphash *state) {
+ assert(p);
+
siphash24_compress_typesafe(*p, state);
}
int uint64_compare_func(const uint64_t *a, const uint64_t *b) {
+ assert(a);
+ assert(b);
+
return CMP(*a, *b);
}
#if SIZEOF_DEV_T != 8
void devt_hash_func(const dev_t *p, struct siphash *state) {
+ assert(p);
+
siphash24_compress_typesafe(*p, state);
}
#endif
int devt_compare_func(const dev_t *a, const dev_t *b) {
int r;
+ assert(a);
+ assert(b);
+
r = CMP(major(*a), major(*b));
if (r != 0)
return r;
int hashmap_ensure_put(Hashmap **h, const struct hash_ops *hash_ops, const void *key, void *value) {
int r;
+ assert(h);
+
r = hashmap_ensure_allocated(h, hash_ops);
if (r < 0)
return r;
int ordered_hashmap_ensure_put(OrderedHashmap **h, const struct hash_ops *hash_ops, const void *key, void *value) {
int r;
+ assert(h);
+
r = ordered_hashmap_ensure_allocated(h, hash_ops);
if (r < 0)
return r;
int ordered_hashmap_ensure_replace(OrderedHashmap **h, const struct hash_ops *hash_ops, const void *key, void *value) {
int r;
+ assert(h);
+
r = ordered_hashmap_ensure_allocated(h, hash_ops);
if (r < 0)
return r;
int hashmap_ensure_replace(Hashmap **h, const struct hash_ops *hash_ops, const void *key, void *value) {
int r;
+ assert(h);
+
r = hashmap_ensure_allocated(h, hash_ops);
if (r < 0)
return r;
int set_ensure_put(Set **s, const struct hash_ops *hash_ops, const void *key) {
int r;
+ assert(s);
+
r = set_ensure_allocated(s, hash_ops);
if (r < 0)
return r;
uint8_t u;
int r;
+ assert(ret);
+
if (!IN_SET(family, AF_INET, AF_INET6))
return -EAFNOSUPPORT;
static size_t nul_length(const uint8_t *p, size_t sz) {
size_t n = 0;
+ assert(p);
+
while (sz > 0) {
if (*p != 0)
break;
const char *format,
va_list ap) {
+ assert(iovec);
+ assert(n);
+
while (format && *n + 1 < iovec_len) {
va_list aq;
char *m;
uint64_t mnt_id;
int r;
+ assert(ret);
+
r = path_get_mnt_id_at_internal(dir_fd, path, /* unique = */ false, &mnt_id);
if (r < 0)
return r;
int mount_propagation_flag_from_string(const char *name, unsigned long *ret) {
+ POINTER_MAY_BE_NULL(name);
+ assert(ret);
+
if (isempty(name))
*ret = 0;
else if (streq(name, "shared"))
#include "strv.h"
int ordered_set_ensure_allocated(OrderedSet **s, const struct hash_ops *ops) {
+ assert(s);
+
if (*s)
return 0;
int ordered_set_ensure_put(OrderedSet **s, const struct hash_ops *ops, void *p) {
int r;
+ assert(s);
+
r = ordered_set_ensure_allocated(s, ops);
if (r < 0)
return r;
uint64_t u, m;
int r;
+ assert(ret);
+
r = parse_size(s, 1024, &u);
if (r < 0)
return r;
char *sh;
int r;
+ assert(ret_sh);
+ assert(ret_copy);
+
if (path_is_absolute(s) && path_is_normalized(s)) {
sh = strdup(s);
if (!sh)
unsigned v;
int r;
+ assert(ret);
+
r = safe_atou(s, &v);
if (r < 0)
return r;
unsigned u;
int r;
+ assert(ret);
+
r = safe_atou_full(s, base, &u);
if (r < 0)
return r;
unsigned u;
int r;
+ assert(ret);
+
r = safe_atou_full(s, base, &u);
if (r < 0)
return r;
unsigned val = 0;
const char *s;
+ assert(p);
+ assert(res);
+
s = *p;
/* accept any number of digits, strtoull is limited to 19 */
int parse_nice(const char *s, int *ret) {
int n, r;
+ assert(ret);
+
r = safe_atoi(s, &n);
if (r < 0)
return r;
uint16_t l;
int r;
+ assert(ret);
+
r = safe_atou16_full(s, SAFE_ATO_REFUSE_LEADING_WHITESPACE, &l);
if (r < 0)
return r;
unsigned l, h;
int r;
+ assert(low);
+ assert(high);
+
r = parse_range(s, &l, &h);
if (r < 0)
return r;
va_list ap;
bool slash;
+ POINTER_MAY_BE_NULL(x);
+
/* Joins all listed strings until the sentinel and places a "/" between them unless the strings
* end/begin already with one so that it is unnecessary. Note that slashes which are already
* duplicate won't be removed. The string returned is hence always equal to or longer than the sum of
}
static const char* skip_slash_or_dot(const char *p) {
+ POINTER_MAY_BE_NULL(p);
+
for (; !isempty(p); p++) {
if (*p == '/')
continue;
const char *q, *last_end, *last_begin;
size_t len;
+ POINTER_MAY_BE_NULL(next);
+ POINTER_MAY_BE_NULL(ret);
+
/* Similar to path_find_first_component(), but search components from the end.
*
* Examples
int _prioq_ensure_put(Prioq **q, compare_func_t compare_func, void *data, unsigned *idx) {
int r;
+ assert(q);
+
r = prioq_ensure_allocated(q, compare_func);
if (r < 0)
return r;
int opinionated_personality(unsigned long *ret) {
int current;
+ assert(ret);
+
/* Returns the current personality, or PERSONALITY_INVALID if we can't determine it. This function is a bit
* opinionated though, and ignores all the finer-grained bits and exotic personalities, only distinguishing the
* two most relevant personalities: PER_LINUX and PER_LINUX32. */
int pid_compare_func(const pid_t *a, const pid_t *b) {
/* Suitable for usage in qsort() */
+ assert(a);
+ assert(b);
+
return CMP(*a, *b);
}
#define DEFAULT_RECURSION_MAX 100
static int sort_func(struct dirent * const *a, struct dirent * const *b) {
+ assert(a);
+ assert(b);
+
return strcmp((*a)->d_name, (*b)->d_name);
}
uint64_t rl;
int r;
+ assert(val);
+ assert(ret);
+
/* So, Linux is weird. The range for RLIMIT_NICE is 40..1, mapping to the nice levels -20..19. However, the
* RLIMIT_NICE limit defaults to 0 by the kernel, i.e. a value that maps to nice level 20, which of course is
* bogus and does not exist. In order to permit parsing the RLIMIT_NICE of 0 here we hence implement a slight
/* Note, this returns the port as 'unsigned' rather than 'uint16_t', as AF_VSOCK knows larger ports */
assert(sa);
+ assert(ret_port);
switch (sa->sa.sa_family) {
bool address_label_valid(const char *p) {
+ POINTER_MAY_BE_NULL(p);
+
if (isempty(p))
return false;
int socket_get_mtu(int fd, int af, size_t *ret) {
int mtu, r;
+ assert(ret);
+
if (af == AF_UNSPEC) {
af = socket_get_family(fd);
if (af < 0)
}
int cmp_int(const int *a, const int *b) {
+ assert(a);
+ assert(b);
+
return CMP(*a, *b);
}
int cmp_uint16(const uint16_t *a, const uint16_t *b) {
+ assert(a);
+ assert(b);
+
return CMP(*a, *b);
}
int string_table_lookup_to_string_fallback(const char * const *table, size_t len, ssize_t i, size_t max, char **ret) {
char *s;
+ assert(ret);
+
if (i < 0 || i > (ssize_t) max)
return -ERANGE;
int ascii_strcasecmp_n(const char *a, const char *b, size_t n) {
+ assert(a);
+ assert(b);
+
for (; n > 0; a++, b++, n--) {
int x, y;
}
static size_t previous_ansi_sequence(const char *s, size_t length, const char **ret_where) {
+
+ assert(s);
+ assert(ret_where);
+
/* Locate the previous ANSI sequence and save its start in *ret_where and return length. */
for (size_t i = length - 2; i > 0; i--) { /* -2 because at least two bytes are needed */
size_t n = 0;
assert(s);
+ assert(ret);
/* Truncate after the specified number of lines. Returns > 0 if a truncation was applied or == 0 if
* there were fewer lines in the string anyway. Trailing newlines on input are ignored, and not
const char *p = s;
size_t c = 0;
+ assert(ret);
+
/* Extract the i'nth line from the specified string. Returns > 0 if there are more lines after that,
* and == 0 if we are looking at the last line or already beyond the last line. As special
* optimization, if the first line is requested and the string only consists of one line we return
* If n is not NULL, the size after the push will be returned.
* If value is empty, no action is taken and *n is not set. */
+ assert(l);
+ POINTER_MAY_BE_NULL(n);
+
if (!value)
return 0;
char **c;
size_t n;
+ assert(l);
+
if (!a && !b)
return 0;
}
bool strv_overlap(char * const *a, char * const *b) {
+ POINTER_MAY_BE_NULL(a);
+ POINTER_MAY_BE_NULL(b);
+
STRV_FOREACH(i, a)
if (strv_contains(b, *i))
return true;
}
static int str_compare(char * const *a, char * const *b) {
+ assert(a);
+ assert(b);
+
return strcmp(*a, *b);
}
int strv_compare(char * const *a, char * const *b) {
int r;
+ POINTER_MAY_BE_NULL(a);
+ POINTER_MAY_BE_NULL(b);
+
if (strv_isempty(a)) {
if (strv_isempty(b))
return 0;
uid_t uid;
int r;
+ assert(ret_uid);
+
r = parse_uid(t, &uid);
if (r < 0)
return log_debug_errno(r, "%s: failed to parse %s %s, ignoring: %m", path, name, t);
const char *e;
char *n;
+ assert(name);
+
e = startswith(path, "/org/freedesktop/systemd1/unit/");
if (!e)
return -EINVAL;
size_t len;
assert(str);
+ assert(ret_unichar);
len = utf8_encoded_expected_len(str[0]);
}
size_t char16_strsize(const char16_t *s) {
+ POINTER_MAY_BE_NULL(s);
+
return s ? (char16_strlen(s) + 1) * sizeof(*s) : 0;
}
size_t utf8_n_codepoints(const char *str) {
size_t n = 0;
+ assert(str);
+
/* Returns the number of UTF-8 codepoints in this string, or SIZE_MAX if the string is not valid UTF-8. */
while (*str != 0) {
}
size_t utf8_console_width(const char *str) {
+ POINTER_MAY_BE_NULL(str);
if (isempty(str))
return 0;