systemd: merge branch systemd into master
This commit is contained in:
@@ -88,6 +88,8 @@ G_STMT_START { \
|
||||
|
||||
#define ENABLE_GSHADOW FALSE
|
||||
|
||||
#define HAVE_SECCOMP 0
|
||||
|
||||
/*****************************************************************************/
|
||||
|
||||
/* systemd cannot be compiled with "-Wdeclaration-after-statement". In particular
|
||||
|
@@ -211,17 +211,21 @@ static int parse_env_file_internal(
|
||||
case DOUBLE_QUOTE_VALUE_ESCAPE:
|
||||
state = DOUBLE_QUOTE_VALUE;
|
||||
|
||||
if (c == '"') {
|
||||
if (strchr(SHELL_NEED_ESCAPE, c)) {
|
||||
/* If this is a char that needs escaping, just unescape it. */
|
||||
if (!GREEDY_REALLOC(value, value_alloc, n_value+2))
|
||||
return -ENOMEM;
|
||||
value[n_value++] = '"';
|
||||
} else if (!strchr(NEWLINE, c)) {
|
||||
value[n_value++] = c;
|
||||
} else if (c != '\n') {
|
||||
/* If other char than what needs escaping, keep the "\" in place, like the
|
||||
* real shell does. */
|
||||
if (!GREEDY_REALLOC(value, value_alloc, n_value+3))
|
||||
return -ENOMEM;
|
||||
value[n_value++] = '\\';
|
||||
value[n_value++] = c;
|
||||
}
|
||||
|
||||
/* Escaped newlines (aka "continuation lines") are eaten up entirely */
|
||||
break;
|
||||
|
||||
case COMMENT:
|
||||
|
@@ -690,7 +690,7 @@ char **replace_env_argv(char **argv, char **env) {
|
||||
if (e) {
|
||||
int r;
|
||||
|
||||
r = strv_split_extract(&m, e, WHITESPACE, EXTRACT_RELAX|EXTRACT_UNQUOTE);
|
||||
r = strv_split_full(&m, e, WHITESPACE, EXTRACT_RELAX|EXTRACT_UNQUOTE);
|
||||
if (r < 0) {
|
||||
ret[k] = NULL;
|
||||
strv_free(ret);
|
||||
@@ -744,7 +744,6 @@ int getenv_bool(const char *p) {
|
||||
return parse_boolean(e);
|
||||
}
|
||||
|
||||
#if 0 /* NM_IGNORED */
|
||||
int getenv_bool_secure(const char *p) {
|
||||
const char *e;
|
||||
|
||||
@@ -754,4 +753,3 @@ int getenv_bool_secure(const char *p) {
|
||||
|
||||
return parse_boolean(e);
|
||||
}
|
||||
#endif /* NM_IGNORED */
|
||||
|
@@ -77,7 +77,7 @@ int cescape_char(char c, char *buf) {
|
||||
return buf - buf_old;
|
||||
}
|
||||
|
||||
char *cescape_length(const char *s, size_t n) {
|
||||
char* cescape_length(const char *s, size_t n) {
|
||||
const char *f;
|
||||
char *r, *t;
|
||||
|
||||
@@ -98,7 +98,7 @@ char *cescape_length(const char *s, size_t n) {
|
||||
return r;
|
||||
}
|
||||
|
||||
char *cescape(const char *s) {
|
||||
char* cescape(const char *s) {
|
||||
assert(s);
|
||||
|
||||
return cescape_length(s, strlen(s));
|
||||
@@ -363,7 +363,7 @@ int cunescape_length_with_prefix(const char *s, size_t length, const char *prefi
|
||||
return t - r;
|
||||
}
|
||||
|
||||
char *xescape_full(const char *s, const char *bad, size_t console_width, bool eight_bits) {
|
||||
char* xescape_full(const char *s, const char *bad, size_t console_width, bool eight_bits) {
|
||||
char *ans, *t, *prev, *prev2;
|
||||
const char *f;
|
||||
|
||||
@@ -430,7 +430,7 @@ char *xescape_full(const char *s, const char *bad, size_t console_width, bool ei
|
||||
return ans;
|
||||
}
|
||||
|
||||
char *escape_non_printable_full(const char *str, size_t console_width, bool eight_bit) {
|
||||
char* escape_non_printable_full(const char *str, size_t console_width, bool eight_bit) {
|
||||
if (eight_bit)
|
||||
return xescape_full(str, "", console_width, true);
|
||||
else
|
||||
@@ -438,7 +438,7 @@ char *escape_non_printable_full(const char *str, size_t console_width, bool eigh
|
||||
}
|
||||
#endif /* NM_IGNORED */
|
||||
|
||||
char *octescape(const char *s, size_t len) {
|
||||
char* octescape(const char *s, size_t len) {
|
||||
char *r, *t;
|
||||
const char *f;
|
||||
|
||||
@@ -466,7 +466,7 @@ char *octescape(const char *s, size_t len) {
|
||||
|
||||
}
|
||||
|
||||
static char *strcpy_backslash_escaped(char *t, const char *s, const char *bad, bool escape_tab_nl) {
|
||||
static char* strcpy_backslash_escaped(char *t, const char *s, const char *bad, bool escape_tab_nl) {
|
||||
assert(bad);
|
||||
|
||||
for (; *s; s++) {
|
||||
@@ -485,7 +485,7 @@ static char *strcpy_backslash_escaped(char *t, const char *s, const char *bad, b
|
||||
return t;
|
||||
}
|
||||
|
||||
char *shell_escape(const char *s, const char *bad) {
|
||||
char* shell_escape(const char *s, const char *bad) {
|
||||
char *r, *t;
|
||||
|
||||
r = new(char, strlen(s)*2+1);
|
||||
|
@@ -43,8 +43,8 @@ typedef enum EscapeStyle {
|
||||
* syntax (a string enclosed in $'') instead of plain quotes. */
|
||||
} EscapeStyle;
|
||||
|
||||
char *cescape(const char *s);
|
||||
char *cescape_length(const char *s, size_t n);
|
||||
char* cescape(const char *s);
|
||||
char* cescape_length(const char *s, size_t n);
|
||||
int cescape_char(char c, char *buf);
|
||||
|
||||
int cunescape_length_with_prefix(const char *s, size_t length, const char *prefix, UnescapeFlags flags, char **ret);
|
||||
@@ -56,12 +56,12 @@ static inline int cunescape(const char *s, UnescapeFlags flags, char **ret) {
|
||||
}
|
||||
int cunescape_one(const char *p, size_t length, char32_t *ret, bool *eight_bit, bool accept_nul);
|
||||
|
||||
char *xescape_full(const char *s, const char *bad, size_t console_width, bool eight_bits);
|
||||
static inline char *xescape(const char *s, const char *bad) {
|
||||
char* xescape_full(const char *s, const char *bad, size_t console_width, bool eight_bits);
|
||||
static inline char* xescape(const char *s, const char *bad) {
|
||||
return xescape_full(s, bad, SIZE_MAX, false);
|
||||
}
|
||||
char *octescape(const char *s, size_t len);
|
||||
char *escape_non_printable_full(const char *str, size_t console_width, bool eight_bit);
|
||||
char* octescape(const char *s, size_t len);
|
||||
char* escape_non_printable_full(const char *str, size_t console_width, bool eight_bit);
|
||||
|
||||
char *shell_escape(const char *s, const char *bad);
|
||||
char* shell_escape(const char *s, const char *bad);
|
||||
char* shell_maybe_quote(const char *s, EscapeStyle style);
|
||||
|
@@ -16,6 +16,7 @@
|
||||
#include "log.h"
|
||||
#include "macro.h"
|
||||
#include "string-util.h"
|
||||
#include "strv.h"
|
||||
#include "utf8.h"
|
||||
|
||||
int extract_first_word(const char **p, char **ret, const char *separators, ExtractFlags flags) {
|
||||
|
@@ -379,6 +379,7 @@ bool fdname_is_valid(const char *s) {
|
||||
return p - s < 256;
|
||||
}
|
||||
|
||||
#if 0 /* NM_IGNORED */
|
||||
int fd_get_path(int fd, char **ret) {
|
||||
char procfs_path[STRLEN("/proc/self/fd/") + DECIMAL_STR_MAX(int)];
|
||||
int r;
|
||||
@@ -389,18 +390,15 @@ int fd_get_path(int fd, char **ret) {
|
||||
/* ENOENT can mean two things: that the fd does not exist or that /proc is not mounted. Let's make
|
||||
* things debuggable and distinguish the two. */
|
||||
|
||||
if (access("/proc/self/fd/", F_OK) < 0)
|
||||
/* /proc is not available or not set up properly, we're most likely in some chroot
|
||||
if (proc_mounted() == 0)
|
||||
return -ENOSYS; /* /proc is not available or not set up properly, we're most likely in some chroot
|
||||
* environment. */
|
||||
return errno == ENOENT ? -EOPNOTSUPP : -errno;
|
||||
|
||||
return -EBADF; /* The directory exists, hence it's the fd that doesn't. */
|
||||
}
|
||||
|
||||
return r;
|
||||
}
|
||||
|
||||
#if 0 /* NM_IGNORED */
|
||||
int move_fd(int from, int to, int cloexec) {
|
||||
int r;
|
||||
|
||||
@@ -736,8 +734,7 @@ int fd_duplicate_data_fd(int fd) {
|
||||
if (f != 0)
|
||||
return -errno;
|
||||
|
||||
safe_close(copy_fd);
|
||||
copy_fd = TAKE_FD(tmp_fd);
|
||||
CLOSE_AND_REPLACE(copy_fd, tmp_fd);
|
||||
|
||||
remains = mfree(remains);
|
||||
remains_size = 0;
|
||||
@@ -872,8 +869,7 @@ int rearrange_stdio(int original_input_fd, int original_output_fd, int original_
|
||||
goto finish;
|
||||
}
|
||||
|
||||
safe_close(null_fd);
|
||||
null_fd = copy;
|
||||
CLOSE_AND_REPLACE(null_fd, copy);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -983,7 +979,7 @@ int read_nr_open(void) {
|
||||
return v;
|
||||
}
|
||||
|
||||
/* If we fail, fallback to the hard-coded kernel limit of 1024 * 1024. */
|
||||
/* If we fail, fall back to the hard-coded kernel limit of 1024 * 1024. */
|
||||
return 1024 * 1024;
|
||||
}
|
||||
#endif /* NM_IGNORED */
|
||||
|
@@ -93,6 +93,16 @@ static inline int make_null_stdio(void) {
|
||||
_fd_; \
|
||||
})
|
||||
|
||||
/* Like free_and_replace(), but for file descriptors */
|
||||
#define CLOSE_AND_REPLACE(a, b) \
|
||||
({ \
|
||||
int *_fdp_ = &(a); \
|
||||
safe_close(*_fdp_); \
|
||||
*_fdp_ = TAKE_FD(b); \
|
||||
0; \
|
||||
})
|
||||
|
||||
|
||||
int fd_reopen(int fd, int flags);
|
||||
|
||||
int read_nr_open(void);
|
||||
|
@@ -123,7 +123,7 @@ int rename_noreplace(int olddirfd, const char *oldpath, int newdirfd, const char
|
||||
if (!IN_SET(errno, EINVAL, ENOSYS, ENOTTY, EPERM)) /* FAT returns EPERM on link()… */
|
||||
return -errno;
|
||||
|
||||
/* OK, neither RENAME_NOREPLACE nor linkat()+unlinkat() worked. Let's then fallback to the racy TOCTOU
|
||||
/* OK, neither RENAME_NOREPLACE nor linkat()+unlinkat() worked. Let's then fall back to the racy TOCTOU
|
||||
* vulnerable accessat(F_OK) check followed by classic, replacing renameat(), we have nothing better. */
|
||||
|
||||
if (faccessat(newdirfd, newpath, F_OK, AT_SYMLINK_NOFOLLOW) >= 0)
|
||||
@@ -234,6 +234,7 @@ int chmod_and_chown(const char *path, mode_t mode, uid_t uid, gid_t gid) {
|
||||
int fchmod_and_chown(int fd, mode_t mode, uid_t uid, gid_t gid) {
|
||||
bool do_chown, do_chmod;
|
||||
struct stat st;
|
||||
int r;
|
||||
|
||||
/* Change ownership and access mode of the specified fd. Tries to do so safely, ensuring that at no
|
||||
* point in time the access mode is above the old access mode under the old ownership or the new
|
||||
@@ -264,65 +265,23 @@ int fchmod_and_chown(int fd, mode_t mode, uid_t uid, gid_t gid) {
|
||||
if (do_chown && do_chmod) {
|
||||
mode_t minimal = st.st_mode & mode; /* the subset of the old and the new mask */
|
||||
|
||||
if (((minimal ^ st.st_mode) & 07777) != 0)
|
||||
if (fchmod_opath(fd, minimal & 07777) < 0)
|
||||
return -errno;
|
||||
if (((minimal ^ st.st_mode) & 07777) != 0) {
|
||||
r = fchmod_opath(fd, minimal & 07777);
|
||||
if (r < 0)
|
||||
return r;
|
||||
}
|
||||
}
|
||||
|
||||
if (do_chown)
|
||||
if (fchownat(fd, "", uid, gid, AT_EMPTY_PATH) < 0)
|
||||
return -errno;
|
||||
|
||||
if (do_chmod)
|
||||
if (fchmod_opath(fd, mode & 07777) < 0)
|
||||
return -errno;
|
||||
|
||||
return do_chown || do_chmod;
|
||||
}
|
||||
|
||||
int chmod_and_chown_unsafe(const char *path, mode_t mode, uid_t uid, gid_t gid) {
|
||||
bool do_chown, do_chmod;
|
||||
struct stat st;
|
||||
|
||||
assert(path);
|
||||
|
||||
/* Change ownership and access mode of the specified path, see description of fchmod_and_chown().
|
||||
* Should only be used on trusted paths. */
|
||||
|
||||
if (lstat(path, &st) < 0)
|
||||
return -errno;
|
||||
|
||||
do_chown =
|
||||
(uid != UID_INVALID && st.st_uid != uid) ||
|
||||
(gid != GID_INVALID && st.st_gid != gid);
|
||||
|
||||
do_chmod =
|
||||
!S_ISLNK(st.st_mode) && /* chmod is not defined on symlinks */
|
||||
((mode != MODE_INVALID && ((st.st_mode ^ mode) & 07777) != 0) ||
|
||||
do_chown); /* If we change ownership, make sure we reset the mode afterwards, since chown()
|
||||
* modifies the access mode too */
|
||||
|
||||
if (mode == MODE_INVALID)
|
||||
mode = st.st_mode; /* If we only shall do a chown(), save original mode, since chown() might break it. */
|
||||
else if ((mode & S_IFMT) != 0 && ((mode ^ st.st_mode) & S_IFMT) != 0)
|
||||
return -EINVAL; /* insist on the right file type if it was specified */
|
||||
|
||||
if (do_chown && do_chmod) {
|
||||
mode_t minimal = st.st_mode & mode; /* the subset of the old and the new mask */
|
||||
|
||||
if (((minimal ^ st.st_mode) & 07777) != 0)
|
||||
if (chmod(path, minimal & 07777) < 0)
|
||||
return -errno;
|
||||
if (do_chmod) {
|
||||
r = fchmod_opath(fd, mode & 07777);
|
||||
if (r < 0)
|
||||
return r;
|
||||
}
|
||||
|
||||
if (do_chown)
|
||||
if (lchown(path, uid, gid) < 0)
|
||||
return -errno;
|
||||
|
||||
if (do_chmod)
|
||||
if (chmod(path, mode & 07777) < 0)
|
||||
return -errno;
|
||||
|
||||
return do_chown || do_chmod;
|
||||
}
|
||||
|
||||
@@ -771,7 +730,7 @@ static int log_unsafe_transition(int a, int b, const char *path, unsigned flags)
|
||||
|
||||
return log_warning_errno(SYNTHETIC_ERRNO(ENOLINK),
|
||||
"Detected unsafe path transition %s %s %s during canonicalization of %s.",
|
||||
n1, special_glyph(SPECIAL_GLYPH_ARROW), n2, path);
|
||||
strna(n1), special_glyph(SPECIAL_GLYPH_ARROW), strna(n2), path);
|
||||
}
|
||||
|
||||
static int log_autofs_mount_point(int fd, const char *path, unsigned flags) {
|
||||
@@ -784,7 +743,7 @@ static int log_autofs_mount_point(int fd, const char *path, unsigned flags) {
|
||||
|
||||
return log_warning_errno(SYNTHETIC_ERRNO(EREMOTE),
|
||||
"Detected autofs mount point %s during canonicalization of %s.",
|
||||
n1, path);
|
||||
strna(n1), path);
|
||||
}
|
||||
|
||||
int chase_symlinks(const char *path, const char *original_root, unsigned flags, char **ret_path, int *ret_fd) {
|
||||
@@ -1304,16 +1263,25 @@ int chase_symlinks_and_stat(
|
||||
|
||||
int access_fd(int fd, int mode) {
|
||||
char p[STRLEN("/proc/self/fd/") + DECIMAL_STR_MAX(fd) + 1];
|
||||
int r;
|
||||
|
||||
/* Like access() but operates on an already open fd */
|
||||
|
||||
xsprintf(p, "/proc/self/fd/%i", fd);
|
||||
r = access(p, mode);
|
||||
if (r < 0)
|
||||
if (access(p, mode) < 0) {
|
||||
if (errno != ENOENT)
|
||||
return -errno;
|
||||
|
||||
return r;
|
||||
/* ENOENT can mean two things: that the fd does not exist or that /proc is not mounted. Let's
|
||||
* make things debuggable and distinguish the two. */
|
||||
|
||||
if (proc_mounted() == 0)
|
||||
return -ENOSYS; /* /proc is not available or not set up properly, we're most likely in some chroot
|
||||
* environment. */
|
||||
|
||||
return -EBADF; /* The directory exists, hence it's the fd that doesn't. */
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
void unlink_tempfilep(char (*p)[]) {
|
||||
@@ -1434,6 +1402,7 @@ int unlinkat_deallocate(int fd, const char *name, UnlinkDeallocateFlags flags) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
#if 0 /* NM_IGNORED */
|
||||
int fsync_directory_of_file(int fd) {
|
||||
_cleanup_free_ char *path = NULL;
|
||||
_cleanup_close_ int dfd = -1;
|
||||
@@ -1447,9 +1416,9 @@ int fsync_directory_of_file(int fd) {
|
||||
if (r < 0) {
|
||||
log_debug_errno(r, "Failed to query /proc/self/fd/%d%s: %m",
|
||||
fd,
|
||||
r == -EOPNOTSUPP ? ", ignoring" : "");
|
||||
r == -ENOSYS ? ", ignoring" : "");
|
||||
|
||||
if (r == -EOPNOTSUPP)
|
||||
if (r == -ENOSYS)
|
||||
/* If /proc is not available, we're most likely running in some
|
||||
* chroot environment, and syncing the directory is not very
|
||||
* important in that case. Let's just silently do nothing. */
|
||||
@@ -1470,6 +1439,7 @@ int fsync_directory_of_file(int fd) {
|
||||
|
||||
return 0;
|
||||
}
|
||||
#endif /* NM_IGNORED */
|
||||
|
||||
int fsync_full(int fd) {
|
||||
int r, q;
|
||||
|
@@ -34,7 +34,6 @@ int readlink_and_make_absolute(const char *p, char **r);
|
||||
|
||||
int chmod_and_chown(const char *path, mode_t mode, uid_t uid, gid_t gid);
|
||||
int fchmod_and_chown(int fd, mode_t mode, uid_t uid, gid_t gid);
|
||||
int chmod_and_chown_unsafe(const char *path, mode_t mode, uid_t uid, gid_t gid);
|
||||
|
||||
int fchmod_umask(int fd, mode_t mode);
|
||||
int fchmod_opath(int fd, mode_t m);
|
||||
|
@@ -3,6 +3,7 @@
|
||||
#include "nm-sd-adapt-shared.h"
|
||||
|
||||
#include <errno.h>
|
||||
#include <pthread.h>
|
||||
#include <stdint.h>
|
||||
#include <stdlib.h>
|
||||
|
||||
@@ -21,7 +22,6 @@
|
||||
#include "strv.h"
|
||||
|
||||
#if ENABLE_DEBUG_HASHMAP
|
||||
#include <pthread.h>
|
||||
#include "list.h"
|
||||
#endif
|
||||
|
||||
@@ -191,7 +191,6 @@ assert_cc(DIRECT_BUCKETS(struct set_entry) < (1 << 3));
|
||||
* a handful of directly stored entries in a hashmap. When a hashmap
|
||||
* outgrows direct storage, it gets its own key for indirect storage. */
|
||||
static uint8_t shared_hash_key[HASH_KEY_SIZE];
|
||||
static bool shared_hash_key_initialized;
|
||||
|
||||
/* Fields that all hashmap/set types must have */
|
||||
struct HashmapBase {
|
||||
@@ -325,12 +324,12 @@ static void n_entries_dec(HashmapBase *h) {
|
||||
h->n_direct_entries--;
|
||||
}
|
||||
|
||||
static void *storage_ptr(HashmapBase *h) {
|
||||
static void* storage_ptr(HashmapBase *h) {
|
||||
return h->has_indirect ? h->indirect.storage
|
||||
: h->direct.storage;
|
||||
}
|
||||
|
||||
static uint8_t *hash_key(HashmapBase *h) {
|
||||
static uint8_t* hash_key(HashmapBase *h) {
|
||||
return h->has_indirect ? h->indirect.hash_key
|
||||
: shared_hash_key;
|
||||
}
|
||||
@@ -373,16 +372,16 @@ static void get_hash_key(uint8_t hash_key[HASH_KEY_SIZE], bool reuse_is_ok) {
|
||||
memcpy(hash_key, current, sizeof(current));
|
||||
}
|
||||
|
||||
static struct hashmap_base_entry *bucket_at(HashmapBase *h, unsigned idx) {
|
||||
static struct hashmap_base_entry* bucket_at(HashmapBase *h, unsigned idx) {
|
||||
return (struct hashmap_base_entry*)
|
||||
((uint8_t*) storage_ptr(h) + idx * hashmap_type_info[h->type].entry_size);
|
||||
}
|
||||
|
||||
static struct plain_hashmap_entry *plain_bucket_at(Hashmap *h, unsigned idx) {
|
||||
static struct plain_hashmap_entry* plain_bucket_at(Hashmap *h, unsigned idx) {
|
||||
return (struct plain_hashmap_entry*) bucket_at(HASHMAP_BASE(h), idx);
|
||||
}
|
||||
|
||||
static struct ordered_hashmap_entry *ordered_bucket_at(OrderedHashmap *h, unsigned idx) {
|
||||
static struct ordered_hashmap_entry* ordered_bucket_at(OrderedHashmap *h, unsigned idx) {
|
||||
return (struct ordered_hashmap_entry*) bucket_at(HASHMAP_BASE(h), idx);
|
||||
}
|
||||
|
||||
@@ -390,13 +389,13 @@ static struct set_entry *set_bucket_at(Set *h, unsigned idx) {
|
||||
return (struct set_entry*) bucket_at(HASHMAP_BASE(h), idx);
|
||||
}
|
||||
|
||||
static struct ordered_hashmap_entry *bucket_at_swap(struct swap_entries *swap, unsigned idx) {
|
||||
static struct ordered_hashmap_entry* bucket_at_swap(struct swap_entries *swap, unsigned idx) {
|
||||
return &swap->e[idx - _IDX_SWAP_BEGIN];
|
||||
}
|
||||
|
||||
/* Returns a pointer to the bucket at index idx.
|
||||
* Understands real indexes and swap indexes, hence "_virtual". */
|
||||
static struct hashmap_base_entry *bucket_at_virtual(HashmapBase *h, struct swap_entries *swap,
|
||||
static struct hashmap_base_entry* bucket_at_virtual(HashmapBase *h, struct swap_entries *swap,
|
||||
unsigned idx) {
|
||||
if (idx < _IDX_SWAP_BEGIN)
|
||||
return bucket_at(h, idx);
|
||||
@@ -407,7 +406,7 @@ static struct hashmap_base_entry *bucket_at_virtual(HashmapBase *h, struct swap_
|
||||
assert_not_reached("Invalid index");
|
||||
}
|
||||
|
||||
static dib_raw_t *dib_raw_ptr(HashmapBase *h) {
|
||||
static dib_raw_t* dib_raw_ptr(HashmapBase *h) {
|
||||
return (dib_raw_t*)
|
||||
((uint8_t*) storage_ptr(h) + hashmap_type_info[h->type].entry_size * n_buckets(h));
|
||||
}
|
||||
@@ -505,7 +504,7 @@ static unsigned prev_idx(HashmapBase *h, unsigned idx) {
|
||||
return (n_buckets(h) + idx - 1U) % n_buckets(h);
|
||||
}
|
||||
|
||||
static void *entry_value(HashmapBase *h, struct hashmap_base_entry *e) {
|
||||
static void* entry_value(HashmapBase *h, struct hashmap_base_entry *e) {
|
||||
switch (h->type) {
|
||||
|
||||
case HASHMAP_TYPE_PLAIN:
|
||||
@@ -732,16 +731,12 @@ bool _hashmap_iterate(HashmapBase *h, Iterator *i, void **value, const void **ke
|
||||
return true;
|
||||
}
|
||||
|
||||
bool set_iterate(const Set *s, Iterator *i, void **value) {
|
||||
return _hashmap_iterate(HASHMAP_BASE((Set*) s), i, value, NULL);
|
||||
}
|
||||
|
||||
#define HASHMAP_FOREACH_IDX(idx, h, i) \
|
||||
for ((i) = ITERATOR_FIRST, (idx) = hashmap_iterate_entry((h), &(i)); \
|
||||
(idx != IDX_NIL); \
|
||||
(idx) = hashmap_iterate_entry((h), &(i)))
|
||||
|
||||
IteratedCache *_hashmap_iterated_cache_new(HashmapBase *h) {
|
||||
IteratedCache* _hashmap_iterated_cache_new(HashmapBase *h) {
|
||||
IteratedCache *cache;
|
||||
|
||||
assert(h);
|
||||
@@ -770,7 +765,11 @@ static void reset_direct_storage(HashmapBase *h) {
|
||||
memset(p, DIB_RAW_INIT, sizeof(dib_raw_t) * hi->n_direct_buckets);
|
||||
}
|
||||
|
||||
static struct HashmapBase *hashmap_base_new(const struct hash_ops *hash_ops, enum HashmapType type HASHMAP_DEBUG_PARAMS) {
|
||||
static void shared_hash_key_initialize(void) {
|
||||
random_bytes(shared_hash_key, sizeof(shared_hash_key));
|
||||
}
|
||||
|
||||
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;
|
||||
@@ -792,10 +791,8 @@ static struct HashmapBase *hashmap_base_new(const struct hash_ops *hash_ops, enu
|
||||
|
||||
reset_direct_storage(h);
|
||||
|
||||
if (!shared_hash_key_initialized) {
|
||||
random_bytes(shared_hash_key, sizeof(shared_hash_key));
|
||||
shared_hash_key_initialized= true;
|
||||
}
|
||||
static pthread_once_t once = PTHREAD_ONCE_INIT;
|
||||
assert_se(pthread_once(&once, shared_hash_key_initialize) == 0);
|
||||
|
||||
#if ENABLE_DEBUG_HASHMAP
|
||||
h->debug.func = func;
|
||||
@@ -850,6 +847,16 @@ int _set_ensure_allocated(Set **s, const struct hash_ops *hash_ops HASHMAP_DEBU
|
||||
return hashmap_base_ensure_allocated((HashmapBase**)s, hash_ops, HASHMAP_TYPE_SET HASHMAP_DEBUG_PASS_ARGS);
|
||||
}
|
||||
|
||||
int _ordered_hashmap_ensure_put(OrderedHashmap **h, const struct hash_ops *hash_ops, const void *key, void *value HASHMAP_DEBUG_PARAMS) {
|
||||
int r;
|
||||
|
||||
r = _ordered_hashmap_ensure_allocated(h, hash_ops HASHMAP_DEBUG_PASS_ARGS);
|
||||
if (r < 0)
|
||||
return r;
|
||||
|
||||
return ordered_hashmap_put(*h, key, value);
|
||||
}
|
||||
|
||||
static void hashmap_free_no_clear(HashmapBase *h) {
|
||||
assert(!h->has_indirect);
|
||||
assert(h->n_direct_entries == 0);
|
||||
@@ -868,7 +875,7 @@ static void hashmap_free_no_clear(HashmapBase *h) {
|
||||
free(h);
|
||||
}
|
||||
|
||||
HashmapBase *_hashmap_free(HashmapBase *h, free_func_t default_free_key, free_func_t default_free_value) {
|
||||
HashmapBase* _hashmap_free(HashmapBase *h, free_func_t default_free_key, free_func_t default_free_value) {
|
||||
if (h) {
|
||||
_hashmap_clear(h, default_free_key, default_free_value);
|
||||
hashmap_free_no_clear(h);
|
||||
@@ -1325,7 +1332,7 @@ int hashmap_update(Hashmap *h, const void *key, void *value) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
void *_hashmap_get(HashmapBase *h, const void *key) {
|
||||
void* _hashmap_get(HashmapBase *h, const void *key) {
|
||||
struct hashmap_base_entry *e;
|
||||
unsigned hash, idx;
|
||||
|
||||
@@ -1341,7 +1348,7 @@ void *_hashmap_get(HashmapBase *h, const void *key) {
|
||||
return entry_value(h, e);
|
||||
}
|
||||
|
||||
void *hashmap_get2(Hashmap *h, const void *key, void **key2) {
|
||||
void* hashmap_get2(Hashmap *h, const void *key, void **key2) {
|
||||
struct plain_hashmap_entry *e;
|
||||
unsigned hash, idx;
|
||||
|
||||
@@ -1370,7 +1377,7 @@ bool _hashmap_contains(HashmapBase *h, const void *key) {
|
||||
return bucket_scan(h, hash, key) != IDX_NIL;
|
||||
}
|
||||
|
||||
void *_hashmap_remove(HashmapBase *h, const void *key) {
|
||||
void* _hashmap_remove(HashmapBase *h, const void *key) {
|
||||
struct hashmap_base_entry *e;
|
||||
unsigned hash, idx;
|
||||
void *data;
|
||||
@@ -1390,7 +1397,7 @@ void *_hashmap_remove(HashmapBase *h, const void *key) {
|
||||
return data;
|
||||
}
|
||||
|
||||
void *hashmap_remove2(Hashmap *h, const void *key, void **rkey) {
|
||||
void* hashmap_remove2(Hashmap *h, const void *key, void **rkey) {
|
||||
struct plain_hashmap_entry *e;
|
||||
unsigned hash, idx;
|
||||
void *data;
|
||||
@@ -1508,7 +1515,7 @@ int hashmap_remove_and_replace(Hashmap *h, const void *old_key, const void *new_
|
||||
return 0;
|
||||
}
|
||||
|
||||
void *_hashmap_remove_value(HashmapBase *h, const void *key, void *value) {
|
||||
void* _hashmap_remove_value(HashmapBase *h, const void *key, void *value) {
|
||||
struct hashmap_base_entry *e;
|
||||
unsigned hash, idx;
|
||||
|
||||
@@ -1538,7 +1545,7 @@ static unsigned find_first_entry(HashmapBase *h) {
|
||||
return hashmap_iterate_entry(h, &i);
|
||||
}
|
||||
|
||||
void *_hashmap_first_key_and_value(HashmapBase *h, bool remove, void **ret_key) {
|
||||
void* _hashmap_first_key_and_value(HashmapBase *h, bool remove, void **ret_key) {
|
||||
struct hashmap_base_entry *e;
|
||||
void *key, *data;
|
||||
unsigned idx;
|
||||
@@ -1713,7 +1720,7 @@ int _hashmap_move_one(HashmapBase *h, HashmapBase *other, const void *key) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
HashmapBase *_hashmap_copy(HashmapBase *h HASHMAP_DEBUG_PARAMS) {
|
||||
HashmapBase* _hashmap_copy(HashmapBase *h HASHMAP_DEBUG_PARAMS) {
|
||||
HashmapBase *copy;
|
||||
int r;
|
||||
|
||||
@@ -1741,7 +1748,7 @@ HashmapBase *_hashmap_copy(HashmapBase *h HASHMAP_DEBUG_PARAMS) {
|
||||
return copy;
|
||||
}
|
||||
|
||||
char **_hashmap_get_strv(HashmapBase *h) {
|
||||
char** _hashmap_get_strv(HashmapBase *h) {
|
||||
char **sv;
|
||||
Iterator i;
|
||||
unsigned idx, n;
|
||||
@@ -1758,7 +1765,7 @@ char **_hashmap_get_strv(HashmapBase *h) {
|
||||
return sv;
|
||||
}
|
||||
|
||||
void *ordered_hashmap_next(OrderedHashmap *h, const void *key) {
|
||||
void* ordered_hashmap_next(OrderedHashmap *h, const void *key) {
|
||||
struct ordered_hashmap_entry *e;
|
||||
unsigned hash, idx;
|
||||
|
||||
@@ -1965,7 +1972,7 @@ int iterated_cache_get(IteratedCache *cache, const void ***res_keys, const void
|
||||
return 0;
|
||||
}
|
||||
|
||||
IteratedCache *iterated_cache_free(IteratedCache *cache) {
|
||||
IteratedCache* iterated_cache_free(IteratedCache *cache) {
|
||||
if (cache) {
|
||||
free(cache->keys.ptr);
|
||||
free(cache->values.ptr);
|
||||
|
@@ -83,8 +83,8 @@ typedef struct {
|
||||
# define HASHMAP_DEBUG_PASS_ARGS
|
||||
#endif
|
||||
|
||||
Hashmap *_hashmap_new(const struct hash_ops *hash_ops HASHMAP_DEBUG_PARAMS);
|
||||
OrderedHashmap *_ordered_hashmap_new(const struct hash_ops *hash_ops HASHMAP_DEBUG_PARAMS);
|
||||
Hashmap* _hashmap_new(const struct hash_ops *hash_ops HASHMAP_DEBUG_PARAMS);
|
||||
OrderedHashmap* _ordered_hashmap_new(const struct hash_ops *hash_ops HASHMAP_DEBUG_PARAMS);
|
||||
#define hashmap_new(ops) _hashmap_new(ops HASHMAP_DEBUG_SRC_ARGS)
|
||||
#define ordered_hashmap_new(ops) _ordered_hashmap_new(ops HASHMAP_DEBUG_SRC_ARGS)
|
||||
|
||||
@@ -96,39 +96,39 @@ OrderedHashmap *_ordered_hashmap_new(const struct hash_ops *hash_ops HASHMAP_DE
|
||||
0; \
|
||||
})
|
||||
|
||||
HashmapBase *_hashmap_free(HashmapBase *h, free_func_t default_free_key, free_func_t default_free_value);
|
||||
static inline Hashmap *hashmap_free(Hashmap *h) {
|
||||
HashmapBase* _hashmap_free(HashmapBase *h, free_func_t default_free_key, free_func_t default_free_value);
|
||||
static inline Hashmap* hashmap_free(Hashmap *h) {
|
||||
return (void*) _hashmap_free(HASHMAP_BASE(h), NULL, NULL);
|
||||
}
|
||||
static inline OrderedHashmap *ordered_hashmap_free(OrderedHashmap *h) {
|
||||
static inline OrderedHashmap* ordered_hashmap_free(OrderedHashmap *h) {
|
||||
return (void*) _hashmap_free(HASHMAP_BASE(h), NULL, NULL);
|
||||
}
|
||||
|
||||
static inline Hashmap *hashmap_free_free(Hashmap *h) {
|
||||
static inline Hashmap* hashmap_free_free(Hashmap *h) {
|
||||
return (void*) _hashmap_free(HASHMAP_BASE(h), NULL, free);
|
||||
}
|
||||
static inline OrderedHashmap *ordered_hashmap_free_free(OrderedHashmap *h) {
|
||||
static inline OrderedHashmap* ordered_hashmap_free_free(OrderedHashmap *h) {
|
||||
return (void*) _hashmap_free(HASHMAP_BASE(h), NULL, free);
|
||||
}
|
||||
|
||||
static inline Hashmap *hashmap_free_free_key(Hashmap *h) {
|
||||
static inline Hashmap* hashmap_free_free_key(Hashmap *h) {
|
||||
return (void*) _hashmap_free(HASHMAP_BASE(h), free, NULL);
|
||||
}
|
||||
static inline OrderedHashmap *ordered_hashmap_free_free_key(OrderedHashmap *h) {
|
||||
static inline OrderedHashmap* ordered_hashmap_free_free_key(OrderedHashmap *h) {
|
||||
return (void*) _hashmap_free(HASHMAP_BASE(h), free, NULL);
|
||||
}
|
||||
|
||||
static inline Hashmap *hashmap_free_free_free(Hashmap *h) {
|
||||
static inline Hashmap* hashmap_free_free_free(Hashmap *h) {
|
||||
return (void*) _hashmap_free(HASHMAP_BASE(h), free, free);
|
||||
}
|
||||
static inline OrderedHashmap *ordered_hashmap_free_free_free(OrderedHashmap *h) {
|
||||
static inline OrderedHashmap* ordered_hashmap_free_free_free(OrderedHashmap *h) {
|
||||
return (void*) _hashmap_free(HASHMAP_BASE(h), free, free);
|
||||
}
|
||||
|
||||
IteratedCache *iterated_cache_free(IteratedCache *cache);
|
||||
IteratedCache* iterated_cache_free(IteratedCache *cache);
|
||||
int iterated_cache_get(IteratedCache *cache, const void ***res_keys, const void ***res_values, unsigned *res_n_entries);
|
||||
|
||||
HashmapBase *_hashmap_copy(HashmapBase *h HASHMAP_DEBUG_PARAMS);
|
||||
HashmapBase* _hashmap_copy(HashmapBase *h HASHMAP_DEBUG_PARAMS);
|
||||
#define hashmap_copy(h) ((Hashmap*) _hashmap_copy(HASHMAP_BASE(h) HASHMAP_DEBUG_SRC_ARGS))
|
||||
#define ordered_hashmap_copy(h) ((OrderedHashmap*) _hashmap_copy(HASHMAP_BASE(h) HASHMAP_DEBUG_SRC_ARGS))
|
||||
|
||||
@@ -137,11 +137,14 @@ int _ordered_hashmap_ensure_allocated(OrderedHashmap **h, const struct hash_ops
|
||||
#define hashmap_ensure_allocated(h, ops) _hashmap_ensure_allocated(h, ops HASHMAP_DEBUG_SRC_ARGS)
|
||||
#define ordered_hashmap_ensure_allocated(h, ops) _ordered_hashmap_ensure_allocated(h, ops HASHMAP_DEBUG_SRC_ARGS)
|
||||
|
||||
IteratedCache *_hashmap_iterated_cache_new(HashmapBase *h);
|
||||
static inline IteratedCache *hashmap_iterated_cache_new(Hashmap *h) {
|
||||
int _ordered_hashmap_ensure_put(OrderedHashmap **h, const struct hash_ops *hash_ops, const void *key, void *value HASHMAP_DEBUG_PARAMS);
|
||||
#define ordered_hashmap_ensure_put(s, ops, key, value) _ordered_hashmap_ensure_put(s, ops, key, value HASHMAP_DEBUG_SRC_ARGS)
|
||||
|
||||
IteratedCache* _hashmap_iterated_cache_new(HashmapBase *h);
|
||||
static inline IteratedCache* hashmap_iterated_cache_new(Hashmap *h) {
|
||||
return (IteratedCache*) _hashmap_iterated_cache_new(HASHMAP_BASE(h));
|
||||
}
|
||||
static inline IteratedCache *ordered_hashmap_iterated_cache_new(OrderedHashmap *h) {
|
||||
static inline IteratedCache* ordered_hashmap_iterated_cache_new(OrderedHashmap *h) {
|
||||
return (IteratedCache*) _hashmap_iterated_cache_new(HASHMAP_BASE(h));
|
||||
}
|
||||
|
||||
@@ -163,7 +166,7 @@ static inline int ordered_hashmap_replace(OrderedHashmap *h, const void *key, vo
|
||||
return hashmap_replace(PLAIN_HASHMAP(h), key, value);
|
||||
}
|
||||
|
||||
void *_hashmap_get(HashmapBase *h, const void *key);
|
||||
void* _hashmap_get(HashmapBase *h, const void *key);
|
||||
static inline void *hashmap_get(Hashmap *h, const void *key) {
|
||||
return _hashmap_get(HASHMAP_BASE(h), key);
|
||||
}
|
||||
@@ -171,7 +174,7 @@ static inline void *ordered_hashmap_get(OrderedHashmap *h, const void *key) {
|
||||
return _hashmap_get(HASHMAP_BASE(h), key);
|
||||
}
|
||||
|
||||
void *hashmap_get2(Hashmap *h, const void *key, void **rkey);
|
||||
void* hashmap_get2(Hashmap *h, const void *key, void **rkey);
|
||||
static inline void *ordered_hashmap_get2(OrderedHashmap *h, const void *key, void **rkey) {
|
||||
return hashmap_get2(PLAIN_HASHMAP(h), key, rkey);
|
||||
}
|
||||
@@ -184,7 +187,7 @@ static inline bool ordered_hashmap_contains(OrderedHashmap *h, const void *key)
|
||||
return _hashmap_contains(HASHMAP_BASE(h), key);
|
||||
}
|
||||
|
||||
void *_hashmap_remove(HashmapBase *h, const void *key);
|
||||
void* _hashmap_remove(HashmapBase *h, const void *key);
|
||||
static inline void *hashmap_remove(Hashmap *h, const void *key) {
|
||||
return _hashmap_remove(HASHMAP_BASE(h), key);
|
||||
}
|
||||
@@ -192,17 +195,17 @@ static inline void *ordered_hashmap_remove(OrderedHashmap *h, const void *key) {
|
||||
return _hashmap_remove(HASHMAP_BASE(h), key);
|
||||
}
|
||||
|
||||
void *hashmap_remove2(Hashmap *h, const void *key, void **rkey);
|
||||
void* hashmap_remove2(Hashmap *h, const void *key, void **rkey);
|
||||
static inline void *ordered_hashmap_remove2(OrderedHashmap *h, const void *key, void **rkey) {
|
||||
return hashmap_remove2(PLAIN_HASHMAP(h), key, rkey);
|
||||
}
|
||||
|
||||
void *_hashmap_remove_value(HashmapBase *h, const void *key, void *value);
|
||||
void* _hashmap_remove_value(HashmapBase *h, const void *key, void *value);
|
||||
static inline void *hashmap_remove_value(Hashmap *h, const void *key, void *value) {
|
||||
return _hashmap_remove_value(HASHMAP_BASE(h), key, value);
|
||||
}
|
||||
|
||||
static inline void *ordered_hashmap_remove_value(OrderedHashmap *h, const void *key, void *value) {
|
||||
static inline void* ordered_hashmap_remove_value(OrderedHashmap *h, const void *key, void *value) {
|
||||
return hashmap_remove_value(PLAIN_HASHMAP(h), key, value);
|
||||
}
|
||||
|
||||
@@ -388,13 +391,13 @@ static inline void *ordered_hashmap_first_key(OrderedHashmap *h) {
|
||||
})
|
||||
|
||||
/* no hashmap_next */
|
||||
void *ordered_hashmap_next(OrderedHashmap *h, const void *key);
|
||||
void* ordered_hashmap_next(OrderedHashmap *h, const void *key);
|
||||
|
||||
char **_hashmap_get_strv(HashmapBase *h);
|
||||
static inline char **hashmap_get_strv(Hashmap *h) {
|
||||
char** _hashmap_get_strv(HashmapBase *h);
|
||||
static inline char** hashmap_get_strv(Hashmap *h) {
|
||||
return _hashmap_get_strv(HASHMAP_BASE(h));
|
||||
}
|
||||
static inline char **ordered_hashmap_get_strv(OrderedHashmap *h) {
|
||||
static inline char** ordered_hashmap_get_strv(OrderedHashmap *h) {
|
||||
return _hashmap_get_strv(HASHMAP_BASE(h));
|
||||
}
|
||||
|
||||
@@ -404,17 +407,25 @@ static inline char **ordered_hashmap_get_strv(OrderedHashmap *h) {
|
||||
* the entries were inserted.
|
||||
* It is safe to remove the current entry.
|
||||
*/
|
||||
#define HASHMAP_FOREACH(e, h, i) \
|
||||
for ((i) = ITERATOR_FIRST; hashmap_iterate((h), &(i), (void**)&(e), NULL); )
|
||||
#define _HASHMAP_FOREACH(e, h, i) \
|
||||
for (Iterator i = ITERATOR_FIRST; hashmap_iterate((h), &i, (void**)&(e), NULL); )
|
||||
#define HASHMAP_FOREACH(e, h) \
|
||||
_HASHMAP_FOREACH(e, h, UNIQ_T(i, UNIQ))
|
||||
|
||||
#define ORDERED_HASHMAP_FOREACH(e, h, i) \
|
||||
for ((i) = ITERATOR_FIRST; ordered_hashmap_iterate((h), &(i), (void**)&(e), NULL); )
|
||||
#define _ORDERED_HASHMAP_FOREACH(e, h, i) \
|
||||
for (Iterator i = ITERATOR_FIRST; ordered_hashmap_iterate((h), &i, (void**)&(e), NULL); )
|
||||
#define ORDERED_HASHMAP_FOREACH(e, h) \
|
||||
_ORDERED_HASHMAP_FOREACH(e, h, UNIQ_T(i, UNIQ))
|
||||
|
||||
#define HASHMAP_FOREACH_KEY(e, k, h, i) \
|
||||
for ((i) = ITERATOR_FIRST; hashmap_iterate((h), &(i), (void**)&(e), (const void**) &(k)); )
|
||||
#define _HASHMAP_FOREACH_KEY(e, k, h, i) \
|
||||
for (Iterator i = ITERATOR_FIRST; hashmap_iterate((h), &i, (void**)&(e), (const void**) &(k)); )
|
||||
#define HASHMAP_FOREACH_KEY(e, k, h) \
|
||||
_HASHMAP_FOREACH_KEY(e, k, h, UNIQ_T(i, UNIQ))
|
||||
|
||||
#define ORDERED_HASHMAP_FOREACH_KEY(e, k, h, i) \
|
||||
for ((i) = ITERATOR_FIRST; ordered_hashmap_iterate((h), &(i), (void**)&(e), (const void**) &(k)); )
|
||||
#define _ORDERED_HASHMAP_FOREACH_KEY(e, k, h, i) \
|
||||
for (Iterator i = ITERATOR_FIRST; ordered_hashmap_iterate((h), &i, (void**)&(e), (const void**) &(k)); )
|
||||
#define ORDERED_HASHMAP_FOREACH_KEY(e, k, h) \
|
||||
_ORDERED_HASHMAP_FOREACH_KEY(e, k, h, UNIQ_T(i, UNIQ))
|
||||
|
||||
DEFINE_TRIVIAL_CLEANUP_FUNC(Hashmap*, hashmap_free);
|
||||
DEFINE_TRIVIAL_CLEANUP_FUNC(Hashmap*, hashmap_free_free);
|
||||
|
@@ -56,6 +56,16 @@ int in_addr_is_link_local(int family, const union in_addr_union *u) {
|
||||
return -EAFNOSUPPORT;
|
||||
}
|
||||
|
||||
bool in6_addr_is_link_local_all_nodes(const struct in6_addr *a) {
|
||||
assert(a);
|
||||
|
||||
/* ff02::1 */
|
||||
return be32toh(a->s6_addr32[0]) == UINT32_C(0xff020000) &&
|
||||
a->s6_addr32[1] == 0 &&
|
||||
a->s6_addr32[2] == 0 &&
|
||||
be32toh(a->s6_addr32[3]) == UINT32_C(0x00000001);
|
||||
}
|
||||
|
||||
int in_addr_is_multicast(int family, const union in_addr_union *u) {
|
||||
assert(u);
|
||||
|
||||
@@ -68,6 +78,12 @@ int in_addr_is_multicast(int family, const union in_addr_union *u) {
|
||||
return -EAFNOSUPPORT;
|
||||
}
|
||||
|
||||
bool in4_addr_is_local_multicast(const struct in_addr *a) {
|
||||
assert(a);
|
||||
|
||||
return (be32toh(a->s_addr) & UINT32_C(0xffffff00)) == UINT32_C(0xe0000000);
|
||||
}
|
||||
|
||||
bool in4_addr_is_localhost(const struct in_addr *a) {
|
||||
assert(a);
|
||||
|
||||
@@ -408,46 +424,6 @@ int in_addr_prefix_to_string(int family, const union in_addr_union *u, unsigned
|
||||
}
|
||||
#endif /* NM_IGNORED */
|
||||
|
||||
int in_addr_ifindex_to_string(int family, const union in_addr_union *u, int ifindex, char **ret) {
|
||||
_cleanup_free_ char *x = NULL;
|
||||
size_t l;
|
||||
int r;
|
||||
|
||||
assert(u);
|
||||
assert(ret);
|
||||
|
||||
/* Much like in_addr_to_string(), but optionally appends the zone interface index to the address, to properly
|
||||
* handle IPv6 link-local addresses. */
|
||||
|
||||
if (family != AF_INET6)
|
||||
goto fallback;
|
||||
if (ifindex <= 0)
|
||||
goto fallback;
|
||||
|
||||
r = in_addr_is_link_local(family, u);
|
||||
if (r < 0)
|
||||
return r;
|
||||
if (r == 0)
|
||||
goto fallback;
|
||||
|
||||
l = INET6_ADDRSTRLEN + 1 + DECIMAL_STR_MAX(ifindex) + 1;
|
||||
x = new(char, l);
|
||||
if (!x)
|
||||
return -ENOMEM;
|
||||
|
||||
errno = 0;
|
||||
if (!inet_ntop(family, u, x, l))
|
||||
return errno_or_else(EINVAL);
|
||||
|
||||
sprintf(strchr(x, 0), "%%%i", ifindex);
|
||||
|
||||
*ret = TAKE_PTR(x);
|
||||
return 0;
|
||||
|
||||
fallback:
|
||||
return in_addr_to_string(family, u, ret);
|
||||
}
|
||||
|
||||
int in_addr_port_ifindex_name_to_string(int family, const union in_addr_union *u, uint16_t port, int ifindex, const char *server_name, char **ret) {
|
||||
_cleanup_free_ char *ip_str = NULL, *x = NULL;
|
||||
int r;
|
||||
@@ -802,13 +778,13 @@ static int in_addr_data_compare_func(const struct in_addr_data *x, const struct
|
||||
|
||||
DEFINE_HASH_OPS(in_addr_data_hash_ops, struct in_addr_data, in_addr_data_hash_func, in_addr_data_compare_func);
|
||||
|
||||
static void in6_addr_hash_func(const struct in6_addr *addr, struct siphash *state) {
|
||||
void in6_addr_hash_func(const struct in6_addr *addr, struct siphash *state) {
|
||||
assert(addr);
|
||||
|
||||
siphash24_compress(addr, sizeof(*addr), state);
|
||||
}
|
||||
|
||||
static int in6_addr_compare_func(const struct in6_addr *a, const struct in6_addr *b) {
|
||||
int in6_addr_compare_func(const struct in6_addr *a, const struct in6_addr *b) {
|
||||
return memcmp(a, b, sizeof(*a));
|
||||
}
|
||||
|
||||
|
@@ -12,6 +12,7 @@
|
||||
union in_addr_union {
|
||||
struct in_addr in;
|
||||
struct in6_addr in6;
|
||||
uint8_t bytes[CONST_MAX(sizeof(struct in_addr), sizeof(struct in6_addr))];
|
||||
};
|
||||
|
||||
struct in_addr_data {
|
||||
@@ -26,10 +27,12 @@ int in_addr_is_multicast(int family, const union in_addr_union *u);
|
||||
|
||||
bool in4_addr_is_link_local(const struct in_addr *a);
|
||||
int in_addr_is_link_local(int family, const union in_addr_union *u);
|
||||
bool in6_addr_is_link_local_all_nodes(const struct in6_addr *a);
|
||||
|
||||
bool in4_addr_is_localhost(const struct in_addr *a);
|
||||
int in_addr_is_localhost(int family, const union in_addr_union *u);
|
||||
|
||||
bool in4_addr_is_local_multicast(const struct in_addr *a);
|
||||
bool in4_addr_is_non_local(const struct in_addr *a);
|
||||
|
||||
bool in4_addr_equal(const struct in_addr *a, const struct in_addr *b);
|
||||
@@ -40,8 +43,13 @@ int in_addr_prefix_nth(int family, union in_addr_union *u, unsigned prefixlen, u
|
||||
int in_addr_random_prefix(int family, union in_addr_union *u, unsigned prefixlen_fixed_part, unsigned prefixlen);
|
||||
int in_addr_to_string(int family, const union in_addr_union *u, char **ret);
|
||||
int in_addr_prefix_to_string(int family, const union in_addr_union *u, unsigned prefixlen, char **ret);
|
||||
int in_addr_ifindex_to_string(int family, const union in_addr_union *u, int ifindex, char **ret);
|
||||
int in_addr_port_ifindex_name_to_string(int family, const union in_addr_union *u, uint16_t port, int ifindex, const char *server_name, char **ret);
|
||||
static inline int in_addr_ifindex_to_string(int family, const union in_addr_union *u, int ifindex, char **ret) {
|
||||
return in_addr_port_ifindex_name_to_string(family, u, 0, ifindex, NULL, ret);
|
||||
}
|
||||
static inline int in_addr_port_to_string(int family, const union in_addr_union *u, uint16_t port, char **ret) {
|
||||
return in_addr_port_ifindex_name_to_string(family, u, port, 0, NULL, ret);
|
||||
}
|
||||
int in_addr_from_string(int family, const char *s, union in_addr_union *ret);
|
||||
int in_addr_from_string_auto(const char *s, int *ret_family, union in_addr_union *ret);
|
||||
|
||||
@@ -74,5 +82,8 @@ static inline size_t FAMILY_ADDRESS_SIZE(int family) {
|
||||
* See also oss-fuzz#11344. */
|
||||
#define IN_ADDR_NULL ((union in_addr_union) { .in6 = {} })
|
||||
|
||||
void in6_addr_hash_func(const struct in6_addr *addr, struct siphash *state);
|
||||
int in6_addr_compare_func(const struct in6_addr *a, const struct in6_addr *b);
|
||||
|
||||
extern const struct hash_ops in_addr_data_hash_ops;
|
||||
extern const struct hash_ops in6_addr_hash_ops;
|
||||
|
@@ -158,10 +158,8 @@ int pipe_eof(int fd) {
|
||||
int r;
|
||||
|
||||
r = fd_wait_for_event(fd, POLLIN, 0);
|
||||
if (r < 0)
|
||||
if (r <= 0)
|
||||
return r;
|
||||
if (r == 0)
|
||||
return 0;
|
||||
|
||||
return !!(r & POLLHUP);
|
||||
}
|
||||
|
@@ -248,12 +248,12 @@ void log_assert_failed_return_realm(
|
||||
#define log_full_errno(level, error, ...) \
|
||||
log_full_errno_realm(LOG_REALM, (level), (error), __VA_ARGS__)
|
||||
|
||||
#define log_full(level, ...) log_full_errno((level), 0, __VA_ARGS__)
|
||||
#define log_full(level, ...) (void) log_full_errno((level), 0, __VA_ARGS__)
|
||||
|
||||
int log_emergency_level(void);
|
||||
|
||||
/* Normal logging */
|
||||
#define log_debug(...) log_full(LOG_DEBUG, __VA_ARGS__)
|
||||
#define log_debug(...) log_full_errno(LOG_DEBUG, 0, __VA_ARGS__)
|
||||
#define log_info(...) log_full(LOG_INFO, __VA_ARGS__)
|
||||
#define log_notice(...) log_full(LOG_NOTICE, __VA_ARGS__)
|
||||
#define log_warning(...) log_full(LOG_WARNING, __VA_ARGS__)
|
||||
|
@@ -547,6 +547,9 @@ static inline int __coverity_check_and_return__(int condition) {
|
||||
(y) = (_t); \
|
||||
} while (false)
|
||||
|
||||
#define STRV_MAKE(...) ((char**) ((const char*[]) { __VA_ARGS__, NULL }))
|
||||
#define STRV_MAKE_EMPTY ((char*[1]) { NULL })
|
||||
|
||||
/* Iterates through a specified list of pointers. Accepts NULL pointers, but uses (void*) -1 as internal marker for EOL. */
|
||||
#define FOREACH_POINTER(p, x, ...) \
|
||||
for (typeof(p) *_l = (typeof(p)[]) { ({ p = x; }), ##__VA_ARGS__, (void*) -1 }; \
|
||||
|
@@ -65,6 +65,10 @@ struct sockaddr_vm {
|
||||
#define IP_TRANSPARENT 19
|
||||
#endif
|
||||
|
||||
#ifndef IPV6_FREEBIND
|
||||
#define IPV6_FREEBIND 78
|
||||
#endif
|
||||
|
||||
/* linux/sockios.h */
|
||||
#ifndef SIOCGSKNS
|
||||
#define SIOCGSKNS 0x894C
|
||||
|
@@ -9,45 +9,129 @@
|
||||
#include <linux/stat.h>
|
||||
#endif
|
||||
|
||||
/* a528d35e8bfcc521d7cb70aaf03e1bd296c8493f (4.11) */
|
||||
/* Thew newest definition we are aware of (fa2fcf4f1df1559a0a4ee0f46915b496cc2ebf60; 5.8) */
|
||||
#define STATX_DEFINITION { \
|
||||
__u32 stx_mask; \
|
||||
__u32 stx_blksize; \
|
||||
__u64 stx_attributes; \
|
||||
__u32 stx_nlink; \
|
||||
__u32 stx_uid; \
|
||||
__u32 stx_gid; \
|
||||
__u16 stx_mode; \
|
||||
__u16 __spare0[1]; \
|
||||
__u64 stx_ino; \
|
||||
__u64 stx_size; \
|
||||
__u64 stx_blocks; \
|
||||
__u64 stx_attributes_mask; \
|
||||
struct statx_timestamp stx_atime; \
|
||||
struct statx_timestamp stx_btime; \
|
||||
struct statx_timestamp stx_ctime; \
|
||||
struct statx_timestamp stx_mtime; \
|
||||
__u32 stx_rdev_major; \
|
||||
__u32 stx_rdev_minor; \
|
||||
__u32 stx_dev_major; \
|
||||
__u32 stx_dev_minor; \
|
||||
__u64 stx_mnt_id; \
|
||||
__u64 __spare2; \
|
||||
__u64 __spare3[12]; \
|
||||
}
|
||||
|
||||
#if !HAVE_STRUCT_STATX
|
||||
struct statx_timestamp {
|
||||
__s64 tv_sec;
|
||||
__u32 tv_nsec;
|
||||
__s32 __reserved;
|
||||
};
|
||||
struct statx {
|
||||
__u32 stx_mask;
|
||||
__u32 stx_blksize;
|
||||
__u64 stx_attributes;
|
||||
__u32 stx_nlink;
|
||||
__u32 stx_uid;
|
||||
__u32 stx_gid;
|
||||
__u16 stx_mode;
|
||||
__u16 __spare0[1];
|
||||
__u64 stx_ino;
|
||||
__u64 stx_size;
|
||||
__u64 stx_blocks;
|
||||
__u64 stx_attributes_mask;
|
||||
struct statx_timestamp stx_atime;
|
||||
struct statx_timestamp stx_btime;
|
||||
struct statx_timestamp stx_ctime;
|
||||
struct statx_timestamp stx_mtime;
|
||||
__u32 stx_rdev_major;
|
||||
__u32 stx_rdev_minor;
|
||||
__u32 stx_dev_major;
|
||||
__u32 stx_dev_minor;
|
||||
__u64 __spare2[14];
|
||||
};
|
||||
|
||||
struct statx STATX_DEFINITION;
|
||||
#endif
|
||||
|
||||
/* Always define the newest version we are aware of as a distinct type, so that we can use it even if glibc
|
||||
* defines an older definition */
|
||||
struct new_statx STATX_DEFINITION;
|
||||
#endif /* NM_IGNORED */
|
||||
|
||||
/* a528d35e8bfcc521d7cb70aaf03e1bd296c8493f (4.11) */
|
||||
#ifndef STATX_BTIME
|
||||
#define STATX_BTIME 0x00000800U
|
||||
#ifndef AT_STATX_SYNC_AS_STAT
|
||||
#define AT_STATX_SYNC_AS_STAT 0x0000
|
||||
#endif
|
||||
|
||||
/* a528d35e8bfcc521d7cb70aaf03e1bd296c8493f (4.11) */
|
||||
#ifndef AT_STATX_FORCE_SYNC
|
||||
#define AT_STATX_FORCE_SYNC 0x2000
|
||||
#endif
|
||||
|
||||
/* a528d35e8bfcc521d7cb70aaf03e1bd296c8493f (4.11) */
|
||||
#ifndef AT_STATX_DONT_SYNC
|
||||
#define AT_STATX_DONT_SYNC 0x4000
|
||||
#endif
|
||||
|
||||
/* a528d35e8bfcc521d7cb70aaf03e1bd296c8493f (4.11) */
|
||||
#ifndef STATX_TYPE
|
||||
#define STATX_TYPE 0x00000001U
|
||||
#endif
|
||||
|
||||
/* a528d35e8bfcc521d7cb70aaf03e1bd296c8493f (4.11) */
|
||||
#ifndef STATX_MODE
|
||||
#define STATX_MODE 0x00000002U
|
||||
#endif
|
||||
|
||||
/* a528d35e8bfcc521d7cb70aaf03e1bd296c8493f (4.11) */
|
||||
#ifndef STATX_NLINK
|
||||
#define STATX_NLINK 0x00000004U
|
||||
#endif
|
||||
|
||||
/* a528d35e8bfcc521d7cb70aaf03e1bd296c8493f (4.11) */
|
||||
#ifndef STATX_UID
|
||||
#define STATX_UID 0x00000008U
|
||||
#endif
|
||||
|
||||
/* a528d35e8bfcc521d7cb70aaf03e1bd296c8493f (4.11) */
|
||||
#ifndef STATX_GID
|
||||
#define STATX_GID 0x00000010U
|
||||
#endif
|
||||
|
||||
/* a528d35e8bfcc521d7cb70aaf03e1bd296c8493f (4.11) */
|
||||
#ifndef STATX_ATIME
|
||||
#define STATX_ATIME 0x00000020U
|
||||
#endif
|
||||
|
||||
/* a528d35e8bfcc521d7cb70aaf03e1bd296c8493f (4.11) */
|
||||
#ifndef STATX_MTIME
|
||||
#define STATX_MTIME 0x00000040U
|
||||
#endif
|
||||
|
||||
/* a528d35e8bfcc521d7cb70aaf03e1bd296c8493f (4.11) */
|
||||
#ifndef STATX_CTIME
|
||||
#define STATX_CTIME 0x00000080U
|
||||
#endif
|
||||
|
||||
/* a528d35e8bfcc521d7cb70aaf03e1bd296c8493f (4.11) */
|
||||
#ifndef STATX_INO
|
||||
#define STATX_INO 0x00000100U
|
||||
#endif
|
||||
|
||||
/* a528d35e8bfcc521d7cb70aaf03e1bd296c8493f (4.11) */
|
||||
#ifndef STATX_SIZE
|
||||
#define STATX_SIZE 0x00000200U
|
||||
#endif
|
||||
|
||||
/* a528d35e8bfcc521d7cb70aaf03e1bd296c8493f (4.11) */
|
||||
#ifndef STATX_BLOCKS
|
||||
#define STATX_BLOCKS 0x00000400U
|
||||
#endif
|
||||
|
||||
/* a528d35e8bfcc521d7cb70aaf03e1bd296c8493f (4.11) */
|
||||
#ifndef STATX_BTIME
|
||||
#define STATX_BTIME 0x00000800U
|
||||
#endif
|
||||
|
||||
/* fa2fcf4f1df1559a0a4ee0f46915b496cc2ebf60 (5.8) */
|
||||
#ifndef STATX_MNT_ID
|
||||
#define STATX_MNT_ID 0x00001000U
|
||||
#endif
|
||||
|
||||
/* 80340fe3605c0e78cfe496c3b3878be828cfdbfe (5.8) */
|
||||
#ifndef STATX_ATTR_MOUNT_ROOT
|
||||
#define STATX_ATTR_MOUNT_ROOT 0x00002000 /* Root of a mount */
|
||||
#endif
|
||||
|
@@ -35,39 +35,49 @@ static inline int missing_pivot_root(const char *new_root, const char *put_old)
|
||||
|
||||
/* ======================================================================= */
|
||||
|
||||
#if !HAVE_MEMFD_CREATE
|
||||
#if defined __x86_64__
|
||||
# define systemd_NR_memfd_create 319
|
||||
#elif defined __arm__
|
||||
# define systemd_NR_memfd_create 385
|
||||
#elif defined __aarch64__
|
||||
# define systemd_NR_memfd_create 279
|
||||
#elif defined(__powerpc__)
|
||||
# define systemd_NR_memfd_create 360
|
||||
#elif defined __s390__
|
||||
# define systemd_NR_memfd_create 350
|
||||
#elif defined _MIPS_SIM
|
||||
# if _MIPS_SIM == _MIPS_SIM_ABI32
|
||||
# define systemd_NR_memfd_create 4354
|
||||
# endif
|
||||
# if _MIPS_SIM == _MIPS_SIM_NABI32
|
||||
# define systemd_NR_memfd_create 6318
|
||||
# endif
|
||||
# if _MIPS_SIM == _MIPS_SIM_ABI64
|
||||
# define systemd_NR_memfd_create 5314
|
||||
# endif
|
||||
#elif defined __i386__
|
||||
# define systemd_NR_memfd_create 356
|
||||
#elif defined __arc__
|
||||
# define systemd_NR_memfd_create 279
|
||||
#else
|
||||
# warning "memfd_create() syscall number unknown for your architecture"
|
||||
#endif
|
||||
|
||||
/* may be (invalid) negative number due to libseccomp, see PR 13319 */
|
||||
# if ! (defined __NR_memfd_create && __NR_memfd_create >= 0)
|
||||
#if defined __NR_memfd_create && __NR_memfd_create >= 0
|
||||
# if defined systemd_NR_memfd_create
|
||||
assert_cc(__NR_memfd_create == systemd_NR_memfd_create);
|
||||
# endif
|
||||
#else
|
||||
# if defined __NR_memfd_create
|
||||
# undef __NR_memfd_create
|
||||
# endif
|
||||
# if defined __x86_64__
|
||||
# define __NR_memfd_create 319
|
||||
# elif defined __arm__
|
||||
# define __NR_memfd_create 385
|
||||
# elif defined __aarch64__
|
||||
# define __NR_memfd_create 279
|
||||
# elif defined __s390__
|
||||
# define __NR_memfd_create 350
|
||||
# elif defined _MIPS_SIM
|
||||
# if _MIPS_SIM == _MIPS_SIM_ABI32
|
||||
# define __NR_memfd_create 4354
|
||||
# endif
|
||||
# if _MIPS_SIM == _MIPS_SIM_NABI32
|
||||
# define __NR_memfd_create 6318
|
||||
# endif
|
||||
# if _MIPS_SIM == _MIPS_SIM_ABI64
|
||||
# define __NR_memfd_create 5314
|
||||
# endif
|
||||
# elif defined __i386__
|
||||
# define __NR_memfd_create 356
|
||||
# elif defined __arc__
|
||||
# define __NR_memfd_create 279
|
||||
# else
|
||||
# warning "__NR_memfd_create unknown for your architecture"
|
||||
# endif
|
||||
# if defined systemd_NR_memfd_create
|
||||
# define __NR_memfd_create systemd_NR_memfd_create
|
||||
# endif
|
||||
#endif
|
||||
|
||||
#if !HAVE_MEMFD_CREATE
|
||||
static inline int missing_memfd_create(const char *name, unsigned int flags) {
|
||||
# ifdef __NR_memfd_create
|
||||
return syscall(__NR_memfd_create, name, flags);
|
||||
@@ -82,45 +92,53 @@ static inline int missing_memfd_create(const char *name, unsigned int flags) {
|
||||
|
||||
/* ======================================================================= */
|
||||
|
||||
#if !HAVE_GETRANDOM
|
||||
#if defined __x86_64__
|
||||
# define systemd_NR_getrandom 318
|
||||
#elif defined(__i386__)
|
||||
# define systemd_NR_getrandom 355
|
||||
#elif defined(__arm__)
|
||||
# define systemd_NR_getrandom 384
|
||||
#elif defined(__aarch64__)
|
||||
# define systemd_NR_getrandom 278
|
||||
#elif defined(__ia64__)
|
||||
# define systemd_NR_getrandom 1339
|
||||
#elif defined(__m68k__)
|
||||
# define systemd_NR_getrandom 352
|
||||
#elif defined(__s390x__)
|
||||
# define systemd_NR_getrandom 349
|
||||
#elif defined(__powerpc__)
|
||||
# define systemd_NR_getrandom 359
|
||||
#elif defined _MIPS_SIM
|
||||
# if _MIPS_SIM == _MIPS_SIM_ABI32
|
||||
# define systemd_NR_getrandom 4353
|
||||
# endif
|
||||
# if _MIPS_SIM == _MIPS_SIM_NABI32
|
||||
# define systemd_NR_getrandom 6317
|
||||
# endif
|
||||
# if _MIPS_SIM == _MIPS_SIM_ABI64
|
||||
# define systemd_NR_getrandom 5313
|
||||
# endif
|
||||
#elif defined(__arc__)
|
||||
# define systemd_NR_getrandom 278
|
||||
#else
|
||||
# warning "getrandom() syscall number unknown for your architecture"
|
||||
#endif
|
||||
|
||||
/* may be (invalid) negative number due to libseccomp, see PR 13319 */
|
||||
# if ! (defined __NR_getrandom && __NR_getrandom >= 0)
|
||||
#if defined __NR_getrandom && __NR_getrandom >= 0
|
||||
# if defined systemd_NR_getrandom
|
||||
assert_cc(__NR_getrandom == systemd_NR_getrandom);
|
||||
# endif
|
||||
#else
|
||||
# if defined __NR_getrandom
|
||||
# undef __NR_getrandom
|
||||
# endif
|
||||
# if defined __x86_64__
|
||||
# define __NR_getrandom 318
|
||||
# elif defined(__i386__)
|
||||
# define __NR_getrandom 355
|
||||
# elif defined(__arm__)
|
||||
# define __NR_getrandom 384
|
||||
# elif defined(__aarch64__)
|
||||
# define __NR_getrandom 278
|
||||
# elif defined(__ia64__)
|
||||
# define __NR_getrandom 1339
|
||||
# elif defined(__m68k__)
|
||||
# define __NR_getrandom 352
|
||||
# elif defined(__s390x__)
|
||||
# define __NR_getrandom 349
|
||||
# elif defined(__powerpc__)
|
||||
# define __NR_getrandom 359
|
||||
# elif defined _MIPS_SIM
|
||||
# if _MIPS_SIM == _MIPS_SIM_ABI32
|
||||
# define __NR_getrandom 4353
|
||||
# endif
|
||||
# if _MIPS_SIM == _MIPS_SIM_NABI32
|
||||
# define __NR_getrandom 6317
|
||||
# endif
|
||||
# if _MIPS_SIM == _MIPS_SIM_ABI64
|
||||
# define __NR_getrandom 5313
|
||||
# endif
|
||||
# elif defined(__arc__)
|
||||
# define __NR_getrandom 278
|
||||
# else
|
||||
# warning "__NR_getrandom unknown for your architecture"
|
||||
# endif
|
||||
# if defined systemd_NR_getrandom
|
||||
# define __NR_getrandom systemd_NR_getrandom
|
||||
# endif
|
||||
#endif
|
||||
|
||||
#if !HAVE_GETRANDOM
|
||||
static inline int missing_getrandom(void *buffer, size_t count, unsigned flags) {
|
||||
# ifdef __NR_getrandom
|
||||
return syscall(__NR_getrandom, buffer, count, flags);
|
||||
@@ -135,9 +153,14 @@ static inline int missing_getrandom(void *buffer, size_t count, unsigned flags)
|
||||
|
||||
/* ======================================================================= */
|
||||
|
||||
/* The syscall has been defined since forever, but the glibc wrapper was missing. */
|
||||
#if !HAVE_GETTID
|
||||
static inline pid_t missing_gettid(void) {
|
||||
# if defined __NR_gettid && __NR_gettid >= 0
|
||||
return (pid_t) syscall(__NR_gettid);
|
||||
# else
|
||||
# error "__NR_gettid not defined"
|
||||
# endif
|
||||
}
|
||||
|
||||
# define gettid missing_gettid
|
||||
@@ -145,27 +168,39 @@ static inline pid_t missing_gettid(void) {
|
||||
|
||||
/* ======================================================================= */
|
||||
|
||||
#if !HAVE_NAME_TO_HANDLE_AT
|
||||
#if defined(__x86_64__)
|
||||
# define systemd_NR_name_to_handle_at 303
|
||||
#elif defined(__i386__)
|
||||
# define systemd_NR_name_to_handle_at 341
|
||||
#elif defined(__arm__)
|
||||
# define systemd_NR_name_to_handle_at 370
|
||||
#elif defined __aarch64__
|
||||
# define systemd_NR_name_to_handle_at 264
|
||||
#elif defined(__powerpc__)
|
||||
# define systemd_NR_name_to_handle_at 345
|
||||
#elif defined __s390__ || defined __s390x__
|
||||
# define systemd_NR_name_to_handle_at 335
|
||||
#elif defined(__arc__)
|
||||
# define systemd_NR_name_to_handle_at 264
|
||||
#else
|
||||
# warning "name_to_handle_at number is not defined"
|
||||
#endif
|
||||
|
||||
/* may be (invalid) negative number due to libseccomp, see PR 13319 */
|
||||
# if ! (defined __NR_name_to_handle_at && __NR_name_to_handle_at >= 0)
|
||||
#if defined __NR_name_to_handle_at && __NR_name_to_handle_at >= 0
|
||||
# if defined systemd_NR_name_to_handle_at
|
||||
assert_cc(__NR_name_to_handle_at == systemd_NR_name_to_handle_at);
|
||||
# endif
|
||||
#else
|
||||
# if defined __NR_name_to_handle_at
|
||||
# undef __NR_name_to_handle_at
|
||||
# endif
|
||||
# if defined(__x86_64__)
|
||||
# define __NR_name_to_handle_at 303
|
||||
# elif defined(__i386__)
|
||||
# define __NR_name_to_handle_at 341
|
||||
# elif defined(__arm__)
|
||||
# define __NR_name_to_handle_at 370
|
||||
# elif defined(__powerpc__)
|
||||
# define __NR_name_to_handle_at 345
|
||||
# elif defined(__arc__)
|
||||
# define __NR_name_to_handle_at 264
|
||||
# else
|
||||
# error "__NR_name_to_handle_at is not defined"
|
||||
# endif
|
||||
# if defined systemd_NR_name_to_handle_at
|
||||
# define __NR_name_to_handle_at systemd_NR_name_to_handle_at
|
||||
# endif
|
||||
#endif
|
||||
|
||||
#if !HAVE_NAME_TO_HANDLE_AT
|
||||
struct file_handle {
|
||||
unsigned int handle_bytes;
|
||||
int handle_type;
|
||||
@@ -186,23 +221,39 @@ static inline int missing_name_to_handle_at(int fd, const char *name, struct fil
|
||||
|
||||
/* ======================================================================= */
|
||||
|
||||
#if !HAVE_SETNS
|
||||
#if defined __aarch64__
|
||||
# define systemd_NR_setns 268
|
||||
#elif defined __arm__
|
||||
# define systemd_NR_setns 375
|
||||
#elif defined(__x86_64__)
|
||||
# define systemd_NR_setns 308
|
||||
#elif defined(__i386__)
|
||||
# define systemd_NR_setns 346
|
||||
#elif defined(__powerpc__)
|
||||
# define systemd_NR_setns 350
|
||||
#elif defined __s390__ || defined __s390x__
|
||||
# define systemd_NR_setns 339
|
||||
#elif defined(__arc__)
|
||||
# define systemd_NR_setns 268
|
||||
#else
|
||||
# warning "setns() syscall number unknown for your architecture"
|
||||
#endif
|
||||
|
||||
/* may be (invalid) negative number due to libseccomp, see PR 13319 */
|
||||
# if ! (defined __NR_setns && __NR_setns >= 0)
|
||||
#if defined __NR_setns && __NR_setns >= 0
|
||||
# if defined systemd_NR_setns
|
||||
assert_cc(__NR_setns == systemd_NR_setns);
|
||||
# endif
|
||||
#else
|
||||
# if defined __NR_setns
|
||||
# undef __NR_setns
|
||||
# endif
|
||||
# if defined(__x86_64__)
|
||||
# define __NR_setns 308
|
||||
# elif defined(__i386__)
|
||||
# define __NR_setns 346
|
||||
# elif defined(__arc__)
|
||||
# define __NR_setns 268
|
||||
# else
|
||||
# error "__NR_setns is not defined"
|
||||
# endif
|
||||
# if defined systemd_NR_setns
|
||||
# define __NR_setns systemd_NR_setns
|
||||
# endif
|
||||
#endif
|
||||
|
||||
#if !HAVE_SETNS
|
||||
static inline int missing_setns(int fd, int nstype) {
|
||||
# ifdef __NR_setns
|
||||
return syscall(__NR_setns, fd, nstype);
|
||||
@@ -227,41 +278,49 @@ static inline pid_t raw_getpid(void) {
|
||||
|
||||
/* ======================================================================= */
|
||||
|
||||
#if !HAVE_RENAMEAT2
|
||||
#if defined __x86_64__
|
||||
# define systemd_NR_renameat2 316
|
||||
#elif defined __arm__
|
||||
# define systemd_NR_renameat2 382
|
||||
#elif defined __aarch64__
|
||||
# define systemd_NR_renameat2 276
|
||||
#elif defined _MIPS_SIM
|
||||
# if _MIPS_SIM == _MIPS_SIM_ABI32
|
||||
# define systemd_NR_renameat2 4351
|
||||
# endif
|
||||
# if _MIPS_SIM == _MIPS_SIM_NABI32
|
||||
# define systemd_NR_renameat2 6315
|
||||
# endif
|
||||
# if _MIPS_SIM == _MIPS_SIM_ABI64
|
||||
# define systemd_NR_renameat2 5311
|
||||
# endif
|
||||
#elif defined __i386__
|
||||
# define systemd_NR_renameat2 353
|
||||
#elif defined __powerpc64__
|
||||
# define systemd_NR_renameat2 357
|
||||
#elif defined __s390__ || defined __s390x__
|
||||
# define systemd_NR_renameat2 347
|
||||
#elif defined __arc__
|
||||
# define systemd_NR_renameat2 276
|
||||
#else
|
||||
# warning "renameat2() syscall number unknown for your architecture"
|
||||
#endif
|
||||
|
||||
/* may be (invalid) negative number due to libseccomp, see PR 13319 */
|
||||
# if ! (defined __NR_renameat2 && __NR_renameat2 >= 0)
|
||||
#if defined __NR_renameat2 && __NR_renameat2 >= 0
|
||||
# if defined systemd_NR_renameat2
|
||||
assert_cc(__NR_renameat2 == systemd_NR_renameat2);
|
||||
# endif
|
||||
#else
|
||||
# if defined __NR_renameat2
|
||||
# undef __NR_renameat2
|
||||
# endif
|
||||
# if defined __x86_64__
|
||||
# define __NR_renameat2 316
|
||||
# elif defined __arm__
|
||||
# define __NR_renameat2 382
|
||||
# elif defined __aarch64__
|
||||
# define __NR_renameat2 276
|
||||
# elif defined _MIPS_SIM
|
||||
# if _MIPS_SIM == _MIPS_SIM_ABI32
|
||||
# define __NR_renameat2 4351
|
||||
# endif
|
||||
# if _MIPS_SIM == _MIPS_SIM_NABI32
|
||||
# define __NR_renameat2 6315
|
||||
# endif
|
||||
# if _MIPS_SIM == _MIPS_SIM_ABI64
|
||||
# define __NR_renameat2 5311
|
||||
# endif
|
||||
# elif defined __i386__
|
||||
# define __NR_renameat2 353
|
||||
# elif defined __powerpc64__
|
||||
# define __NR_renameat2 357
|
||||
# elif defined __s390__ || defined __s390x__
|
||||
# define __NR_renameat2 347
|
||||
# elif defined __arc__
|
||||
# define __NR_renameat2 276
|
||||
# else
|
||||
# warning "__NR_renameat2 unknown for your architecture"
|
||||
# endif
|
||||
# if defined systemd_NR_renameat2
|
||||
# define __NR_renameat2 systemd_NR_renameat2
|
||||
# endif
|
||||
#endif
|
||||
|
||||
#if !HAVE_RENAMEAT2
|
||||
static inline int missing_renameat2(int oldfd, const char *oldname, int newfd, const char *newname, unsigned flags) {
|
||||
# ifdef __NR_renameat2
|
||||
return syscall(__NR_renameat2, oldfd, oldname, newfd, newname, flags);
|
||||
@@ -328,31 +387,39 @@ static inline key_serial_t missing_request_key(const char *type, const char *des
|
||||
|
||||
/* ======================================================================= */
|
||||
|
||||
#if !HAVE_COPY_FILE_RANGE
|
||||
#if defined(__x86_64__)
|
||||
# define systemd_NR_copy_file_range 326
|
||||
#elif defined(__i386__)
|
||||
# define systemd_NR_copy_file_range 377
|
||||
#elif defined __s390__
|
||||
# define systemd_NR_copy_file_range 375
|
||||
#elif defined __arm__
|
||||
# define systemd_NR_copy_file_range 391
|
||||
#elif defined __aarch64__
|
||||
# define systemd_NR_copy_file_range 285
|
||||
#elif defined __powerpc__
|
||||
# define systemd_NR_copy_file_range 379
|
||||
#elif defined __arc__
|
||||
# define systemd_NR_copy_file_range 285
|
||||
#else
|
||||
# warning "copy_file_range() syscall number unknown for your architecture"
|
||||
#endif
|
||||
|
||||
/* may be (invalid) negative number due to libseccomp, see PR 13319 */
|
||||
# if ! (defined __NR_copy_file_range && __NR_copy_file_range >= 0)
|
||||
#if defined __NR_copy_file_range && __NR_copy_file_range >= 0
|
||||
# if defined systemd_NR_copy_file_range
|
||||
assert_cc(__NR_copy_file_range == systemd_NR_copy_file_range);
|
||||
# endif
|
||||
#else
|
||||
# if defined __NR_copy_file_range
|
||||
# undef __NR_copy_file_range
|
||||
# endif
|
||||
# if defined(__x86_64__)
|
||||
# define __NR_copy_file_range 326
|
||||
# elif defined(__i386__)
|
||||
# define __NR_copy_file_range 377
|
||||
# elif defined __s390__
|
||||
# define __NR_copy_file_range 375
|
||||
# elif defined __arm__
|
||||
# define __NR_copy_file_range 391
|
||||
# elif defined __aarch64__
|
||||
# define __NR_copy_file_range 285
|
||||
# elif defined __powerpc__
|
||||
# define __NR_copy_file_range 379
|
||||
# elif defined __arc__
|
||||
# define __NR_copy_file_range 285
|
||||
# else
|
||||
# warning "__NR_copy_file_range not defined for your architecture"
|
||||
# endif
|
||||
# if defined systemd_NR_copy_file_range
|
||||
# define __NR_copy_file_range systemd_NR_copy_file_range
|
||||
# endif
|
||||
#endif
|
||||
|
||||
#if !HAVE_COPY_FILE_RANGE
|
||||
static inline ssize_t missing_copy_file_range(int fd_in, loff_t *off_in,
|
||||
int fd_out, loff_t *off_out,
|
||||
size_t len,
|
||||
@@ -370,31 +437,41 @@ static inline ssize_t missing_copy_file_range(int fd_in, loff_t *off_in,
|
||||
|
||||
/* ======================================================================= */
|
||||
|
||||
#if !HAVE_BPF
|
||||
#if defined __i386__
|
||||
# define systemd_NR_bpf 357
|
||||
#elif defined __x86_64__
|
||||
# define systemd_NR_bpf 321
|
||||
#elif defined __aarch64__
|
||||
# define systemd_NR_bpf 280
|
||||
#elif defined __arm__
|
||||
# define systemd_NR_bpf 386
|
||||
#elif defined(__powerpc__)
|
||||
# define systemd_NR_bpf 361
|
||||
#elif defined __sparc__
|
||||
# define systemd_NR_bpf 349
|
||||
#elif defined __s390__
|
||||
# define systemd_NR_bpf 351
|
||||
#elif defined __tilegx__
|
||||
# define systemd_NR_bpf 280
|
||||
#else
|
||||
# warning "bpf() syscall number unknown for your architecture"
|
||||
#endif
|
||||
|
||||
/* may be (invalid) negative number due to libseccomp, see PR 13319 */
|
||||
# if ! (defined __NR_bpf && __NR_bpf >= 0)
|
||||
#if defined __NR_bpf && __NR_bpf >= 0
|
||||
# if defined systemd_NR_bpf
|
||||
assert_cc(__NR_bpf == systemd_NR_bpf);
|
||||
# endif
|
||||
#else
|
||||
# if defined __NR_bpf
|
||||
# undef __NR_bpf
|
||||
# endif
|
||||
# if defined __i386__
|
||||
# define __NR_bpf 357
|
||||
# elif defined __x86_64__
|
||||
# define __NR_bpf 321
|
||||
# elif defined __aarch64__
|
||||
# define __NR_bpf 280
|
||||
# elif defined __arm__
|
||||
# define __NR_bpf 386
|
||||
# elif defined __sparc__
|
||||
# define __NR_bpf 349
|
||||
# elif defined __s390__
|
||||
# define __NR_bpf 351
|
||||
# elif defined __tilegx__
|
||||
# define __NR_bpf 280
|
||||
# else
|
||||
# warning "__NR_bpf not defined for your architecture"
|
||||
# endif
|
||||
# if defined systemd_NR_bpf
|
||||
# define __NR_bpf systemd_NR_bpf
|
||||
# endif
|
||||
#endif
|
||||
|
||||
#if !HAVE_BPF
|
||||
union bpf_attr;
|
||||
|
||||
static inline int missing_bpf(int cmd, union bpf_attr *attr, size_t size) {
|
||||
@@ -412,69 +489,84 @@ static inline int missing_bpf(int cmd, union bpf_attr *attr, size_t size) {
|
||||
/* ======================================================================= */
|
||||
|
||||
#ifndef __IGNORE_pkey_mprotect
|
||||
# if defined __i386__
|
||||
# define systemd_NR_pkey_mprotect 380
|
||||
# elif defined __x86_64__
|
||||
# define systemd_NR_pkey_mprotect 329
|
||||
# elif defined __aarch64__
|
||||
# define systemd_NR_pkey_mprotect 288
|
||||
# elif defined __arm__
|
||||
# define systemd_NR_pkey_mprotect 394
|
||||
# elif defined __powerpc__
|
||||
# define systemd_NR_pkey_mprotect 386
|
||||
# elif defined __s390__
|
||||
# define systemd_NR_pkey_mprotect 384
|
||||
# elif defined _MIPS_SIM
|
||||
# if _MIPS_SIM == _MIPS_SIM_ABI32
|
||||
# define systemd_NR_pkey_mprotect 4363
|
||||
# endif
|
||||
# if _MIPS_SIM == _MIPS_SIM_NABI32
|
||||
# define systemd_NR_pkey_mprotect 6327
|
||||
# endif
|
||||
# if _MIPS_SIM == _MIPS_SIM_ABI64
|
||||
# define systemd_NR_pkey_mprotect 5323
|
||||
# endif
|
||||
# else
|
||||
# warning "pkey_mprotect() syscall number unknown for your architecture"
|
||||
# endif
|
||||
|
||||
/* may be (invalid) negative number due to libseccomp, see PR 13319 */
|
||||
# if ! (defined __NR_pkey_mprotect && __NR_pkey_mprotect >= 0)
|
||||
# if defined __NR_pkey_mprotect && __NR_pkey_mprotect >= 0
|
||||
# if defined systemd_NR_pkey_mprotect
|
||||
assert_cc(__NR_pkey_mprotect == systemd_NR_pkey_mprotect);
|
||||
# endif
|
||||
# else
|
||||
# if defined __NR_pkey_mprotect
|
||||
# undef __NR_pkey_mprotect
|
||||
# endif
|
||||
# if defined __i386__
|
||||
# define __NR_pkey_mprotect 380
|
||||
# elif defined __x86_64__
|
||||
# define __NR_pkey_mprotect 329
|
||||
# elif defined __arm__
|
||||
# define __NR_pkey_mprotect 394
|
||||
# elif defined __aarch64__
|
||||
# define __NR_pkey_mprotect 394
|
||||
# elif defined __powerpc__
|
||||
# define __NR_pkey_mprotect 386
|
||||
# elif defined __s390__
|
||||
# define __NR_pkey_mprotect 384
|
||||
# elif defined _MIPS_SIM
|
||||
# if _MIPS_SIM == _MIPS_SIM_ABI32
|
||||
# define __NR_pkey_mprotect 4363
|
||||
# endif
|
||||
# if _MIPS_SIM == _MIPS_SIM_NABI32
|
||||
# define __NR_pkey_mprotect 6327
|
||||
# endif
|
||||
# if _MIPS_SIM == _MIPS_SIM_ABI64
|
||||
# define __NR_pkey_mprotect 5323
|
||||
# endif
|
||||
# else
|
||||
# warning "__NR_pkey_mprotect not defined for your architecture"
|
||||
# if defined systemd_NR_pkey_mprotect
|
||||
# define __NR_pkey_mprotect systemd_NR_pkey_mprotect
|
||||
# endif
|
||||
# endif
|
||||
#endif
|
||||
|
||||
/* ======================================================================= */
|
||||
|
||||
#if !HAVE_STATX
|
||||
#if defined __aarch64__
|
||||
# define systemd_NR_statx 291
|
||||
#elif defined __arm__
|
||||
# define systemd_NR_statx 397
|
||||
#elif defined __alpha__
|
||||
# define systemd_NR_statx 522
|
||||
#elif defined __i386__ || defined __powerpc64__
|
||||
# define systemd_NR_statx 383
|
||||
#elif defined __s390__ || defined __s390x__
|
||||
# define systemd_NR_statx 379
|
||||
#elif defined __sparc__
|
||||
# define systemd_NR_statx 360
|
||||
#elif defined __x86_64__
|
||||
# define systemd_NR_statx 332
|
||||
#else
|
||||
# warning "statx() syscall number unknown for your architecture"
|
||||
#endif
|
||||
|
||||
/* may be (invalid) negative number due to libseccomp, see PR 13319 */
|
||||
# if ! (defined __NR_statx && __NR_statx >= 0)
|
||||
#if defined __NR_statx && __NR_statx >= 0
|
||||
# if defined systemd_NR_statx
|
||||
assert_cc(__NR_statx == systemd_NR_statx);
|
||||
# endif
|
||||
#else
|
||||
# if defined __NR_statx
|
||||
# undef __NR_statx
|
||||
# endif
|
||||
# if defined __aarch64__ || defined __arm__
|
||||
# define __NR_statx 397
|
||||
# elif defined __alpha__
|
||||
# define __NR_statx 522
|
||||
# elif defined __i386__ || defined __powerpc64__
|
||||
# define __NR_statx 383
|
||||
# elif defined __sparc__
|
||||
# define __NR_statx 360
|
||||
# elif defined __x86_64__
|
||||
# define __NR_statx 332
|
||||
# else
|
||||
# warning "__NR_statx not defined for your architecture"
|
||||
# if defined systemd_NR_statx
|
||||
# define __NR_statx systemd_NR_statx
|
||||
# endif
|
||||
# endif
|
||||
|
||||
struct statx;
|
||||
#endif
|
||||
|
||||
/* This typedef is supposed to be always defined. */
|
||||
typedef struct statx struct_statx;
|
||||
|
||||
#if !HAVE_STATX
|
||||
struct statx;
|
||||
|
||||
static inline ssize_t missing_statx(int dfd, const char *filename, unsigned flags, unsigned int mask, struct statx *buffer) {
|
||||
# ifdef __NR_statx
|
||||
return syscall(__NR_statx, dfd, filename, flags, mask, buffer);
|
||||
@@ -483,12 +575,18 @@ static inline ssize_t missing_statx(int dfd, const char *filename, unsigned flag
|
||||
return -1;
|
||||
# endif
|
||||
}
|
||||
|
||||
# define statx missing_statx
|
||||
#endif
|
||||
|
||||
#if !HAVE_SET_MEMPOLICY
|
||||
/* This typedef is supposed to be always defined. */
|
||||
typedef struct statx struct_statx;
|
||||
|
||||
#if !HAVE_STATX
|
||||
# define statx(dfd, filename, flags, mask, buffer) missing_statx(dfd, filename, flags, mask, buffer)
|
||||
#endif
|
||||
|
||||
/* ======================================================================= */
|
||||
|
||||
#if !HAVE_SET_MEMPOLICY
|
||||
enum {
|
||||
MPOL_DEFAULT,
|
||||
MPOL_PREFERRED,
|
||||
@@ -517,7 +615,7 @@ static inline long missing_get_mempolicy(int *mode, unsigned long *nodemask,
|
||||
unsigned long maxnode, void *addr,
|
||||
unsigned long flags) {
|
||||
long i;
|
||||
# ifdef __NR_get_mempolicy
|
||||
# if defined __NR_get_mempolicy && __NR_get_mempolicy >= 0
|
||||
i = syscall(__NR_get_mempolicy, mode, nodemask, maxnode, addr, flags);
|
||||
# else
|
||||
errno = ENOSYS;
|
||||
@@ -526,49 +624,87 @@ static inline long missing_get_mempolicy(int *mode, unsigned long *nodemask,
|
||||
return i;
|
||||
}
|
||||
|
||||
#define get_mempolicy missing_get_mempolicy
|
||||
# define get_mempolicy missing_get_mempolicy
|
||||
#endif
|
||||
|
||||
#endif /* NM_IGNORED */
|
||||
|
||||
#if !HAVE_PIDFD_OPEN
|
||||
/* may be (invalid) negative number due to libseccomp, see PR 13319 */
|
||||
# if ! (defined __NR_pidfd_open && __NR_pidfd_open >= 0)
|
||||
# if defined __NR_pidfd_open
|
||||
# undef __NR_pidfd_open
|
||||
# endif
|
||||
# define __NR_pidfd_open 434
|
||||
#endif
|
||||
static inline int pidfd_open(pid_t pid, unsigned flags) {
|
||||
#ifdef __NR_pidfd_open
|
||||
return syscall(__NR_pidfd_open, pid, flags);
|
||||
/* ======================================================================= */
|
||||
|
||||
/* should be always defined, see kernel 39036cd2727395c3369b1051005da74059a85317 */
|
||||
#if defined(__alpha__)
|
||||
# define systemd_NR_pidfd_send_signal 534
|
||||
#else
|
||||
errno = ENOSYS;
|
||||
return -1;
|
||||
#endif
|
||||
}
|
||||
# define systemd_NR_pidfd_send_signal 424
|
||||
#endif
|
||||
|
||||
#if !HAVE_PIDFD_SEND_SIGNAL
|
||||
/* may be (invalid) negative number due to libseccomp, see PR 13319 */
|
||||
# if ! (defined __NR_pidfd_send_signal && __NR_pidfd_send_signal >= 0)
|
||||
#if defined __NR_pidfd_send_signal && __NR_pidfd_send_signal >= 0
|
||||
# if defined systemd_NR_pidfd_send_signal
|
||||
assert_cc(__NR_pidfd_send_signal == systemd_NR_pidfd_send_signal);
|
||||
# endif
|
||||
#else
|
||||
# if defined __NR_pidfd_send_signal
|
||||
# undef __NR_pidfd_send_signal
|
||||
# endif
|
||||
# define __NR_pidfd_send_signal 424
|
||||
#endif
|
||||
static inline int pidfd_send_signal(int fd, int sig, siginfo_t *info, unsigned flags) {
|
||||
#ifdef __NR_pidfd_open
|
||||
return syscall(__NR_pidfd_send_signal, fd, sig, info, flags);
|
||||
#else
|
||||
errno = ENOSYS;
|
||||
return -1;
|
||||
#endif
|
||||
}
|
||||
# define __NR_pidfd_send_signal systemd_NR_pidfd_send_signal
|
||||
#endif
|
||||
|
||||
#if !HAVE_RT_SIGQUEUEINFO
|
||||
static inline int rt_sigqueueinfo(pid_t tgid, int sig, siginfo_t *info) {
|
||||
return syscall(__NR_rt_sigqueueinfo, tgid, sig, info);
|
||||
#if !HAVE_PIDFD_SEND_SIGNAL
|
||||
static inline int missing_pidfd_send_signal(int fd, int sig, siginfo_t *info, unsigned flags) {
|
||||
# ifdef __NR_pidfd_open
|
||||
return syscall(__NR_pidfd_send_signal, fd, sig, info, flags);
|
||||
# else
|
||||
errno = ENOSYS;
|
||||
return -1;
|
||||
# endif
|
||||
}
|
||||
|
||||
# define pidfd_send_signal missing_pidfd_send_signal
|
||||
#endif
|
||||
|
||||
/* should be always defined, see kernel 7615d9e1780e26e0178c93c55b73309a5dc093d7 */
|
||||
#if defined(__alpha__)
|
||||
# define systemd_NR_pidfd_open 544
|
||||
#else
|
||||
# define systemd_NR_pidfd_open 434
|
||||
#endif
|
||||
|
||||
/* may be (invalid) negative number due to libseccomp, see PR 13319 */
|
||||
#if defined __NR_pidfd_open && __NR_pidfd_open >= 0
|
||||
# if defined systemd_NR_pidfd_open
|
||||
assert_cc(__NR_pidfd_open == systemd_NR_pidfd_open);
|
||||
# endif
|
||||
#else
|
||||
# if defined __NR_pidfd_open
|
||||
# undef __NR_pidfd_open
|
||||
# endif
|
||||
# define __NR_pidfd_open systemd_NR_pidfd_open
|
||||
#endif
|
||||
|
||||
#if !HAVE_PIDFD_OPEN
|
||||
static inline int missing_pidfd_open(pid_t pid, unsigned flags) {
|
||||
# ifdef __NR_pidfd_open
|
||||
return syscall(__NR_pidfd_open, pid, flags);
|
||||
# else
|
||||
errno = ENOSYS;
|
||||
return -1;
|
||||
# endif
|
||||
}
|
||||
|
||||
# define pidfd_open missing_pidfd_open
|
||||
#endif
|
||||
|
||||
/* ======================================================================= */
|
||||
|
||||
#if !HAVE_RT_SIGQUEUEINFO
|
||||
static inline int missing_rt_sigqueueinfo(pid_t tgid, int sig, siginfo_t *info) {
|
||||
# if defined __NR_rt_sigqueueinfo && __NR_rt_sigqueueinfo >= 0
|
||||
return syscall(__NR_rt_sigqueueinfo, tgid, sig, info);
|
||||
# else
|
||||
# error "__NR_rt_sigqueueinfo not defined"
|
||||
# endif
|
||||
}
|
||||
|
||||
# define rt_sigqueueinfo missing_rt_sigqueueinfo
|
||||
#endif
|
||||
|
@@ -18,6 +18,9 @@
|
||||
#include "missing_network.h"
|
||||
#include "parse-util.h"
|
||||
#include "process-util.h"
|
||||
#if HAVE_SECCOMP
|
||||
#include "seccomp-util.h"
|
||||
#endif
|
||||
#include "stat-util.h"
|
||||
#include "string-util.h"
|
||||
#include "strv.h"
|
||||
@@ -317,6 +320,7 @@ int parse_errno(const char *t) {
|
||||
return e;
|
||||
}
|
||||
|
||||
#if HAVE_SECCOMP
|
||||
int parse_syscall_and_errno(const char *in, char **name, int *error) {
|
||||
_cleanup_free_ char *n = NULL;
|
||||
char *p;
|
||||
@@ -335,7 +339,7 @@ int parse_syscall_and_errno(const char *in, char **name, int *error) {
|
||||
|
||||
p = strchr(in, ':');
|
||||
if (p) {
|
||||
e = parse_errno(p + 1);
|
||||
e = seccomp_parse_errno_or_action(p + 1);
|
||||
if (e < 0)
|
||||
return e;
|
||||
|
||||
@@ -354,6 +358,7 @@ int parse_syscall_and_errno(const char *in, char **name, int *error) {
|
||||
|
||||
return 0;
|
||||
}
|
||||
#endif
|
||||
#endif /* NM_IGNORED */
|
||||
|
||||
static const char *mangle_base(const char *s, unsigned *base) {
|
||||
|
@@ -19,7 +19,9 @@ int parse_mtu(int family, const char *s, uint32_t *ret);
|
||||
int parse_size(const char *t, uint64_t base, uint64_t *size);
|
||||
int parse_range(const char *t, unsigned *lower, unsigned *upper);
|
||||
int parse_errno(const char *t);
|
||||
#if HAVE_SECCOMP
|
||||
int parse_syscall_and_errno(const char *in, char **name, int *error);
|
||||
#endif
|
||||
|
||||
#define SAFE_ATO_REFUSE_PLUS_MINUS (1U << 30)
|
||||
#define SAFE_ATO_REFUSE_LEADING_ZERO (1U << 29)
|
||||
|
@@ -16,6 +16,7 @@
|
||||
|
||||
#include "alloc-util.h"
|
||||
#include "extract-word.h"
|
||||
#include "fd-util.h"
|
||||
#include "fs-util.h"
|
||||
#include "glob-util.h"
|
||||
#include "log.h"
|
||||
@@ -29,15 +30,7 @@
|
||||
#include "time-util.h"
|
||||
#include "utf8.h"
|
||||
|
||||
bool path_is_absolute(const char *p) {
|
||||
return p[0] == '/';
|
||||
}
|
||||
|
||||
#if 0 /* NM_IGNORED */
|
||||
bool is_path(const char *p) {
|
||||
return !!strchr(p, '/');
|
||||
}
|
||||
|
||||
int path_split_and_make_absolute(const char *p, char ***ret) {
|
||||
char **l;
|
||||
int r;
|
||||
@@ -601,9 +594,9 @@ char* path_join_internal(const char *first, ...) {
|
||||
}
|
||||
|
||||
#if 0 /* NM_IGNORED */
|
||||
int find_binary(const char *name, char **ret) {
|
||||
int find_executable_full(const char *name, bool use_path_envvar, char **ret) {
|
||||
int last_error, r;
|
||||
const char *p;
|
||||
const char *p = NULL;
|
||||
|
||||
assert(name);
|
||||
|
||||
@@ -620,10 +613,9 @@ int find_binary(const char *name, char **ret) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
/**
|
||||
* Plain getenv, not secure_getenv, because we want
|
||||
* to actually allow the user to pick the binary.
|
||||
*/
|
||||
if (use_path_envvar)
|
||||
/* Plain getenv, not secure_getenv, because we want to actually allow the user to pick the
|
||||
* binary. */
|
||||
p = getenv("PATH");
|
||||
if (!p)
|
||||
p = DEFAULT_PATH;
|
||||
@@ -647,13 +639,25 @@ int find_binary(const char *name, char **ret) {
|
||||
return -ENOMEM;
|
||||
|
||||
if (access(j, X_OK) >= 0) {
|
||||
/* Found it! */
|
||||
_cleanup_free_ char *with_dash;
|
||||
|
||||
with_dash = strjoin(j, "/");
|
||||
if (!with_dash)
|
||||
return -ENOMEM;
|
||||
|
||||
/* If this passes, it must be a directory, and so should be skipped. */
|
||||
if (access(with_dash, X_OK) >= 0)
|
||||
continue;
|
||||
|
||||
/* We can't just `continue` inverting this case, since we need to update last_error. */
|
||||
if (errno == ENOTDIR) {
|
||||
/* Found it! */
|
||||
if (ret)
|
||||
*ret = path_simplify(TAKE_PTR(j), false);
|
||||
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
|
||||
/* PATH entries which we don't have access to are ignored, as per tradition. */
|
||||
if (errno != EACCES)
|
||||
@@ -698,18 +702,17 @@ bool paths_check_timestamp(const char* const* paths, usec_t *timestamp, bool upd
|
||||
return changed;
|
||||
}
|
||||
|
||||
static int binary_is_good(const char *binary) {
|
||||
static int executable_is_good(const char *executable) {
|
||||
_cleanup_free_ char *p = NULL, *d = NULL;
|
||||
int r;
|
||||
|
||||
r = find_binary(binary, &p);
|
||||
r = find_executable(executable, &p);
|
||||
if (r == -ENOENT)
|
||||
return 0;
|
||||
if (r < 0)
|
||||
return r;
|
||||
|
||||
/* An fsck that is linked to /bin/true is a non-existent
|
||||
* fsck */
|
||||
/* An fsck that is linked to /bin/true is a non-existent fsck */
|
||||
|
||||
r = readlink_malloc(p, &d);
|
||||
if (r == -EINVAL) /* not a symlink */
|
||||
@@ -732,19 +735,7 @@ int fsck_exists(const char *fstype) {
|
||||
return -EINVAL;
|
||||
|
||||
checker = strjoina("fsck.", fstype);
|
||||
return binary_is_good(checker);
|
||||
}
|
||||
|
||||
int mkfs_exists(const char *fstype) {
|
||||
const char *mkfs;
|
||||
|
||||
assert(fstype);
|
||||
|
||||
if (streq(fstype, "auto"))
|
||||
return -EINVAL;
|
||||
|
||||
mkfs = strjoina("mkfs.", fstype);
|
||||
return binary_is_good(mkfs);
|
||||
return executable_is_good(checker);
|
||||
}
|
||||
|
||||
int parse_path_argument_and_warn(const char *path, bool suppress_root, char **arg) {
|
||||
@@ -1152,4 +1143,10 @@ bool prefixed_path_strv_contains(char **l, const char *path) {
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
bool credential_name_valid(const char *s) {
|
||||
/* We want that credential names are both valid in filenames (since that's our primary way to pass
|
||||
* them around) and as fdnames (which is how we might want to pass them around eventually) */
|
||||
return filename_is_valid(s) && fdname_is_valid(s);
|
||||
}
|
||||
#endif /* NM_IGNORED */
|
||||
|
@@ -44,9 +44,17 @@
|
||||
# define DEFAULT_USER_PATH DEFAULT_PATH
|
||||
#endif
|
||||
|
||||
bool is_path(const char *p) _pure_;
|
||||
static inline bool is_path(const char *p) {
|
||||
assert(p);
|
||||
return strchr(p, '/');
|
||||
}
|
||||
|
||||
static inline bool path_is_absolute(const char *p) {
|
||||
assert(p);
|
||||
return p[0] == '/';
|
||||
}
|
||||
|
||||
int path_split_and_make_absolute(const char *p, char ***ret);
|
||||
bool path_is_absolute(const char *p) _pure_;
|
||||
char* path_make_absolute(const char *p, const char *prefix);
|
||||
int safe_getcwd(char **ret);
|
||||
int path_make_absolute_cwd(const char *p, char **ret);
|
||||
@@ -82,12 +90,14 @@ int path_strv_make_absolute_cwd(char **l);
|
||||
char** path_strv_resolve(char **l, const char *root);
|
||||
char** path_strv_resolve_uniq(char **l, const char *root);
|
||||
|
||||
int find_binary(const char *name, char **filename);
|
||||
int find_executable_full(const char *name, bool use_path_envvar, char **ret);
|
||||
static inline int find_executable(const char *name, char **ret) {
|
||||
return find_executable_full(name, true, ret);
|
||||
}
|
||||
|
||||
bool paths_check_timestamp(const char* const* paths, usec_t *paths_ts_usec, bool update);
|
||||
|
||||
int fsck_exists(const char *fstype);
|
||||
int mkfs_exists(const char *fstype);
|
||||
|
||||
/* Iterates through the path prefixes of the specified path, going up
|
||||
* the tree, to root. Also returns "" (and not "/"!) for the root
|
||||
@@ -176,3 +186,5 @@ static inline const char *empty_to_root(const char *path) {
|
||||
|
||||
bool path_strv_contains(char **l, const char *path);
|
||||
bool prefixed_path_strv_contains(char **l, const char *path);
|
||||
|
||||
bool credential_name_valid(const char *s);
|
||||
|
@@ -23,6 +23,7 @@
|
||||
#endif
|
||||
|
||||
#include "alloc-util.h"
|
||||
#include "env-util.h"
|
||||
#include "errno-util.h"
|
||||
#include "fd-util.h"
|
||||
#include "fileio.h"
|
||||
@@ -118,6 +119,15 @@ int rdrand(unsigned long *ret) {
|
||||
#endif
|
||||
|
||||
have_rdrand = !!(ecx & bit_RDRND);
|
||||
|
||||
if (have_rdrand > 0) {
|
||||
/* Allow disabling use of RDRAND with SYSTEMD_RDRAND=0
|
||||
If it is unset getenv_bool_secure will return a negative value. */
|
||||
if (getenv_bool_secure("SYSTEMD_RDRAND") == 0) {
|
||||
have_rdrand = false;
|
||||
return -EOPNOTSUPP;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (have_rdrand == 0)
|
||||
|
@@ -13,14 +13,14 @@
|
||||
0; \
|
||||
})
|
||||
|
||||
Set *_set_new(const struct hash_ops *hash_ops HASHMAP_DEBUG_PARAMS);
|
||||
Set* _set_new(const struct hash_ops *hash_ops HASHMAP_DEBUG_PARAMS);
|
||||
#define set_new(ops) _set_new(ops HASHMAP_DEBUG_SRC_ARGS)
|
||||
|
||||
static inline Set *set_free(Set *s) {
|
||||
static inline Set* set_free(Set *s) {
|
||||
return (Set*) _hashmap_free(HASHMAP_BASE(s), NULL, NULL);
|
||||
}
|
||||
|
||||
static inline Set *set_free_free(Set *s) {
|
||||
static inline Set* set_free_free(Set *s) {
|
||||
return (Set*) _hashmap_free(HASHMAP_BASE(s), free, NULL);
|
||||
}
|
||||
|
||||
@@ -34,7 +34,7 @@ int _set_ensure_allocated(Set **s, const struct hash_ops *hash_ops HASHMAP_DEBUG
|
||||
int set_put(Set *s, const void *key);
|
||||
/* no set_update */
|
||||
/* no set_replace */
|
||||
static inline void *set_get(const Set *s, void *key) {
|
||||
static inline void *set_get(const Set *s, const void *key) {
|
||||
return _hashmap_get(HASHMAP_BASE((Set *) s), key);
|
||||
}
|
||||
/* no set_get2 */
|
||||
@@ -77,7 +77,9 @@ static inline unsigned set_buckets(const Set *s) {
|
||||
return _hashmap_buckets(HASHMAP_BASE((Set *) s));
|
||||
}
|
||||
|
||||
bool set_iterate(const Set *s, Iterator *i, void **value);
|
||||
static inline bool set_iterate(const Set *s, Iterator *i, void **value) {
|
||||
return _hashmap_iterate(HASHMAP_BASE((Set*) s), i, value, NULL);
|
||||
}
|
||||
|
||||
static inline void set_clear(Set *s) {
|
||||
_hashmap_clear(HASHMAP_BASE(s), NULL, NULL);
|
||||
@@ -133,8 +135,10 @@ int _set_put_strdupv(Set **s, char **l HASHMAP_DEBUG_PARAMS);
|
||||
|
||||
int set_put_strsplit(Set *s, const char *v, const char *separators, ExtractFlags flags);
|
||||
|
||||
#define SET_FOREACH(e, s, i) \
|
||||
for ((i) = ITERATOR_FIRST; set_iterate((s), &(i), (void**)&(e)); )
|
||||
#define _SET_FOREACH(e, s, i) \
|
||||
for (Iterator i = ITERATOR_FIRST; set_iterate((s), &i, (void**)&(e)); )
|
||||
#define SET_FOREACH(e, s) \
|
||||
_SET_FOREACH(e, s, UNIQ_T(i, UNIQ))
|
||||
|
||||
#define SET_FOREACH_MOVE(e, d, s) \
|
||||
for (; ({ e = set_first(s); assert_se(!e || set_move_one(d, s, e) >= 0); e; }); )
|
||||
|
@@ -6,6 +6,8 @@
|
||||
#include <string.h>
|
||||
#include <sys/types.h>
|
||||
|
||||
#include "time-util.h"
|
||||
|
||||
#if 0 /* NM_IGNORED */
|
||||
struct siphash {
|
||||
uint64_t v0;
|
||||
@@ -55,6 +57,10 @@ static inline void siphash24_compress_boolean(bool in, struct siphash *state) {
|
||||
siphash24_compress(&i, sizeof i, state);
|
||||
}
|
||||
|
||||
static inline void siphash24_compress_usec_t(usec_t in, struct siphash *state) {
|
||||
siphash24_compress(&in, sizeof in, state);
|
||||
}
|
||||
|
||||
static inline void siphash24_compress_string(const char *in, struct siphash *state) {
|
||||
if (!in)
|
||||
return;
|
||||
|
@@ -30,6 +30,7 @@
|
||||
#include "macro.h"
|
||||
#include "memory-util.h"
|
||||
#include "missing_socket.h"
|
||||
#include "missing_network.h"
|
||||
#include "parse-util.h"
|
||||
#include "path-util.h"
|
||||
#include "process-util.h"
|
||||
@@ -73,7 +74,7 @@ int socket_address_verify(const SocketAddress *a, bool strict) {
|
||||
if (a->sockaddr.in.sin_port == 0)
|
||||
return -EINVAL;
|
||||
|
||||
if (!IN_SET(a->type, SOCK_STREAM, SOCK_DGRAM))
|
||||
if (!IN_SET(a->type, 0, SOCK_STREAM, SOCK_DGRAM))
|
||||
return -EINVAL;
|
||||
|
||||
return 0;
|
||||
@@ -85,7 +86,7 @@ int socket_address_verify(const SocketAddress *a, bool strict) {
|
||||
if (a->sockaddr.in6.sin6_port == 0)
|
||||
return -EINVAL;
|
||||
|
||||
if (!IN_SET(a->type, SOCK_STREAM, SOCK_DGRAM))
|
||||
if (!IN_SET(a->type, 0, SOCK_STREAM, SOCK_DGRAM))
|
||||
return -EINVAL;
|
||||
|
||||
return 0;
|
||||
@@ -119,7 +120,7 @@ int socket_address_verify(const SocketAddress *a, bool strict) {
|
||||
}
|
||||
}
|
||||
|
||||
if (!IN_SET(a->type, SOCK_STREAM, SOCK_DGRAM, SOCK_SEQPACKET))
|
||||
if (!IN_SET(a->type, 0, SOCK_STREAM, SOCK_DGRAM, SOCK_SEQPACKET))
|
||||
return -EINVAL;
|
||||
|
||||
return 0;
|
||||
@@ -129,7 +130,7 @@ int socket_address_verify(const SocketAddress *a, bool strict) {
|
||||
if (a->size != sizeof(struct sockaddr_nl))
|
||||
return -EINVAL;
|
||||
|
||||
if (!IN_SET(a->type, SOCK_RAW, SOCK_DGRAM))
|
||||
if (!IN_SET(a->type, 0, SOCK_RAW, SOCK_DGRAM))
|
||||
return -EINVAL;
|
||||
|
||||
return 0;
|
||||
@@ -138,7 +139,7 @@ int socket_address_verify(const SocketAddress *a, bool strict) {
|
||||
if (a->size != sizeof(struct sockaddr_vm))
|
||||
return -EINVAL;
|
||||
|
||||
if (!IN_SET(a->type, SOCK_STREAM, SOCK_DGRAM))
|
||||
if (!IN_SET(a->type, 0, SOCK_STREAM, SOCK_DGRAM))
|
||||
return -EINVAL;
|
||||
|
||||
return 0;
|
||||
@@ -404,19 +405,23 @@ int sockaddr_pretty(
|
||||
if (r < 0)
|
||||
return -ENOMEM;
|
||||
} else {
|
||||
char a[INET6_ADDRSTRLEN];
|
||||
char a[INET6_ADDRSTRLEN], ifname[IF_NAMESIZE + 1];
|
||||
|
||||
inet_ntop(AF_INET6, &sa->in6.sin6_addr, a, sizeof(a));
|
||||
if (sa->in6.sin6_scope_id != 0)
|
||||
format_ifname_full(sa->in6.sin6_scope_id, ifname, FORMAT_IFNAME_IFINDEX);
|
||||
|
||||
if (include_port) {
|
||||
r = asprintf(&p,
|
||||
"[%s]:%u",
|
||||
"[%s]:%u%s%s",
|
||||
a,
|
||||
be16toh(sa->in6.sin6_port));
|
||||
be16toh(sa->in6.sin6_port),
|
||||
sa->in6.sin6_scope_id != 0 ? "%" : "",
|
||||
sa->in6.sin6_scope_id != 0 ? ifname : "");
|
||||
if (r < 0)
|
||||
return -ENOMEM;
|
||||
} else {
|
||||
p = strdup(a);
|
||||
p = sa->in6.sin6_scope_id != 0 ? strjoin(a, "%", ifname) : strdup(a);
|
||||
if (!p)
|
||||
return -ENOMEM;
|
||||
}
|
||||
@@ -622,40 +627,64 @@ bool sockaddr_equal(const union sockaddr_union *a, const union sockaddr_union *b
|
||||
return false;
|
||||
}
|
||||
|
||||
int fd_inc_sndbuf(int fd, size_t n) {
|
||||
int fd_set_sndbuf(int fd, size_t n, bool increase) {
|
||||
int r, value;
|
||||
socklen_t l = sizeof(value);
|
||||
|
||||
if (n > INT_MAX)
|
||||
return -ERANGE;
|
||||
|
||||
r = getsockopt(fd, SOL_SOCKET, SO_SNDBUF, &value, &l);
|
||||
if (r >= 0 && l == sizeof(value) && (size_t) value >= n*2)
|
||||
if (r >= 0 && l == sizeof(value) && increase ? (size_t) value >= n*2 : (size_t) value == n*2)
|
||||
return 0;
|
||||
|
||||
/* If we have the privileges we will ignore the kernel limit. */
|
||||
/* First, try to set the buffer size with SO_SNDBUF. */
|
||||
r = setsockopt_int(fd, SOL_SOCKET, SO_SNDBUF, n);
|
||||
if (r < 0)
|
||||
return r;
|
||||
|
||||
if (setsockopt_int(fd, SOL_SOCKET, SO_SNDBUF, n) < 0) {
|
||||
/* SO_SNDBUF above may set to the kernel limit, instead of the requested size.
|
||||
* So, we need to check the actual buffer size here. */
|
||||
l = sizeof(value);
|
||||
r = getsockopt(fd, SOL_SOCKET, SO_SNDBUF, &value, &l);
|
||||
if (r >= 0 && l == sizeof(value) && increase ? (size_t) value >= n*2 : (size_t) value == n*2)
|
||||
return 1;
|
||||
|
||||
/* If we have the privileges we will ignore the kernel limit. */
|
||||
r = setsockopt_int(fd, SOL_SOCKET, SO_SNDBUFFORCE, n);
|
||||
if (r < 0)
|
||||
return r;
|
||||
}
|
||||
|
||||
return 1;
|
||||
}
|
||||
|
||||
int fd_inc_rcvbuf(int fd, size_t n) {
|
||||
int fd_set_rcvbuf(int fd, size_t n, bool increase) {
|
||||
int r, value;
|
||||
socklen_t l = sizeof(value);
|
||||
|
||||
if (n > INT_MAX)
|
||||
return -ERANGE;
|
||||
|
||||
r = getsockopt(fd, SOL_SOCKET, SO_RCVBUF, &value, &l);
|
||||
if (r >= 0 && l == sizeof(value) && (size_t) value >= n*2)
|
||||
if (r >= 0 && l == sizeof(value) && increase ? (size_t) value >= n*2 : (size_t) value == n*2)
|
||||
return 0;
|
||||
|
||||
/* If we have the privileges we will ignore the kernel limit. */
|
||||
/* First, try to set the buffer size with SO_RCVBUF. */
|
||||
r = setsockopt_int(fd, SOL_SOCKET, SO_RCVBUF, n);
|
||||
if (r < 0)
|
||||
return r;
|
||||
|
||||
if (setsockopt_int(fd, SOL_SOCKET, SO_RCVBUF, n) < 0) {
|
||||
/* SO_RCVBUF above may set to the kernel limit, instead of the requested size.
|
||||
* So, we need to check the actual buffer size here. */
|
||||
l = sizeof(value);
|
||||
r = getsockopt(fd, SOL_SOCKET, SO_RCVBUF, &value, &l);
|
||||
if (r >= 0 && l == sizeof(value) && increase ? (size_t) value >= n*2 : (size_t) value == n*2)
|
||||
return 1;
|
||||
|
||||
/* If we have the privileges we will ignore the kernel limit. */
|
||||
r = setsockopt_int(fd, SOL_SOCKET, SO_RCVBUFFORCE, n);
|
||||
if (r < 0)
|
||||
return r;
|
||||
}
|
||||
|
||||
return 1;
|
||||
}
|
||||
@@ -669,17 +698,19 @@ static const char* const ip_tos_table[] = {
|
||||
|
||||
DEFINE_STRING_TABLE_LOOKUP_WITH_FALLBACK(ip_tos, int, 0xff);
|
||||
|
||||
bool ifname_valid_full(const char *p, bool alternative) {
|
||||
bool ifname_valid_full(const char *p, IfnameValidFlags flags) {
|
||||
bool numeric = true;
|
||||
|
||||
/* Checks whether a network interface name is valid. This is inspired by dev_valid_name() in the kernel sources
|
||||
* but slightly stricter, as we only allow non-control, non-space ASCII characters in the interface name. We
|
||||
* also don't permit names that only container numbers, to avoid confusion with numeric interface indexes. */
|
||||
|
||||
assert(!(flags & ~_IFNAME_VALID_ALL));
|
||||
|
||||
if (isempty(p))
|
||||
return false;
|
||||
|
||||
if (alternative) {
|
||||
if (flags & IFNAME_VALID_ALTERNATIVE) {
|
||||
if (strlen(p) >= ALTIFNAMSIZ)
|
||||
return false;
|
||||
} else {
|
||||
@@ -690,23 +721,28 @@ bool ifname_valid_full(const char *p, bool alternative) {
|
||||
if (dot_or_dot_dot(p))
|
||||
return false;
|
||||
|
||||
while (*p) {
|
||||
if ((unsigned char) *p >= 127U)
|
||||
for (const char *t = p; *t; t++) {
|
||||
if ((unsigned char) *t >= 127U)
|
||||
return false;
|
||||
|
||||
if ((unsigned char) *p <= 32U)
|
||||
if ((unsigned char) *t <= 32U)
|
||||
return false;
|
||||
|
||||
if (IN_SET(*p, ':', '/'))
|
||||
if (IN_SET(*t, ':', '/'))
|
||||
return false;
|
||||
|
||||
numeric = numeric && (*p >= '0' && *p <= '9');
|
||||
p++;
|
||||
numeric = numeric && (*t >= '0' && *t <= '9');
|
||||
}
|
||||
|
||||
if (numeric)
|
||||
if (numeric) {
|
||||
if (!(flags & IFNAME_VALID_NUMERIC))
|
||||
return false;
|
||||
|
||||
/* Verify that the number is well-formatted and in range. */
|
||||
if (parse_ifindex(p) < 0)
|
||||
return false;
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
@@ -1095,12 +1131,10 @@ int sockaddr_un_set_path(struct sockaddr_un *ret, const char *path) {
|
||||
* reference paths in the abstract namespace that include NUL bytes in the name. */
|
||||
|
||||
l = strlen(path);
|
||||
if (l == 0)
|
||||
if (l < 2)
|
||||
return -EINVAL;
|
||||
if (!IN_SET(path[0], '/', '@'))
|
||||
return -EINVAL;
|
||||
if (path[1] == 0)
|
||||
return -EINVAL;
|
||||
|
||||
/* Don't allow paths larger than the space in sockaddr_un. Note that we are a tiny bit more restrictive than
|
||||
* the kernel is: we insist on NUL termination (both for abstract namespace and regular file system socket
|
||||
@@ -1183,13 +1217,28 @@ ssize_t recvmsg_safe(int sockfd, struct msghdr *msg, int flags) {
|
||||
return n;
|
||||
}
|
||||
|
||||
int socket_pass_pktinfo(int fd, bool b) {
|
||||
int socket_get_family(int fd, int *ret) {
|
||||
int af;
|
||||
socklen_t sl = sizeof(af);
|
||||
|
||||
if (getsockopt(fd, SOL_SOCKET, SO_DOMAIN, &af, &sl) < 0)
|
||||
return -errno;
|
||||
|
||||
if (sl != sizeof(af))
|
||||
return -EINVAL;
|
||||
|
||||
return af;
|
||||
}
|
||||
|
||||
int socket_set_recvpktinfo(int fd, int af, bool b) {
|
||||
int r;
|
||||
|
||||
if (af == AF_UNSPEC) {
|
||||
r = socket_get_family(fd, &af);
|
||||
if (r < 0)
|
||||
return r;
|
||||
}
|
||||
|
||||
switch (af) {
|
||||
|
||||
case AF_INET:
|
||||
@@ -1205,3 +1254,142 @@ int socket_pass_pktinfo(int fd, bool b) {
|
||||
return -EAFNOSUPPORT;
|
||||
}
|
||||
}
|
||||
|
||||
int socket_set_recverr(int fd, int af, bool b) {
|
||||
int r;
|
||||
|
||||
if (af == AF_UNSPEC) {
|
||||
r = socket_get_family(fd, &af);
|
||||
if (r < 0)
|
||||
return r;
|
||||
}
|
||||
|
||||
switch (af) {
|
||||
|
||||
case AF_INET:
|
||||
return setsockopt_int(fd, IPPROTO_IP, IP_RECVERR, b);
|
||||
|
||||
case AF_INET6:
|
||||
return setsockopt_int(fd, IPPROTO_IPV6, IPV6_RECVERR, b);
|
||||
|
||||
default:
|
||||
return -EAFNOSUPPORT;
|
||||
}
|
||||
}
|
||||
|
||||
int socket_set_recvttl(int fd, int af, bool b) {
|
||||
int r;
|
||||
|
||||
if (af == AF_UNSPEC) {
|
||||
r = socket_get_family(fd, &af);
|
||||
if (r < 0)
|
||||
return r;
|
||||
}
|
||||
|
||||
switch (af) {
|
||||
|
||||
case AF_INET:
|
||||
return setsockopt_int(fd, IPPROTO_IP, IP_RECVTTL, b);
|
||||
|
||||
case AF_INET6:
|
||||
return setsockopt_int(fd, IPPROTO_IPV6, IPV6_RECVHOPLIMIT, b);
|
||||
|
||||
default:
|
||||
return -EAFNOSUPPORT;
|
||||
}
|
||||
}
|
||||
|
||||
int socket_set_ttl(int fd, int af, int ttl) {
|
||||
int r;
|
||||
|
||||
if (af == AF_UNSPEC) {
|
||||
r = socket_get_family(fd, &af);
|
||||
if (r < 0)
|
||||
return r;
|
||||
}
|
||||
|
||||
switch (af) {
|
||||
|
||||
case AF_INET:
|
||||
return setsockopt_int(fd, IPPROTO_IP, IP_TTL, ttl);
|
||||
|
||||
case AF_INET6:
|
||||
return setsockopt_int(fd, IPPROTO_IPV6, IPV6_UNICAST_HOPS, ttl);
|
||||
|
||||
default:
|
||||
return -EAFNOSUPPORT;
|
||||
}
|
||||
}
|
||||
|
||||
int socket_set_unicast_if(int fd, int af, int ifi) {
|
||||
be32_t ifindex_be = htobe32(ifi);
|
||||
int r;
|
||||
|
||||
if (af == AF_UNSPEC) {
|
||||
r = socket_get_family(fd, &af);
|
||||
if (r < 0)
|
||||
return r;
|
||||
}
|
||||
|
||||
switch (af) {
|
||||
|
||||
case AF_INET:
|
||||
if (setsockopt(fd, IPPROTO_IP, IP_UNICAST_IF, &ifindex_be, sizeof(ifindex_be)) < 0)
|
||||
return -errno;
|
||||
|
||||
return 0;
|
||||
|
||||
case AF_INET6:
|
||||
if (setsockopt(fd, IPPROTO_IPV6, IPV6_UNICAST_IF, &ifindex_be, sizeof(ifindex_be)) < 0)
|
||||
return -errno;
|
||||
|
||||
return 0;
|
||||
|
||||
default:
|
||||
return -EAFNOSUPPORT;
|
||||
}
|
||||
}
|
||||
|
||||
int socket_set_freebind(int fd, int af, bool b) {
|
||||
int r;
|
||||
|
||||
if (af == AF_UNSPEC) {
|
||||
r = socket_get_family(fd, &af);
|
||||
if (r < 0)
|
||||
return r;
|
||||
}
|
||||
|
||||
switch (af) {
|
||||
|
||||
case AF_INET:
|
||||
return setsockopt_int(fd, IPPROTO_IP, IP_FREEBIND, b);
|
||||
|
||||
case AF_INET6:
|
||||
return setsockopt_int(fd, IPPROTO_IPV6, IPV6_FREEBIND, b);
|
||||
|
||||
default:
|
||||
return -EAFNOSUPPORT;
|
||||
}
|
||||
}
|
||||
|
||||
int socket_set_transparent(int fd, int af, bool b) {
|
||||
int r;
|
||||
|
||||
if (af == AF_UNSPEC) {
|
||||
r = socket_get_family(fd, &af);
|
||||
if (r < 0)
|
||||
return r;
|
||||
}
|
||||
|
||||
switch (af) {
|
||||
|
||||
case AF_INET:
|
||||
return setsockopt_int(fd, IPPROTO_IP, IP_TRANSPARENT, b);
|
||||
|
||||
case AF_INET6:
|
||||
return setsockopt_int(fd, IPPROTO_IPV6, IPV6_TRANSPARENT, b);
|
||||
|
||||
default:
|
||||
return -EAFNOSUPPORT;
|
||||
}
|
||||
}
|
||||
|
@@ -120,15 +120,26 @@ int netlink_family_from_string(const char *s) _pure_;
|
||||
|
||||
bool sockaddr_equal(const union sockaddr_union *a, const union sockaddr_union *b);
|
||||
|
||||
int fd_inc_sndbuf(int fd, size_t n);
|
||||
int fd_inc_rcvbuf(int fd, size_t n);
|
||||
int fd_set_sndbuf(int fd, size_t n, bool increase);
|
||||
static inline int fd_inc_sndbuf(int fd, size_t n) {
|
||||
return fd_set_sndbuf(fd, n, true);
|
||||
}
|
||||
int fd_set_rcvbuf(int fd, size_t n, bool increase);
|
||||
static inline int fd_inc_rcvbuf(int fd, size_t n) {
|
||||
return fd_set_rcvbuf(fd, n, true);
|
||||
}
|
||||
|
||||
int ip_tos_to_string_alloc(int i, char **s);
|
||||
int ip_tos_from_string(const char *s);
|
||||
|
||||
bool ifname_valid_full(const char *p, bool alternative);
|
||||
typedef enum {
|
||||
IFNAME_VALID_ALTERNATIVE = 1 << 0,
|
||||
IFNAME_VALID_NUMERIC = 1 << 1,
|
||||
_IFNAME_VALID_ALL = IFNAME_VALID_ALTERNATIVE | IFNAME_VALID_NUMERIC,
|
||||
} IfnameValidFlags;
|
||||
bool ifname_valid_full(const char *p, IfnameValidFlags flags);
|
||||
static inline bool ifname_valid(const char *p) {
|
||||
return ifname_valid_full(p, false);
|
||||
return ifname_valid_full(p, 0);
|
||||
}
|
||||
bool address_label_valid(const char *p);
|
||||
|
||||
@@ -207,6 +218,35 @@ struct cmsghdr* cmsg_find(struct msghdr *mh, int level, int type, socklen_t leng
|
||||
strnlen(_sa->sun_path, sizeof(_sa->sun_path))+1); \
|
||||
})
|
||||
|
||||
#define SOCKADDR_LEN(sa) \
|
||||
({ \
|
||||
const union sockaddr_union *__sa = &(sa); \
|
||||
size_t _len; \
|
||||
switch(__sa->sa.sa_family) { \
|
||||
case AF_INET: \
|
||||
_len = sizeof(struct sockaddr_in); \
|
||||
break; \
|
||||
case AF_INET6: \
|
||||
_len = sizeof(struct sockaddr_in6); \
|
||||
break; \
|
||||
case AF_UNIX: \
|
||||
_len = SOCKADDR_UN_LEN(__sa->un); \
|
||||
break; \
|
||||
case AF_PACKET: \
|
||||
_len = SOCKADDR_LL_LEN(__sa->ll); \
|
||||
break; \
|
||||
case AF_NETLINK: \
|
||||
_len = sizeof(struct sockaddr_nl); \
|
||||
break; \
|
||||
case AF_VSOCK: \
|
||||
_len = sizeof(struct sockaddr_vm); \
|
||||
break; \
|
||||
default: \
|
||||
assert_not_reached("invalid socket family"); \
|
||||
} \
|
||||
_len; \
|
||||
})
|
||||
|
||||
int socket_ioctl_fd(void);
|
||||
|
||||
int sockaddr_un_set_path(struct sockaddr_un *ret, const char *path);
|
||||
@@ -223,4 +263,11 @@ int socket_bind_to_ifindex(int fd, int ifindex);
|
||||
|
||||
ssize_t recvmsg_safe(int sockfd, struct msghdr *msg, int flags);
|
||||
|
||||
int socket_pass_pktinfo(int fd, bool b);
|
||||
int socket_get_family(int fd, int *ret);
|
||||
int socket_set_recvpktinfo(int fd, int af, bool b);
|
||||
int socket_set_recverr(int fd, int af, bool b);
|
||||
int socket_set_recvttl(int fd, int af, bool b);
|
||||
int socket_set_ttl(int fd, int af, int ttl);
|
||||
int socket_set_unicast_if(int fd, int af, int ifi);
|
||||
int socket_set_freebind(int fd, int af, bool b);
|
||||
int socket_set_transparent(int fd, int af, bool b);
|
||||
|
@@ -17,6 +17,7 @@
|
||||
#include "macro.h"
|
||||
#include "missing_fs.h"
|
||||
#include "missing_magic.h"
|
||||
#include "missing_syscall.h"
|
||||
#include "parse-util.h"
|
||||
#include "stat-util.h"
|
||||
#include "string-util.h"
|
||||
@@ -420,4 +421,60 @@ bool stat_inode_unmodified(const struct stat *a, const struct stat *b) {
|
||||
a->st_ino == b->st_ino &&
|
||||
(!(S_ISCHR(a->st_mode) || S_ISBLK(a->st_mode)) || a->st_rdev == b->st_rdev); /* if device node, also compare major/minor, because we can */
|
||||
}
|
||||
|
||||
int statx_fallback(int dfd, const char *path, int flags, unsigned mask, struct statx *sx) {
|
||||
static bool avoid_statx = false;
|
||||
struct stat st;
|
||||
|
||||
if (!avoid_statx) {
|
||||
if (statx(dfd, path, flags, mask, sx) < 0) {
|
||||
if (!ERRNO_IS_NOT_SUPPORTED(errno) && errno != EPERM)
|
||||
return -errno;
|
||||
|
||||
/* If statx() is not supported or if we see EPERM (which might indicate seccomp
|
||||
* filtering or so), let's do a fallback. Not that on EACCES we'll not fall back,
|
||||
* since that is likely an indication of fs access issues, which we should
|
||||
* propagate */
|
||||
} else
|
||||
return 0;
|
||||
|
||||
avoid_statx = true;
|
||||
}
|
||||
|
||||
/* Only do fallback if fstatat() supports the flag too, or if it's one of the sync flags, which are
|
||||
* OK to ignore */
|
||||
if ((flags & ~(AT_EMPTY_PATH|AT_NO_AUTOMOUNT|AT_SYMLINK_NOFOLLOW|
|
||||
AT_STATX_SYNC_AS_STAT|AT_STATX_FORCE_SYNC|AT_STATX_DONT_SYNC)) != 0)
|
||||
return -EOPNOTSUPP;
|
||||
|
||||
if (fstatat(dfd, path, &st, flags & (AT_EMPTY_PATH|AT_NO_AUTOMOUNT|AT_SYMLINK_NOFOLLOW)) < 0)
|
||||
return -errno;
|
||||
|
||||
*sx = (struct statx) {
|
||||
.stx_mask = STATX_TYPE|STATX_MODE|
|
||||
STATX_NLINK|STATX_UID|STATX_GID|
|
||||
STATX_ATIME|STATX_MTIME|STATX_CTIME|
|
||||
STATX_INO|STATX_SIZE|STATX_BLOCKS,
|
||||
.stx_blksize = st.st_blksize,
|
||||
.stx_nlink = st.st_nlink,
|
||||
.stx_uid = st.st_uid,
|
||||
.stx_gid = st.st_gid,
|
||||
.stx_mode = st.st_mode,
|
||||
.stx_ino = st.st_ino,
|
||||
.stx_size = st.st_size,
|
||||
.stx_blocks = st.st_blocks,
|
||||
.stx_rdev_major = major(st.st_rdev),
|
||||
.stx_rdev_minor = minor(st.st_rdev),
|
||||
.stx_dev_major = major(st.st_dev),
|
||||
.stx_dev_minor = minor(st.st_dev),
|
||||
.stx_atime.tv_sec = st.st_atim.tv_sec,
|
||||
.stx_atime.tv_nsec = st.st_atim.tv_nsec,
|
||||
.stx_mtime.tv_sec = st.st_mtim.tv_sec,
|
||||
.stx_mtime.tv_nsec = st.st_mtim.tv_nsec,
|
||||
.stx_ctime.tv_sec = st.st_ctim.tv_sec,
|
||||
.stx_ctime.tv_nsec = st.st_ctim.tv_nsec,
|
||||
};
|
||||
|
||||
return 0;
|
||||
}
|
||||
#endif /* NM_IGNORED */
|
||||
|
@@ -10,6 +10,7 @@
|
||||
#include <sys/vfs.h>
|
||||
|
||||
#include "macro.h"
|
||||
#include "missing_stat.h"
|
||||
|
||||
int is_symlink(const char *path);
|
||||
int is_dir(const char *path, bool follow);
|
||||
@@ -91,3 +92,24 @@ int device_path_parse_major_minor(const char *path, mode_t *ret_mode, dev_t *ret
|
||||
int proc_mounted(void);
|
||||
|
||||
bool stat_inode_unmodified(const struct stat *a, const struct stat *b);
|
||||
|
||||
int statx_fallback(int dfd, const char *path, int flags, unsigned mask, struct statx *sx);
|
||||
|
||||
#if HAS_FEATURE_MEMORY_SANITIZER
|
||||
# warning "Explicitly initializing struct statx, to work around msan limitation. Please remove as soon as msan has been updated to not require this."
|
||||
# define STRUCT_STATX_DEFINE(var) \
|
||||
struct statx var = {}
|
||||
# define STRUCT_NEW_STATX_DEFINE(var) \
|
||||
union { \
|
||||
struct statx sx; \
|
||||
struct new_statx nsx; \
|
||||
} var = {}
|
||||
#else
|
||||
# define STRUCT_STATX_DEFINE(var) \
|
||||
struct statx var
|
||||
# define STRUCT_NEW_STATX_DEFINE(var) \
|
||||
union { \
|
||||
struct statx sx; \
|
||||
struct new_statx nsx; \
|
||||
} var
|
||||
#endif
|
||||
|
@@ -10,12 +10,14 @@
|
||||
|
||||
#include "alloc-util.h"
|
||||
#include "escape.h"
|
||||
#include "extract-word.h"
|
||||
#include "fileio.h"
|
||||
#include "gunicode.h"
|
||||
#include "locale-util.h"
|
||||
#include "macro.h"
|
||||
#include "memory-util.h"
|
||||
#include "string-util.h"
|
||||
#include "strv.h"
|
||||
#include "terminal-util.h"
|
||||
#include "utf8.h"
|
||||
#include "util.h"
|
||||
@@ -112,83 +114,6 @@ char* first_word(const char *s, const char *word) {
|
||||
return (char*) p;
|
||||
}
|
||||
|
||||
static size_t strcspn_escaped(const char *s, const char *reject) {
|
||||
bool escaped = false;
|
||||
int n;
|
||||
|
||||
for (n = 0; s[n] != '\0'; n++) {
|
||||
if (escaped)
|
||||
escaped = false;
|
||||
else if (s[n] == '\\')
|
||||
escaped = true;
|
||||
else if (strchr(reject, s[n]))
|
||||
break;
|
||||
}
|
||||
|
||||
return n;
|
||||
}
|
||||
|
||||
/* Split a string into words. */
|
||||
const char* split(
|
||||
const char **state,
|
||||
size_t *l,
|
||||
const char *separator,
|
||||
SplitFlags flags) {
|
||||
|
||||
const char *current;
|
||||
|
||||
assert(state);
|
||||
assert(l);
|
||||
|
||||
if (!separator)
|
||||
separator = WHITESPACE;
|
||||
|
||||
current = *state;
|
||||
|
||||
if (*current == '\0') /* already at the end? */
|
||||
return NULL;
|
||||
|
||||
current += strspn(current, separator); /* skip leading separators */
|
||||
if (*current == '\0') { /* at the end now? */
|
||||
*state = current;
|
||||
return NULL;
|
||||
}
|
||||
|
||||
if (FLAGS_SET(flags, SPLIT_QUOTES)) {
|
||||
|
||||
if (strchr(QUOTES, *current)) {
|
||||
/* We are looking at a quote */
|
||||
*l = strcspn_escaped(current + 1, CHAR_TO_STR(*current));
|
||||
if (current[*l + 1] != *current ||
|
||||
(current[*l + 2] != 0 && !strchr(separator, current[*l + 2]))) {
|
||||
/* right quote missing or garbage at the end */
|
||||
if (FLAGS_SET(flags, SPLIT_RELAX)) {
|
||||
*state = current + *l + 1 + (current[*l + 1] != '\0');
|
||||
return current + 1;
|
||||
}
|
||||
*state = current;
|
||||
return NULL;
|
||||
}
|
||||
*state = current++ + *l + 2;
|
||||
|
||||
} else {
|
||||
/* We are looking at a something that is not a quote */
|
||||
*l = strcspn_escaped(current, separator);
|
||||
if (current[*l] && !strchr(separator, current[*l]) && !FLAGS_SET(flags, SPLIT_RELAX)) {
|
||||
/* unfinished escape */
|
||||
*state = current;
|
||||
return NULL;
|
||||
}
|
||||
*state = current + *l;
|
||||
}
|
||||
} else {
|
||||
*l = strcspn(current, separator);
|
||||
*state = current + *l;
|
||||
}
|
||||
|
||||
return current;
|
||||
}
|
||||
|
||||
char *strnappend(const char *s, const char *suffix, size_t b) {
|
||||
size_t a;
|
||||
char *r;
|
||||
@@ -1216,4 +1141,31 @@ int string_extract_line(const char *s, size_t i, char **ret) {
|
||||
c++;
|
||||
}
|
||||
}
|
||||
|
||||
int string_contains_word_strv(const char *string, const char *separators, char **words, const char **ret_word) {
|
||||
/* In the default mode with no separators specified, we split on whitespace and
|
||||
* don't coalesce separators. */
|
||||
const ExtractFlags flags = separators ? EXTRACT_DONT_COALESCE_SEPARATORS : 0;
|
||||
|
||||
const char *found = NULL;
|
||||
|
||||
for (const char *p = string;;) {
|
||||
_cleanup_free_ char *w = NULL;
|
||||
int r;
|
||||
|
||||
r = extract_first_word(&p, &w, separators, flags);
|
||||
if (r < 0)
|
||||
return r;
|
||||
if (r == 0)
|
||||
break;
|
||||
|
||||
found = strv_find(words, w);
|
||||
if (found)
|
||||
break;
|
||||
}
|
||||
|
||||
if (ret_word)
|
||||
*ret_word = found;
|
||||
return !!found;
|
||||
}
|
||||
#endif /* NM_IGNORED */
|
||||
|
@@ -108,24 +108,6 @@ char *endswith_no_case(const char *s, const char *postfix) _pure_;
|
||||
|
||||
char *first_word(const char *s, const char *word) _pure_;
|
||||
|
||||
typedef enum SplitFlags {
|
||||
SPLIT_QUOTES = 0x01 << 0,
|
||||
SPLIT_RELAX = 0x01 << 1,
|
||||
} SplitFlags;
|
||||
|
||||
/* Smelly. Do not use this anymore. Use extract_first_word() instead! */
|
||||
const char* split(const char **state, size_t *l, const char *separator, SplitFlags flags);
|
||||
|
||||
/* Similar, don't use this anymore */
|
||||
#define FOREACH_WORD(word, length, s, state) \
|
||||
_FOREACH_WORD(word, length, s, WHITESPACE, 0, state)
|
||||
|
||||
#define FOREACH_WORD_SEPARATOR(word, length, s, separator, state) \
|
||||
_FOREACH_WORD(word, length, s, separator, 0, state)
|
||||
|
||||
#define _FOREACH_WORD(word, length, s, separator, flags, state) \
|
||||
for ((state) = (s), (word) = split(&(state), &(length), (separator), (flags)); (word); (word) = split(&(state), &(length), (separator), (flags)))
|
||||
|
||||
char *strnappend(const char *s, const char *suffix, size_t length);
|
||||
|
||||
char *strjoin_real(const char *x, ...) _sentinel_;
|
||||
@@ -152,7 +134,6 @@ char *delete_trailing_chars(char *s, const char *bad);
|
||||
char *truncate_nl(char *s);
|
||||
|
||||
static inline char *skip_leading_chars(const char *s, const char *bad) {
|
||||
|
||||
if (!s)
|
||||
return NULL;
|
||||
|
||||
@@ -231,11 +212,9 @@ REENABLE_WARNING;
|
||||
|
||||
/* Like startswith(), but operates on arbitrary memory blocks */
|
||||
static inline void *memory_startswith(const void *p, size_t sz, const char *token) {
|
||||
size_t n;
|
||||
|
||||
assert(token);
|
||||
|
||||
n = strlen(token);
|
||||
size_t n = strlen(token);
|
||||
if (sz < n)
|
||||
return NULL;
|
||||
|
||||
@@ -251,20 +230,17 @@ static inline void *memory_startswith(const void *p, size_t sz, const char *toke
|
||||
* It works only for ASCII strings.
|
||||
*/
|
||||
static inline void *memory_startswith_no_case(const void *p, size_t sz, const char *token) {
|
||||
size_t n, i;
|
||||
|
||||
assert(token);
|
||||
|
||||
n = strlen(token);
|
||||
size_t n = strlen(token);
|
||||
if (sz < n)
|
||||
return NULL;
|
||||
|
||||
assert(p);
|
||||
|
||||
for (i = 0; i < n; i++) {
|
||||
for (size_t i = 0; i < n; i++)
|
||||
if (ascii_tolower(((char *)p)[i]) != ascii_tolower(token[i]))
|
||||
return NULL;
|
||||
}
|
||||
|
||||
return (uint8_t*) p + n;
|
||||
}
|
||||
@@ -286,3 +262,8 @@ char* string_erase(char *x);
|
||||
|
||||
int string_truncate_lines(const char *s, size_t n_lines, char **ret);
|
||||
int string_extract_line(const char *s, size_t i, char **ret);
|
||||
|
||||
int string_contains_word_strv(const char *string, const char *separators, char **words, const char **ret_word);
|
||||
static inline int string_contains_word(const char *string, const char *separators, const char *word) {
|
||||
return string_contains_word_strv(string, separators, STRV_MAKE(word), NULL);
|
||||
}
|
||||
|
@@ -260,44 +260,6 @@ int strv_extend_strv_concat(char ***a, char * const *b, const char *suffix) {
|
||||
}
|
||||
#endif /* NM_IGNORED */
|
||||
|
||||
char **strv_split_full(const char *s, const char *separator, SplitFlags flags) {
|
||||
const char *word, *state;
|
||||
size_t l;
|
||||
size_t n, i;
|
||||
char **r;
|
||||
|
||||
assert(s);
|
||||
|
||||
if (!separator)
|
||||
separator = WHITESPACE;
|
||||
|
||||
s += strspn(s, separator);
|
||||
if (isempty(s))
|
||||
return new0(char*, 1);
|
||||
|
||||
n = 0;
|
||||
_FOREACH_WORD(word, l, s, separator, flags, state)
|
||||
n++;
|
||||
|
||||
r = new(char*, n+1);
|
||||
if (!r)
|
||||
return NULL;
|
||||
|
||||
i = 0;
|
||||
_FOREACH_WORD(word, l, s, separator, flags, state) {
|
||||
r[i] = strndup(word, l);
|
||||
if (!r[i]) {
|
||||
strv_free(r);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
i++;
|
||||
}
|
||||
|
||||
r[i] = NULL;
|
||||
return r;
|
||||
}
|
||||
|
||||
char **strv_split_newlines(const char *s) {
|
||||
char **l;
|
||||
size_t n;
|
||||
@@ -321,8 +283,7 @@ char **strv_split_newlines(const char *s) {
|
||||
return l;
|
||||
}
|
||||
|
||||
#if 0 /* NM_IGNORED */
|
||||
int strv_split_extract(char ***t, const char *s, const char *separators, ExtractFlags flags) {
|
||||
int strv_split_full(char ***t, const char *s, const char *separators, ExtractFlags flags) {
|
||||
_cleanup_strv_free_ char **l = NULL;
|
||||
size_t n = 0, allocated = 0;
|
||||
int r;
|
||||
@@ -358,6 +319,7 @@ int strv_split_extract(char ***t, const char *s, const char *separators, Extract
|
||||
return (int) n;
|
||||
}
|
||||
|
||||
#if 0 /* NM_IGNORED */
|
||||
int strv_split_colon_pairs(char ***t, const char *s) {
|
||||
_cleanup_strv_free_ char **l = NULL;
|
||||
size_t n = 0, allocated = 0;
|
||||
|
@@ -72,13 +72,19 @@ static inline bool strv_isempty(char * const *l) {
|
||||
return !l || !*l;
|
||||
}
|
||||
|
||||
char **strv_split_full(const char *s, const char *separator, SplitFlags flags);
|
||||
static inline char **strv_split(const char *s, const char *separator) {
|
||||
return strv_split_full(s, separator, 0);
|
||||
}
|
||||
char **strv_split_newlines(const char *s);
|
||||
|
||||
int strv_split_extract(char ***t, const char *s, const char *separators, ExtractFlags flags);
|
||||
int strv_split_full(char ***t, const char *s, const char *separators, ExtractFlags flags);
|
||||
static inline char **strv_split(const char *s, const char *separators) {
|
||||
char **ret;
|
||||
int r;
|
||||
|
||||
r = strv_split_full(&ret, s, separators, 0);
|
||||
if (r < 0)
|
||||
return NULL;
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
/* Given a string containing white-space separated tuples of words themselves separated by ':',
|
||||
* returns a vector of strings. If the second element in a tuple is missing, the corresponding
|
||||
@@ -123,10 +129,6 @@ bool strv_overlap(char * const *a, char * const *b) _pure_;
|
||||
char **strv_sort(char **l);
|
||||
void strv_print(char * const *l);
|
||||
|
||||
#define STRV_MAKE(...) ((char**) ((const char*[]) { __VA_ARGS__, NULL }))
|
||||
|
||||
#define STRV_MAKE_EMPTY ((char*[1]) { NULL })
|
||||
|
||||
#define strv_from_stdarg_alloca(first) \
|
||||
({ \
|
||||
char **_l; \
|
||||
|
@@ -25,6 +25,7 @@
|
||||
#include "path-util.h"
|
||||
#include "process-util.h"
|
||||
#include "stat-util.h"
|
||||
#include "string-table.h"
|
||||
#include "string-util.h"
|
||||
#include "strv.h"
|
||||
#include "time-util.h"
|
||||
@@ -245,12 +246,28 @@ struct timespec *timespec_store(struct timespec *ts, usec_t u) {
|
||||
if (u == USEC_INFINITY ||
|
||||
u / USEC_PER_SEC >= TIME_T_MAX) {
|
||||
ts->tv_sec = (time_t) -1;
|
||||
ts->tv_nsec = (long) -1;
|
||||
ts->tv_nsec = -1L;
|
||||
return ts;
|
||||
}
|
||||
|
||||
ts->tv_sec = (time_t) (u / USEC_PER_SEC);
|
||||
ts->tv_nsec = (long int) ((u % USEC_PER_SEC) * NSEC_PER_USEC);
|
||||
ts->tv_nsec = (long) ((u % USEC_PER_SEC) * NSEC_PER_USEC);
|
||||
|
||||
return ts;
|
||||
}
|
||||
|
||||
struct timespec *timespec_store_nsec(struct timespec *ts, nsec_t n) {
|
||||
assert(ts);
|
||||
|
||||
if (n == NSEC_INFINITY ||
|
||||
n / NSEC_PER_SEC >= TIME_T_MAX) {
|
||||
ts->tv_sec = (time_t) -1;
|
||||
ts->tv_nsec = -1L;
|
||||
return ts;
|
||||
}
|
||||
|
||||
ts->tv_sec = (time_t) (n / NSEC_PER_SEC);
|
||||
ts->tv_nsec = (long) (n % NSEC_PER_SEC);
|
||||
|
||||
return ts;
|
||||
}
|
||||
@@ -285,12 +302,11 @@ struct timeval *timeval_store(struct timeval *tv, usec_t u) {
|
||||
return tv;
|
||||
}
|
||||
|
||||
static char *format_timestamp_internal(
|
||||
char *format_timestamp_style(
|
||||
char *buf,
|
||||
size_t l,
|
||||
usec_t t,
|
||||
bool utc,
|
||||
bool us) {
|
||||
TimestampStyle style) {
|
||||
|
||||
/* The weekdays in non-localized (English) form. We use this instead of the localized form, so that our
|
||||
* generated timestamps may be parsed with parse_timestamp(), and always read the same. */
|
||||
@@ -307,9 +323,27 @@ static char *format_timestamp_internal(
|
||||
struct tm tm;
|
||||
time_t sec;
|
||||
size_t n;
|
||||
bool utc = false, us = false;
|
||||
|
||||
assert(buf);
|
||||
|
||||
switch (style) {
|
||||
case TIMESTAMP_PRETTY:
|
||||
break;
|
||||
case TIMESTAMP_US:
|
||||
us = true;
|
||||
break;
|
||||
case TIMESTAMP_UTC:
|
||||
utc = true;
|
||||
break;
|
||||
case TIMESTAMP_US_UTC:
|
||||
us = true;
|
||||
utc = true;
|
||||
break;
|
||||
default:
|
||||
return NULL;
|
||||
}
|
||||
|
||||
if (l < (size_t) (3 + /* week day */
|
||||
1 + 10 + /* space and date */
|
||||
1 + 8 + /* space and time */
|
||||
@@ -383,22 +417,6 @@ static char *format_timestamp_internal(
|
||||
return buf;
|
||||
}
|
||||
|
||||
char *format_timestamp(char *buf, size_t l, usec_t t) {
|
||||
return format_timestamp_internal(buf, l, t, false, false);
|
||||
}
|
||||
|
||||
char *format_timestamp_utc(char *buf, size_t l, usec_t t) {
|
||||
return format_timestamp_internal(buf, l, t, true, false);
|
||||
}
|
||||
|
||||
char *format_timestamp_us(char *buf, size_t l, usec_t t) {
|
||||
return format_timestamp_internal(buf, l, t, false, true);
|
||||
}
|
||||
|
||||
char *format_timestamp_us_utc(char *buf, size_t l, usec_t t) {
|
||||
return format_timestamp_internal(buf, l, t, true, true);
|
||||
}
|
||||
|
||||
char *format_timestamp_relative(char *buf, size_t l, usec_t t) {
|
||||
const char *s;
|
||||
usec_t n, d;
|
||||
@@ -1575,4 +1593,28 @@ int time_change_fd(void) {
|
||||
|
||||
return -errno;
|
||||
}
|
||||
|
||||
static const char* const timestamp_style_table[_TIMESTAMP_STYLE_MAX] = {
|
||||
[TIMESTAMP_PRETTY] = "pretty",
|
||||
[TIMESTAMP_US] = "us",
|
||||
[TIMESTAMP_UTC] = "utc",
|
||||
[TIMESTAMP_US_UTC] = "us+utc",
|
||||
};
|
||||
|
||||
/* Use the macro for enum → string to allow for aliases */
|
||||
_DEFINE_STRING_TABLE_LOOKUP_TO_STRING(timestamp_style, TimestampStyle,);
|
||||
|
||||
/* For the string → enum mapping we use the generic implementation, but also support two aliases */
|
||||
TimestampStyle timestamp_style_from_string(const char *s) {
|
||||
TimestampStyle t;
|
||||
|
||||
t = (TimestampStyle) string_table_lookup(timestamp_style_table, ELEMENTSOF(timestamp_style_table), s);
|
||||
if (t >= 0)
|
||||
return t;
|
||||
if (streq_ptr(s, "µs"))
|
||||
return TIMESTAMP_US;
|
||||
if (streq_ptr(s, "µs+uts"))
|
||||
return TIMESTAMP_US_UTC;
|
||||
return t;
|
||||
}
|
||||
#endif /* NM_IGNORED */
|
||||
|
@@ -29,6 +29,15 @@ typedef struct triple_timestamp {
|
||||
usec_t boottime;
|
||||
} triple_timestamp;
|
||||
|
||||
typedef enum TimestampStyle {
|
||||
TIMESTAMP_PRETTY,
|
||||
TIMESTAMP_US,
|
||||
TIMESTAMP_UTC,
|
||||
TIMESTAMP_US_UTC,
|
||||
_TIMESTAMP_STYLE_MAX,
|
||||
_TIMESTAMP_STYLE_INVALID = -1,
|
||||
} TimestampStyle;
|
||||
|
||||
#define USEC_INFINITY ((usec_t) UINT64_MAX)
|
||||
#define NSEC_INFINITY ((nsec_t) UINT64_MAX)
|
||||
|
||||
@@ -103,17 +112,19 @@ usec_t triple_timestamp_by_clock(triple_timestamp *ts, clockid_t clock);
|
||||
usec_t timespec_load(const struct timespec *ts) _pure_;
|
||||
nsec_t timespec_load_nsec(const struct timespec *ts) _pure_;
|
||||
struct timespec *timespec_store(struct timespec *ts, usec_t u);
|
||||
struct timespec *timespec_store_nsec(struct timespec *ts, nsec_t n);
|
||||
|
||||
usec_t timeval_load(const struct timeval *tv) _pure_;
|
||||
struct timeval *timeval_store(struct timeval *tv, usec_t u);
|
||||
|
||||
char *format_timestamp(char *buf, size_t l, usec_t t);
|
||||
char *format_timestamp_utc(char *buf, size_t l, usec_t t);
|
||||
char *format_timestamp_us(char *buf, size_t l, usec_t t);
|
||||
char *format_timestamp_us_utc(char *buf, size_t l, usec_t t);
|
||||
char *format_timestamp_style(char *buf, size_t l, usec_t t, TimestampStyle style);
|
||||
char *format_timestamp_relative(char *buf, size_t l, usec_t t);
|
||||
char *format_timespan(char *buf, size_t l, usec_t t, usec_t accuracy);
|
||||
|
||||
static inline char *format_timestamp(char *buf, size_t l, usec_t t) {
|
||||
return format_timestamp_style(buf, l, t, TIMESTAMP_PRETTY);
|
||||
}
|
||||
|
||||
int parse_timestamp(const char *t, usec_t *usec);
|
||||
|
||||
int parse_sec(const char *t, usec_t *usec);
|
||||
@@ -185,3 +196,6 @@ static inline usec_t usec_sub_signed(usec_t timestamp, int64_t delta) {
|
||||
#endif
|
||||
|
||||
int time_change_fd(void);
|
||||
|
||||
const char* timestamp_style_to_string(TimestampStyle t) _const_;
|
||||
TimestampStyle timestamp_style_from_string(const char *s) _pure_;
|
||||
|
@@ -125,7 +125,7 @@ int utf8_encoded_to_unichar(const char *str, char32_t *ret_unichar) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
bool utf8_is_printable_newline(const char* str, size_t length, bool newline) {
|
||||
bool utf8_is_printable_newline(const char* str, size_t length, bool allow_newline) {
|
||||
const char *p;
|
||||
|
||||
assert(str);
|
||||
@@ -142,7 +142,7 @@ bool utf8_is_printable_newline(const char* str, size_t length, bool newline) {
|
||||
r = utf8_encoded_to_unichar(p, &val);
|
||||
if (r < 0 ||
|
||||
unichar_is_control(val) ||
|
||||
(!newline && val == '\n'))
|
||||
(!allow_newline && val == '\n'))
|
||||
return false;
|
||||
|
||||
length -= encoded_len;
|
||||
@@ -152,18 +152,22 @@ bool utf8_is_printable_newline(const char* str, size_t length, bool newline) {
|
||||
return true;
|
||||
}
|
||||
|
||||
char *utf8_is_valid(const char *str) {
|
||||
const char *p;
|
||||
char *utf8_is_valid_n(const char *str, size_t len_bytes) {
|
||||
/* Check if the string is composed of valid utf8 characters. If length len_bytes is given, stop after
|
||||
* len_bytes. Otherwise, stop at NUL. */
|
||||
|
||||
assert(str);
|
||||
|
||||
p = str;
|
||||
while (*p) {
|
||||
for (const char *p = str; len_bytes != (size_t) -1 ? (size_t) (p - str) < len_bytes : *p != '\0'; ) {
|
||||
int len;
|
||||
|
||||
len = utf8_encoded_valid_unichar(p, (size_t) -1);
|
||||
if (len < 0)
|
||||
return NULL;
|
||||
if (_unlikely_(*p == '\0') && len_bytes != (size_t) -1)
|
||||
return NULL; /* embedded NUL */
|
||||
|
||||
len = utf8_encoded_valid_unichar(p,
|
||||
len_bytes != (size_t) -1 ? len_bytes - (p - str) : (size_t) -1);
|
||||
if (_unlikely_(len < 0))
|
||||
return NULL; /* invalid character */
|
||||
|
||||
p += len;
|
||||
}
|
||||
|
@@ -14,11 +14,14 @@
|
||||
|
||||
bool unichar_is_valid(char32_t c);
|
||||
|
||||
char *utf8_is_valid(const char *s) _pure_;
|
||||
char *utf8_is_valid_n(const char *str, size_t len_bytes) _pure_;
|
||||
static inline char *utf8_is_valid(const char *s) {
|
||||
return utf8_is_valid_n(s, (size_t) -1);
|
||||
}
|
||||
char *ascii_is_valid(const char *s) _pure_;
|
||||
char *ascii_is_valid_n(const char *str, size_t len);
|
||||
|
||||
bool utf8_is_printable_newline(const char* str, size_t length, bool newline) _pure_;
|
||||
bool utf8_is_printable_newline(const char* str, size_t length, bool allow_newline) _pure_;
|
||||
#define utf8_is_printable(str, length) utf8_is_printable_newline(str, length, true)
|
||||
|
||||
char *utf8_escape_invalid(const char *s);
|
||||
|
@@ -78,7 +78,7 @@ int arp_network_bind_raw_socket(int ifindex, be32_t address, const struct ether_
|
||||
|
||||
assert(ifindex > 0);
|
||||
|
||||
s = socket(PF_PACKET, SOCK_DGRAM | SOCK_CLOEXEC | SOCK_NONBLOCK, 0);
|
||||
s = socket(AF_PACKET, SOCK_DGRAM | SOCK_CLOEXEC | SOCK_NONBLOCK, 0);
|
||||
if (s < 0)
|
||||
return -errno;
|
||||
|
||||
|
@@ -83,9 +83,8 @@ static int option_append(uint8_t options[], size_t size, size_t *offset,
|
||||
OrderedHashmap *s = (OrderedHashmap *) optval;
|
||||
struct sd_dhcp_option *p;
|
||||
size_t l = 0;
|
||||
Iterator i;
|
||||
|
||||
ORDERED_HASHMAP_FOREACH(p, s, i)
|
||||
ORDERED_HASHMAP_FOREACH(p, s)
|
||||
l += p->length + 2;
|
||||
|
||||
if (*offset + l + 2 > size)
|
||||
@@ -96,7 +95,7 @@ static int option_append(uint8_t options[], size_t size, size_t *offset,
|
||||
|
||||
*offset += 2;
|
||||
|
||||
ORDERED_HASHMAP_FOREACH(p, s, i) {
|
||||
ORDERED_HASHMAP_FOREACH(p, s) {
|
||||
options[*offset] = p->option;
|
||||
options[*offset + 1] = p->length;
|
||||
memcpy(&options[*offset + 2], p->data, p->length);
|
||||
|
@@ -83,7 +83,6 @@ int dhcp6_option_append(uint8_t **buf, size_t *buflen, uint16_t code,
|
||||
|
||||
int dhcp6_option_append_vendor_option(uint8_t **buf, size_t *buflen, OrderedHashmap *vendor_options) {
|
||||
sd_dhcp6_option *options;
|
||||
Iterator i;
|
||||
int r;
|
||||
|
||||
assert(buf);
|
||||
@@ -91,7 +90,7 @@ int dhcp6_option_append_vendor_option(uint8_t **buf, size_t *buflen, OrderedHash
|
||||
assert(buflen);
|
||||
assert(vendor_options);
|
||||
|
||||
ORDERED_HASHMAP_FOREACH(options, vendor_options, i) {
|
||||
ORDERED_HASHMAP_FOREACH(options, vendor_options) {
|
||||
_cleanup_free_ uint8_t *p = NULL;
|
||||
size_t total;
|
||||
|
||||
|
@@ -49,7 +49,7 @@ int lldp_network_bind_raw_socket(int ifindex) {
|
||||
|
||||
assert(ifindex > 0);
|
||||
|
||||
fd = socket(PF_PACKET, SOCK_RAW|SOCK_CLOEXEC|SOCK_NONBLOCK,
|
||||
fd = socket(AF_PACKET, SOCK_RAW|SOCK_CLOEXEC|SOCK_NONBLOCK,
|
||||
htobe16(ETHERTYPE_LLDP));
|
||||
if (fd < 0)
|
||||
return -errno;
|
||||
|
@@ -924,7 +924,6 @@ static int dhcp_client_send_raw(
|
||||
|
||||
static int client_append_common_discover_request_options(sd_dhcp_client *client, DHCPPacket *packet, size_t *optoffset, size_t optlen) {
|
||||
sd_dhcp_option *j;
|
||||
Iterator i;
|
||||
int r;
|
||||
|
||||
assert(client);
|
||||
@@ -975,7 +974,7 @@ static int client_append_common_discover_request_options(sd_dhcp_client *client,
|
||||
return r;
|
||||
}
|
||||
|
||||
ORDERED_HASHMAP_FOREACH(j, client->extra_options, i) {
|
||||
ORDERED_HASHMAP_FOREACH(j, client->extra_options) {
|
||||
r = dhcp_option_append(&packet->dhcp, optlen, optoffset, 0,
|
||||
j->option, j->length, j->data);
|
||||
if (r < 0)
|
||||
|
@@ -630,7 +630,6 @@ static int client_send_message(sd_dhcp6_client *client, usec_t time_now) {
|
||||
IN6ADDR_ALL_DHCP6_RELAY_AGENTS_AND_SERVERS_INIT;
|
||||
struct sd_dhcp6_option *j;
|
||||
size_t len, optlen = 512;
|
||||
Iterator i;
|
||||
uint8_t *opt;
|
||||
int r;
|
||||
usec_t elapsed_usec;
|
||||
@@ -865,7 +864,7 @@ static int client_send_message(sd_dhcp6_client *client, usec_t time_now) {
|
||||
if (r < 0)
|
||||
return r;
|
||||
|
||||
ORDERED_HASHMAP_FOREACH(j, client->extra_options, i) {
|
||||
ORDERED_HASHMAP_FOREACH(j, client->extra_options) {
|
||||
r = dhcp6_option_append(&opt, &optlen, j->option, j->length, j->data);
|
||||
if (r < 0)
|
||||
return r;
|
||||
@@ -1701,7 +1700,7 @@ int sd_dhcp6_client_is_running(sd_dhcp6_client *client) {
|
||||
|
||||
int sd_dhcp6_client_start(sd_dhcp6_client *client) {
|
||||
enum DHCP6State state = DHCP6_STATE_SOLICITATION;
|
||||
int r = 0;
|
||||
int r;
|
||||
|
||||
assert_return(client, -EINVAL);
|
||||
assert_return(client->event, -EINVAL);
|
||||
|
@@ -144,10 +144,17 @@ static void ipv4acd_client_notify(sd_ipv4acd *acd, int event) {
|
||||
}
|
||||
|
||||
int sd_ipv4acd_stop(sd_ipv4acd *acd) {
|
||||
IPv4ACDState old_state;
|
||||
|
||||
assert_return(acd, -EINVAL);
|
||||
|
||||
old_state = acd->state;
|
||||
|
||||
ipv4acd_reset(acd);
|
||||
|
||||
if (old_state == IPV4ACD_STATE_INIT)
|
||||
return 0;
|
||||
|
||||
log_ipv4acd(acd, "STOPPED");
|
||||
|
||||
ipv4acd_client_notify(acd, SD_IPV4ACD_EVENT_STOP);
|
||||
@@ -437,6 +444,15 @@ int sd_ipv4acd_set_address(sd_ipv4acd *acd, const struct in_addr *address) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
int sd_ipv4acd_get_address(sd_ipv4acd *acd, struct in_addr *address) {
|
||||
assert_return(acd, -EINVAL);
|
||||
assert_return(address, -EINVAL);
|
||||
|
||||
address->s_addr = acd->address;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
int sd_ipv4acd_is_running(sd_ipv4acd *acd) {
|
||||
assert_return(acd, false);
|
||||
|
||||
@@ -457,8 +473,7 @@ int sd_ipv4acd_start(sd_ipv4acd *acd, bool reset_conflicts) {
|
||||
if (r < 0)
|
||||
return r;
|
||||
|
||||
safe_close(acd->fd);
|
||||
acd->fd = r;
|
||||
CLOSE_AND_REPLACE(acd->fd, r);
|
||||
acd->defend_window = 0;
|
||||
|
||||
if (reset_conflicts)
|
||||
|
@@ -433,7 +433,6 @@ static int lldp_start_timer(sd_lldp *lldp, sd_lldp_neighbor *neighbor) {
|
||||
|
||||
_public_ int sd_lldp_get_neighbors(sd_lldp *lldp, sd_lldp_neighbor ***ret) {
|
||||
sd_lldp_neighbor **l = NULL, *n;
|
||||
Iterator i;
|
||||
int k = 0, r;
|
||||
|
||||
assert_return(lldp, -EINVAL);
|
||||
@@ -454,7 +453,7 @@ _public_ int sd_lldp_get_neighbors(sd_lldp *lldp, sd_lldp_neighbor ***ret) {
|
||||
return r;
|
||||
}
|
||||
|
||||
HASHMAP_FOREACH(n, lldp->neighbor_by_id, i)
|
||||
HASHMAP_FOREACH(n, lldp->neighbor_by_id)
|
||||
l[k++] = sd_lldp_neighbor_ref(n);
|
||||
|
||||
assert((size_t) k == hashmap_size(lldp->neighbor_by_id));
|
||||
|
@@ -2874,7 +2874,6 @@ static int process_timer(
|
||||
|
||||
static int process_child(sd_event *e) {
|
||||
sd_event_source *s;
|
||||
Iterator i;
|
||||
int r;
|
||||
|
||||
assert(e);
|
||||
@@ -2899,7 +2898,7 @@ static int process_child(sd_event *e) {
|
||||
the callback still sees the process as a zombie.
|
||||
*/
|
||||
|
||||
HASHMAP_FOREACH(s, e->child_sources, i) {
|
||||
HASHMAP_FOREACH(s, e->child_sources) {
|
||||
assert(s->type == SOURCE_CHILD);
|
||||
|
||||
if (s->pending)
|
||||
@@ -3104,12 +3103,11 @@ static int event_inotify_data_process(sd_event *e, struct inotify_data *d) {
|
||||
|
||||
if (d->buffer.ev.mask & IN_Q_OVERFLOW) {
|
||||
struct inode_data *inode_data;
|
||||
Iterator i;
|
||||
|
||||
/* The queue overran, let's pass this event to all event sources connected to this inotify
|
||||
* object */
|
||||
|
||||
HASHMAP_FOREACH(inode_data, d->inodes, i) {
|
||||
HASHMAP_FOREACH(inode_data, d->inodes) {
|
||||
sd_event_source *s;
|
||||
|
||||
LIST_FOREACH(inotify.by_inode_data, s, inode_data->event_sources) {
|
||||
@@ -3207,12 +3205,11 @@ static int source_dispatch(sd_event_source *s) {
|
||||
|
||||
if (s->type != SOURCE_POST) {
|
||||
sd_event_source *z;
|
||||
Iterator i;
|
||||
|
||||
/* If we execute a non-post source, let's mark all
|
||||
* post sources as pending */
|
||||
|
||||
SET_FOREACH(z, s->event->post_sources, i) {
|
||||
SET_FOREACH(z, s->event->post_sources) {
|
||||
if (z->enabled == SD_EVENT_OFF)
|
||||
continue;
|
||||
|
||||
|
Reference in New Issue
Block a user