Commit 5437448a authored by Thomas Haller's avatar Thomas Haller

systemd: update code from upstream (2018-10-27)

This is a direct dump from systemd git.

======

SYSTEMD_DIR=../systemd
COMMIT=e6b538d06680857fb25e2a6da94fc416bb2340f5

(
  cd "$SYSTEMD_DIR"
  git checkout "$COMMIT"
  git reset --hard
  git clean -fdx
)

git ls-files :/src/systemd/src/ \
             :/shared/nm-utils/unaligned.h | \
  xargs -d '\n' rm -f

nm_copy_sd() {
    mkdir -p "./src/systemd/$(dirname "$1")"
    cp "$SYSTEMD_DIR/$1" "./src/systemd/$1"
}

nm_copy_sd_shared() {
    mkdir -p "./shared/nm-utils/"
    cp "$SYSTEMD_DIR/$1" "./shared/nm-utils/${1##*/}"
}

nm_copy_sd "src/basic/alloc-util.c"
nm_copy_sd "src/basic/alloc-util.h"
nm_copy_sd "src/basic/async.h"
nm_copy_sd "src/basic/env-util.c"
nm_copy_sd "src/basic/env-util.h"
nm_copy_sd "src/basic/escape.c"
nm_copy_sd "src/basic/escape.h"
nm_copy_sd "src/basic/ether-addr-util.c"
nm_copy_sd "src/basic/ether-addr-util.h"
nm_copy_sd "src/basic/extract-word.c"
nm_copy_sd "src/basic/extract-word.h"
nm_copy_sd "src/basic/fileio.c"
nm_copy_sd "src/basic/fileio.h"
nm_copy_sd "src/basic/fd-util.c"
nm_copy_sd "src/basic/fd-util.h"
nm_copy_sd "src/basic/fs-util.c"
nm_copy_sd "src/basic/fs-util.h"
nm_copy_sd "src/basic/hash-funcs.c"
nm_copy_sd "src/basic/hash-funcs.h"
nm_copy_sd "src/basic/hashmap.c"
nm_copy_sd "src/basic/hashmap.h"
nm_copy_sd "src/basic/hexdecoct.c"
nm_copy_sd "src/basic/hexdecoct.h"
nm_copy_sd "src/basic/hostname-util.c"
nm_copy_sd "src/basic/hostname-util.h"
nm_copy_sd "src/basic/in-addr-util.c"
nm_copy_sd "src/basic/in-addr-util.h"
nm_copy_sd "src/basic/io-util.c"
nm_copy_sd "src/basic/io-util.h"
nm_copy_sd "src/basic/list.h"
nm_copy_sd "src/basic/log.h"
nm_copy_sd "src/basic/macro.h"
nm_copy_sd "src/basic/mempool.h"
nm_copy_sd "src/basic/mempool.c"
nm_copy_sd "src/basic/parse-util.c"
nm_copy_sd "src/basic/parse-util.h"
nm_copy_sd "src/basic/path-util.c"
nm_copy_sd "src/basic/path-util.h"
nm_copy_sd "src/basic/prioq.h"
nm_copy_sd "src/basic/prioq.c"
nm_copy_sd "src/basic/process-util.h"
nm_copy_sd "src/basic/process-util.c"
nm_copy_sd "src/basic/random-util.c"
nm_copy_sd "src/basic/random-util.h"
nm_copy_sd "src/basic/refcnt.h"
nm_copy_sd "src/basic/set.h"
nm_copy_sd "src/basic/signal-util.h"
nm_copy_sd "src/basic/siphash24.h"
nm_copy_sd "src/basic/socket-util.c"
nm_copy_sd "src/basic/socket-util.h"
nm_copy_sd "src/basic/sparse-endian.h"
nm_copy_sd "src/basic/stat-util.c"
nm_copy_sd "src/basic/stat-util.h"
nm_copy_sd "src/basic/stdio-util.h"
nm_copy_sd "src/basic/string-table.c"
nm_copy_sd "src/basic/string-table.h"
nm_copy_sd "src/basic/string-util.c"
nm_copy_sd "src/basic/string-util.h"
nm_copy_sd "src/basic/strv.c"
nm_copy_sd "src/basic/strv.h"
nm_copy_sd "src/basic/time-util.c"
nm_copy_sd "src/basic/time-util.h"
nm_copy_sd "src/basic/umask-util.h"
nm_copy_sd_shared "src/basic/unaligned.h"
nm_copy_sd "src/basic/utf8.c"
nm_copy_sd "src/basic/utf8.h"
nm_copy_sd "src/basic/util.c"
nm_copy_sd "src/basic/util.h"
nm_copy_sd "src/libsystemd-network/arp-util.c"
nm_copy_sd "src/libsystemd-network/arp-util.h"
nm_copy_sd "src/libsystemd-network/dhcp6-internal.h"
nm_copy_sd "src/libsystemd-network/dhcp6-lease-internal.h"
nm_copy_sd "src/libsystemd-network/dhcp6-network.c"
nm_copy_sd "src/libsystemd-network/dhcp6-option.c"
nm_copy_sd "src/libsystemd-network/dhcp6-protocol.h"
nm_copy_sd "src/libsystemd-network/dhcp-identifier.c"
nm_copy_sd "src/libsystemd-network/dhcp-identifier.h"
nm_copy_sd "src/libsystemd-network/dhcp-internal.h"
nm_copy_sd "src/libsystemd-network/dhcp-lease-internal.h"
nm_copy_sd "src/libsystemd-network/dhcp-network.c"
nm_copy_sd "src/libsystemd-network/dhcp-option.c"
nm_copy_sd "src/libsystemd-network/dhcp-packet.c"
nm_copy_sd "src/libsystemd-network/dhcp-protocol.h"
nm_copy_sd "src/libsystemd-network/lldp-internal.h"
nm_copy_sd "src/libsystemd-network/lldp-neighbor.c"
nm_copy_sd "src/libsystemd-network/lldp-neighbor.h"
nm_copy_sd "src/libsystemd-network/lldp-network.c"
nm_copy_sd "src/libsystemd-network/lldp-network.h"
nm_copy_sd "src/libsystemd-network/network-internal.c"
nm_copy_sd "src/libsystemd-network/network-internal.h"
nm_copy_sd "src/libsystemd-network/sd-dhcp6-client.c"
nm_copy_sd "src/libsystemd-network/sd-dhcp6-lease.c"
nm_copy_sd "src/libsystemd-network/sd-dhcp-client.c"
nm_copy_sd "src/libsystemd-network/sd-dhcp-lease.c"
nm_copy_sd "src/libsystemd-network/sd-ipv4ll.c"
nm_copy_sd "src/libsystemd-network/sd-ipv4acd.c"
nm_copy_sd "src/libsystemd-network/sd-lldp.c"
nm_copy_sd "src/libsystemd/sd-event/sd-event.c"
nm_copy_sd "src/libsystemd/sd-id128/id128-util.c"
nm_copy_sd "src/libsystemd/sd-id128/id128-util.h"
nm_copy_sd "src/libsystemd/sd-id128/sd-id128.c"
nm_copy_sd "src/shared/dns-domain.c"
nm_copy_sd "src/shared/dns-domain.h"
nm_copy_sd "src/systemd/_sd-common.h"
nm_copy_sd "src/systemd/sd-dhcp6-client.h"
nm_copy_sd "src/systemd/sd-dhcp6-lease.h"
nm_copy_sd "src/systemd/sd-dhcp-client.h"
nm_copy_sd "src/systemd/sd-dhcp-lease.h"
nm_copy_sd "src/systemd/sd-event.h"
nm_copy_sd "src/systemd/sd-ndisc.h"
nm_copy_sd "src/systemd/sd-id128.h"
nm_copy_sd "src/systemd/sd-ipv4acd.h"
nm_copy_sd "src/systemd/sd-ipv4ll.h"
nm_copy_sd "src/systemd/sd-lldp.h"
parent 2e5d35f2
......@@ -46,6 +46,21 @@ static inline void *mfree(void *memory) {
void* memdup(const void *p, size_t l) _alloc_(2);
void* memdup_suffix0(const void *p, size_t l) _alloc_(2);
#define memdupa(p, l) \
({ \
void *_q_; \
_q_ = alloca(l); \
memcpy(_q_, p, l); \
})
#define memdupa_suffix0(p, l) \
({ \
void *_q_; \
_q_ = alloca(l + 1); \
((uint8_t*) _q_)[l] = 0; \
memcpy(_q_, p, l); \
})
static inline void freep(void *p) {
free(*(void**) p);
}
......
......@@ -21,10 +21,6 @@
DIGITS LETTERS \
"_"
#ifndef ARG_MAX
#define ARG_MAX ((size_t) sysconf(_SC_ARG_MAX))
#endif
static bool env_name_is_valid_n(const char *e, size_t n) {
const char *p;
......@@ -42,7 +38,7 @@ static bool env_name_is_valid_n(const char *e, size_t n) {
* either. Discounting the equal sign and trailing NUL this
* hence leaves ARG_MAX-2 as longest possible variable
* name. */
if (n > ARG_MAX - 2)
if (n > (size_t) sysconf(_SC_ARG_MAX) - 2)
return false;
for (p = e; p < e + n; p++)
......@@ -76,7 +72,7 @@ bool env_value_is_valid(const char *e) {
* either. Discounting the shortest possible variable name of
* length 1, the equal sign and trailing NUL this hence leaves
* ARG_MAX-3 as longest possible variable value. */
if (strlen(e) > ARG_MAX - 3)
if (strlen(e) > (size_t) sysconf(_SC_ARG_MAX) - 3)
return false;
return true;
......@@ -99,7 +95,7 @@ bool env_assignment_is_valid(const char *e) {
* be > ARG_MAX, hence the individual variable assignments
* cannot be either, but let's leave room for one trailing NUL
* byte. */
if (strlen(e) > ARG_MAX - 1)
if (strlen(e) > (size_t) sysconf(_SC_ARG_MAX) - 1)
return false;
return true;
......@@ -125,30 +121,28 @@ bool strv_env_is_valid(char **e) {
}
bool strv_env_name_is_valid(char **l) {
char **p, **q;
char **p;
STRV_FOREACH(p, l) {
if (!env_name_is_valid(*p))
return false;
STRV_FOREACH(q, p + 1)
if (streq(*p, *q))
return false;
if (strv_contains(p + 1, *p))
return false;
}
return true;
}
bool strv_env_name_or_assignment_is_valid(char **l) {
char **p, **q;
char **p;
STRV_FOREACH(p, l) {
if (!env_assignment_is_valid(*p) && !env_name_is_valid(*p))
return false;
STRV_FOREACH(q, p + 1)
if (streq(*p, *q))
return false;
if (strv_contains(p + 1, *p))
return false;
}
return true;
......@@ -157,20 +151,23 @@ bool strv_env_name_or_assignment_is_valid(char **l) {
static int env_append(char **r, char ***k, char **a) {
assert(r);
assert(k);
assert(*k >= r);
if (!a)
return 0;
/* Add the entries of a to *k unless they already exist in *r
* in which case they are overridden instead. This assumes
* there is enough space in the r array. */
/* Expects the following arguments: 'r' shall point to the beginning of an strv we are going to append to, 'k'
* to a pointer pointing to the NULL entry at the end of the same array. 'a' shall point to another strv.
*
* This call adds every entry of 'a' to 'r', either overriding an existing matching entry, or appending to it.
*
* This call assumes 'r' has enough pre-allocated space to grow by all of 'a''s items. */
for (; *a; a++) {
char **j;
char **j, *c;
size_t n;
n = strcspn(*a, "=");
if ((*a)[n] == '=')
n++;
......@@ -178,24 +175,26 @@ static int env_append(char **r, char ***k, char **a) {
if (strneq(*j, *a, n))
break;
if (j >= *k)
(*k)++;
else
free(*j);
*j = strdup(*a);
if (!*j)
c = strdup(*a);
if (!c)
return -ENOMEM;
if (j >= *k) { /* Append to the end? */
(*k)[0] = c;
(*k)[1] = NULL;
(*k)++;
} else
free_and_replace(*j, c); /* Override existing item */
}
return 0;
}
char **strv_env_merge(size_t n_lists, ...) {
size_t n = 0;
char **l, **k, **r;
_cleanup_strv_free_ char **ret = NULL;
size_t n = 0, i;
char **l, **k;
va_list ap;
size_t i;
/* Merges an arbitrary number of environment sets */
......@@ -206,29 +205,24 @@ char **strv_env_merge(size_t n_lists, ...) {
}
va_end(ap);
r = new(char*, n+1);
if (!r)
ret = new(char*, n+1);
if (!ret)
return NULL;
k = r;
*ret = NULL;
k = ret;
va_start(ap, n_lists);
for (i = 0; i < n_lists; i++) {
l = va_arg(ap, char**);
if (env_append(r, &k, l) < 0)
goto fail;
if (env_append(ret, &k, l) < 0) {
va_end(ap);
return NULL;
}
}
va_end(ap);
*k = NULL;
return r;
fail:
va_end(ap);
strv_free(r);
return NULL;
return TAKE_PTR(ret);
}
static bool env_match(const char *t, const char *pattern) {
......@@ -382,22 +376,23 @@ char **strv_env_unset_many(char **l, ...) {
}
int strv_env_replace(char ***l, char *p) {
char **f;
const char *t, *name;
char **f;
int r;
assert(p);
/* Replace first occurrence of the env var or add a new one in the
* string list. Drop other occurrences. Edits in-place. Does not copy p.
* p must be a valid key=value assignment.
/* Replace first occurrence of the env var or add a new one in the string list. Drop other occurrences. Edits
* in-place. Does not copy p. p must be a valid key=value assignment.
*/
t = strchr(p, '=');
assert(t);
if (!t)
return -EINVAL;
name = strndupa(p, t - p);
for (f = *l; f && *f; f++)
STRV_FOREACH(f, *l)
if (env_entry_has_name(*f, name)) {
free_and_replace(*f, p);
strv_env_unset(f + 1, *f);
......@@ -405,33 +400,40 @@ int strv_env_replace(char ***l, char *p) {
}
/* We didn't find a match, we need to append p or create a new strv */
if (strv_push(l, p) < 0)
return -ENOMEM;
r = strv_push(l, p);
if (r < 0)
return r;
return 1;
}
char **strv_env_set(char **x, const char *p) {
_cleanup_strv_free_ char **ret = NULL;
size_t n, m;
char **k;
_cleanup_strv_free_ char **r = NULL;
char* m[2] = { (char*) p, NULL };
/* Overrides the env var setting of p, returns a new copy */
r = new(char*, strv_length(x)+2);
if (!r)
n = strv_length(x);
m = n + 2;
if (m < n) /* overflow? */
return NULL;
k = r;
if (env_append(r, &k, x) < 0)
ret = new(char*, m);
if (!ret)
return NULL;
if (env_append(r, &k, m) < 0)
*ret = NULL;
k = ret;
if (env_append(ret, &k, x) < 0)
return NULL;
*k = NULL;
if (env_append(ret, &k, STRV_MAKE(p)) < 0)
return NULL;
return TAKE_PTR(r);
return TAKE_PTR(ret);
}
char *strv_env_get_n(char **l, const char *name, size_t k, unsigned flags) {
......@@ -750,36 +752,3 @@ int getenv_bool_secure(const char *p) {
return parse_boolean(e);
}
int serialize_environment(FILE *f, char **environment) {
char **e;
STRV_FOREACH(e, environment) {
_cleanup_free_ char *ce;
ce = cescape(*e);
if (!ce)
return -ENOMEM;
fprintf(f, "env=%s\n", ce);
}
/* caller should call ferror() */
return 0;
}
int deserialize_environment(char ***environment, const char *line) {
char *uce;
int r;
assert(line);
assert(environment);
assert(startswith(line, "env="));
r = cunescape(line + 4, 0, &uce);
if (r < 0)
return r;
return strv_env_replace(environment, uce);
}
......@@ -45,6 +45,3 @@ char *strv_env_get(char **x, const char *n) _pure_;
int getenv_bool(const char *p);
int getenv_bool_secure(const char *p);
int serialize_environment(FILE *f, char **environment);
int deserialize_environment(char ***environment, const char *line);
......@@ -353,22 +353,22 @@ bool fdname_is_valid(const char *s) {
}
int fd_get_path(int fd, char **ret) {
_cleanup_close_ int dir = -1;
char fdname[DECIMAL_STR_MAX(int)];
char procfs_path[STRLEN("/proc/self/fd/") + DECIMAL_STR_MAX(int)];
int r;
dir = open("/proc/self/fd/", O_CLOEXEC | O_DIRECTORY | O_PATH);
if (dir < 0)
/* /proc is not available or not set up properly, we're most likely
* in some chroot environment. */
return errno == ENOENT ? -EOPNOTSUPP : -errno;
xsprintf(procfs_path, "/proc/self/fd/%i", fd);
r = readlink_malloc(procfs_path, ret);
if (r == -ENOENT) {
/* ENOENT can mean two things: that the fd does not exist or that /proc is not mounted. Let's make
* things debuggable and distuingish the two. */
xsprintf(fdname, "%i", fd);
if (access("/proc/self/fd/", F_OK) < 0)
/* /proc is not available or not set up properly, we're most likely in some chroot
* environment. */
return errno == ENOENT ? -EOPNOTSUPP : -errno;
r = readlinkat_malloc(dir, fdname, ret);
if (r == -ENOENT)
/* If the file doesn't exist the fd is invalid */
return -EBADF;
return -EBADF; /* The directory exists, hence it's the fd that doesn't. */
}
return r;
}
......
......@@ -1221,6 +1221,24 @@ int mkostemp_safe(char *pattern) {
return fd;
}
int fmkostemp_safe(char *pattern, const char *mode, FILE **ret_f) {
int fd;
FILE *f;
fd = mkostemp_safe(pattern);
if (fd < 0)
return fd;
f = fdopen(fd, mode);
if (!f) {
safe_close(fd);
return -errno;
}
*ret_f = f;
return 0;
}
int tempfn_xxxxxx(const char *p, const char *extra, char **ret) {
const char *fn;
char *t;
......
......@@ -59,20 +59,12 @@ DIR *xopendirat(int dirfd, const char *name, int flags);
int search_and_fopen(const char *path, const char *mode, const char *root, const char **search, FILE **_f);
int search_and_fopen_nulstr(const char *path, const char *mode, const char *root, const char *search, FILE **_f);
#define FOREACH_LINE(line, f, on_error) \
for (;;) \
if (!fgets(line, sizeof(line), f)) { \
if (ferror(f)) { \
on_error; \
} \
break; \
} else
int fflush_and_check(FILE *f);
int fflush_sync_and_check(FILE *f);
int fopen_temporary(const char *path, FILE **_f, char **_temp_path);
int mkostemp_safe(char *pattern);
int fmkostemp_safe(char *pattern, const char *mode, FILE**_f);
int tempfn_xxxxxx(const char *p, const char *extra, char **ret);
int tempfn_random(const char *p, const char *extra, char **ret);
......
......@@ -132,7 +132,7 @@ int rename_noreplace(int olddirfd, const char *oldpath, int newdirfd, const char
}
int readlinkat_malloc(int fd, const char *p, char **ret) {
size_t l = 100;
size_t l = FILENAME_MAX+1;
int r;
assert(p);
......@@ -1173,7 +1173,7 @@ int unlinkat_deallocate(int fd, const char *name, int flags) {
return 0;
if (fstat(truncate_fd, &st) < 0) {
log_debug_errno(errno, "Failed to stat file '%s' for deallocation, ignoring.", name);
log_debug_errno(errno, "Failed to stat file '%s' for deallocation, ignoring: %m", name);
return 0;
}
......@@ -1235,6 +1235,34 @@ int fsync_directory_of_file(int fd) {
return 0;
}
int fsync_path_at(int at_fd, const char *path) {
_cleanup_close_ int opened_fd = -1;
int fd;
if (isempty(path)) {
if (at_fd == AT_FDCWD) {
opened_fd = open(".", O_RDONLY|O_DIRECTORY|O_CLOEXEC);
if (opened_fd < 0)
return -errno;
fd = opened_fd;
} else
fd = at_fd;
} else {
opened_fd = openat(at_fd, path, O_RDONLY|O_CLOEXEC);
if (opened_fd < 0)
return -errno;
fd = opened_fd;
}
if (fsync(fd) < 0)
return -errno;
return 0;
}
int open_parent(const char *path, int flags, mode_t mode) {
_cleanup_free_ char *parent = NULL;
int fd;
......
......@@ -105,5 +105,6 @@ void unlink_tempfilep(char (*p)[]);
int unlinkat_deallocate(int fd, const char *name, int flags);
int fsync_directory_of_file(int fd);
int fsync_path_at(int at_fd, const char *path);
int open_parent(const char *path, int flags, mode_t mode);
......@@ -6,7 +6,6 @@
#include <string.h>
#include "alloc-util.h"
#include "env-util.h"
#include "fileio.h"
#include "hashmap.h"
#include "macro.h"
......@@ -767,24 +766,12 @@ static void reset_direct_storage(HashmapBase *h) {
memset(p, DIB_RAW_INIT, sizeof(dib_raw_t) * hi->n_direct_buckets);
}
static bool use_pool(void) {
static int b = -1;
if (!is_main_thread())
return false;
if (b < 0)
b = getenv_bool("SYSTEMD_MEMPOOL") != 0;
return b;
}
static struct HashmapBase *hashmap_base_new(const struct hash_ops *hash_ops, enum HashmapType type HASHMAP_DEBUG_PARAMS) {
HashmapBase *h;
const struct hashmap_type_info *hi = &hashmap_type_info[type];
bool up;
up = use_pool();
up = mempool_enabled();
h = up ? mempool_alloc0_tile(hi->mempool) : malloc0(hi->head_size);
if (!h)
......@@ -1556,18 +1543,9 @@ static unsigned find_first_entry(HashmapBase *h) {
return hashmap_iterate_entry(h, &i);
}
void *internal_hashmap_first(HashmapBase *h) {
unsigned idx;
idx = find_first_entry(h);
if (idx == IDX_NIL)
return NULL;
return entry_value(h, bucket_at(h, idx));
}
void *internal_hashmap_first_key(HashmapBase *h) {
void *internal_hashmap_first_key_and_value(HashmapBase *h, bool remove, void **ret_key) {
struct hashmap_base_entry *e;
void *key, *data;
unsigned idx;
idx = find_first_entry(h);
......@@ -1575,39 +1553,16 @@ void *internal_hashmap_first_key(HashmapBase *h) {
return NULL;
e = bucket_at(h, idx);
return (void*) e->key;
}
void *internal_hashmap_steal_first(HashmapBase *h) {
struct hashmap_base_entry *e;
void *data;
unsigned idx;
idx = find_first_entry(h);
if (idx == IDX_NIL)
return NULL;
e = bucket_at(h, idx);
key = (void*) e->key;
data = entry_value(h, e);
remove_entry(h, idx);
return data;
}
void *internal_hashmap_steal_first_key(HashmapBase *h) {
struct hashmap_base_entry *e;
void *key;
unsigned idx;
idx = find_first_entry(h);
if (idx == IDX_NIL)
return NULL;
if (remove)
remove_entry(h, idx);
e = bucket_at(h, idx);
key = (void*) e->key;
remove_entry(h, idx);
if (ret_key)
*ret_key = key;
return key;
return data;
}
unsigned internal_hashmap_size(HashmapBase *h) {
......
......@@ -290,36 +290,51 @@ static inline void ordered_hashmap_clear_free_free(OrderedHashmap *h) {
* the first entry is O(1).
*/
void *internal_hashmap_steal_first(HashmapBase *h);
void *internal_hashmap_first_key_and_value(HashmapBase *h, bool remove, void **ret_key);
static inline void *hashmap_steal_first_key_and_value(Hashmap *h, void **ret) {
return internal_hashmap_first_key_and_value(HASHMAP_BASE(h), true, ret);
}
static inline void *ordered_hashmap_steal_first_key_and_value(OrderedHashmap *h, void **ret) {
return internal_hashmap_first_key_and_value(HASHMAP_BASE(h), true, ret);
}
static inline void *hashmap_first_key_and_value(Hashmap *h, void **ret) {
return internal_hashmap_first_key_and_value(HASHMAP_BASE(h), false, ret);
}
static inline void *ordered_hashmap_first_key_and_value(OrderedHashmap *h, void **ret) {
return internal_hashmap_first_key_and_value(HASHMAP_BASE(h), false, ret);
}
static inline void *hashmap_steal_first(Hashmap *h) {
return internal_hashmap_steal_first(HASHMAP_BASE(h));
return internal_hashmap_first_key_and_value(HASHMAP_BASE(h), true, NULL);
}
static inline void *ordered_hashmap_steal_first(OrderedHashmap *h) {
return internal_hashmap_steal_first(HASHMAP_BASE(h));
return internal_hashmap_first_key_and_value(HASHMAP_BASE(h), true, NULL);
}
static inline void *hashmap_first(Hashmap *h) {
return internal_hashmap_first_key_and_value(HASHMAP_BASE(h), false, NULL);
}
static inline void *ordered_hashmap_first(OrderedHashmap *h) {
return internal_hashmap_first_key_and_value(HASHMAP_BASE(h), false, NULL);
}
void *internal_hashmap_steal_first_key(HashmapBase *h);
static inline void *internal_hashmap_first_key(HashmapBase *h, bool remove) {
void *key = NULL;
(void) internal_hashmap_first_key_and_value(HASHMAP_BASE(h), remove, &key);
return key;
}
static inline void *hashmap_steal_first_key(Hashmap *h) {
return internal_hashmap_steal_first_key(HASHMAP_BASE(h));
return internal_hashmap_first_key(HASHMAP_BASE(h), true);
}
static inline void *ordered_hashmap_steal_first_key(OrderedHashmap *h) {
return internal_hashmap_steal_first_key(HASHMAP_BASE(h));
return internal_hashmap_first_key(HASHMAP_BASE(h), true);
}
void *internal_hashmap_first_key(HashmapBase *h) _pure_;
static inline void *hashmap_first_key(Hashmap *h) {
return internal_hashmap_first_key(HASHMAP_BASE(h));
return internal_hashmap_first_key(HASHMAP_BASE(h), false);
}
static inline void *ordered_hashmap_first_key(OrderedHashmap *h) {
return internal_hashmap_first_key(HASHMAP_BASE(h));
}
void *internal_hashmap_first(HashmapBase *h) _pure_;
static inline void *hashmap_first(Hashmap *h) {
return internal_hashmap_first(HASHMAP_BASE(h));
}
static inline void *ordered_hashmap_first(OrderedHashmap *h) {
return internal_hashmap_first(HASHMAP_BASE(h));
return internal_hashmap_first_key(HASHMAP_BASE(h), false);
}
#define hashmap_clear_with_destructor(_s, _f) \
......
......@@ -38,9 +38,9 @@
/* Append an item to the list */
#define LIST_APPEND(name,head,item) \
do { \
typeof(*(head)) *_tail; \
LIST_FIND_TAIL(name,head,_tail); \
LIST_INSERT_AFTER(name,head,_tail,item); \
typeof(*(head)) **_hhead = &(head), *_tail; \
LIST_FIND_TAIL(name, *_hhead, _tail); \
LIST_INSERT_AFTER(name, *_hhead, _tail, item); \
} while (false)
/* Remove an item from the list */
......
/* SPDX-License-Identifier: LGPL-2.1+ */
#pragma once
#include <assert.h>
#include <inttypes.h>
#include <stdbool.h>
#include <sys/param.h>
......@@ -56,10 +57,6 @@
#endif
/* Temporarily disable some warnings */
#define DISABLE_WARNING_DECLARATION_AFTER_STATEMENT \
_Pragma("GCC diagnostic push"); \
_Pragma("GCC diagnostic ignored \"-Wdeclaration-after-statement\"")
#define DISABLE_WARNING_FORMAT_NONLITERAL \
_Pragma("GCC diagnostic push"); \
_Pragma("GCC diagnostic ignored \"-Wformat-nonliteral\"")
......@@ -314,20 +311,13 @@ static inline int __coverity_check__(int condition) {
} while (false)
#if defined(static_assert)
/* static_assert() is sometimes defined in a way that trips up
* -Wdeclaration-after-statement, hence let's temporarily turn off
* this warning around it. */
#define assert_cc(expr) \
DISABLE_WARNING_DECLARATION_AFTER_STATEMENT; \
static_assert(expr, #expr); \
REENABLE_WARNING
static_assert(expr, #expr);
#else
#define assert_cc(expr) \
DISABLE_WARNING_DECLARATION_AFTER_STATEMENT; \
struct CONCATENATE(_assert_struct_, __COUNTER__) { \
char x[(expr) ? 0 : -1]; \
}; \