systemd: merge branch systemd into master
This commit is contained in:
@@ -1085,6 +1085,7 @@ src_libsystemd_nm_la_SOURCES = \
|
|||||||
src/systemd/sd-adapt/conf-parser.h \
|
src/systemd/sd-adapt/conf-parser.h \
|
||||||
src/systemd/sd-adapt/def.h \
|
src/systemd/sd-adapt/def.h \
|
||||||
src/systemd/sd-adapt/dirent-util.h \
|
src/systemd/sd-adapt/dirent-util.h \
|
||||||
|
src/systemd/sd-adapt/env-util.h \
|
||||||
src/systemd/sd-adapt/format-util.h \
|
src/systemd/sd-adapt/format-util.h \
|
||||||
src/systemd/sd-adapt/gunicode.h \
|
src/systemd/sd-adapt/gunicode.h \
|
||||||
src/systemd/sd-adapt/khash.h \
|
src/systemd/sd-adapt/khash.h \
|
||||||
|
@@ -62,6 +62,12 @@ AC_TYPE_PID_T
|
|||||||
AC_CHECK_SIZEOF(dev_t)
|
AC_CHECK_SIZEOF(dev_t)
|
||||||
AC_CHECK_SIZEOF(time_t)
|
AC_CHECK_SIZEOF(time_t)
|
||||||
|
|
||||||
|
AC_CHECK_DECLS([
|
||||||
|
explicit_bzero],
|
||||||
|
[], [], [[
|
||||||
|
#include <string.h>
|
||||||
|
]])
|
||||||
|
|
||||||
dnl
|
dnl
|
||||||
dnl translation support
|
dnl translation support
|
||||||
dnl
|
dnl
|
||||||
|
3
src/systemd/sd-adapt/env-util.h
Normal file
3
src/systemd/sd-adapt/env-util.h
Normal file
@@ -0,0 +1,3 @@
|
|||||||
|
#pragma once
|
||||||
|
|
||||||
|
/* dummy header */
|
@@ -32,6 +32,7 @@
|
|||||||
|
|
||||||
#include "alloc-util.h"
|
#include "alloc-util.h"
|
||||||
#include "ctype.h"
|
#include "ctype.h"
|
||||||
|
#include "env-util.h"
|
||||||
#include "escape.h"
|
#include "escape.h"
|
||||||
#include "fd-util.h"
|
#include "fd-util.h"
|
||||||
#include "fileio.h"
|
#include "fileio.h"
|
||||||
@@ -555,13 +556,14 @@ static int parse_env_file_internal(
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if (state == PRE_VALUE ||
|
if (IN_SET(state,
|
||||||
state == VALUE ||
|
PRE_VALUE,
|
||||||
state == VALUE_ESCAPE ||
|
VALUE,
|
||||||
state == SINGLE_QUOTE_VALUE ||
|
VALUE_ESCAPE,
|
||||||
state == SINGLE_QUOTE_VALUE_ESCAPE ||
|
SINGLE_QUOTE_VALUE,
|
||||||
state == DOUBLE_QUOTE_VALUE ||
|
SINGLE_QUOTE_VALUE_ESCAPE,
|
||||||
state == DOUBLE_QUOTE_VALUE_ESCAPE) {
|
DOUBLE_QUOTE_VALUE,
|
||||||
|
DOUBLE_QUOTE_VALUE_ESCAPE)) {
|
||||||
|
|
||||||
key[n_key] = 0;
|
key[n_key] = 0;
|
||||||
|
|
||||||
@@ -588,14 +590,9 @@ fail:
|
|||||||
return r;
|
return r;
|
||||||
}
|
}
|
||||||
|
|
||||||
static int parse_env_file_push(
|
static int check_utf8ness_and_warn(
|
||||||
const char *filename, unsigned line,
|
const char *filename, unsigned line,
|
||||||
const char *key, char *value,
|
const char *key, char *value) {
|
||||||
void *userdata,
|
|
||||||
int *n_pushed) {
|
|
||||||
|
|
||||||
const char *k;
|
|
||||||
va_list aq, *ap = userdata;
|
|
||||||
|
|
||||||
if (!utf8_is_valid(key)) {
|
if (!utf8_is_valid(key)) {
|
||||||
_cleanup_free_ char *p = NULL;
|
_cleanup_free_ char *p = NULL;
|
||||||
@@ -613,6 +610,23 @@ static int parse_env_file_push(
|
|||||||
return -EINVAL;
|
return -EINVAL;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
static int parse_env_file_push(
|
||||||
|
const char *filename, unsigned line,
|
||||||
|
const char *key, char *value,
|
||||||
|
void *userdata,
|
||||||
|
int *n_pushed) {
|
||||||
|
|
||||||
|
const char *k;
|
||||||
|
va_list aq, *ap = userdata;
|
||||||
|
int r;
|
||||||
|
|
||||||
|
r = check_utf8ness_and_warn(filename, line, key, value);
|
||||||
|
if (r < 0)
|
||||||
|
return r;
|
||||||
|
|
||||||
va_copy(aq, *ap);
|
va_copy(aq, *ap);
|
||||||
|
|
||||||
while ((k = va_arg(aq, const char *))) {
|
while ((k = va_arg(aq, const char *))) {
|
||||||
@@ -655,6 +669,7 @@ int parse_env_file(
|
|||||||
return r < 0 ? r : n_pushed;
|
return r < 0 ? r : n_pushed;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#if 0 /* NM_IGNORED */
|
||||||
static int load_env_file_push(
|
static int load_env_file_push(
|
||||||
const char *filename, unsigned line,
|
const char *filename, unsigned line,
|
||||||
const char *key, char *value,
|
const char *key, char *value,
|
||||||
@@ -664,27 +679,19 @@ static int load_env_file_push(
|
|||||||
char *p;
|
char *p;
|
||||||
int r;
|
int r;
|
||||||
|
|
||||||
if (!utf8_is_valid(key)) {
|
r = check_utf8ness_and_warn(filename, line, key, value);
|
||||||
_cleanup_free_ char *t = utf8_escape_invalid(key);
|
if (r < 0)
|
||||||
|
return r;
|
||||||
|
|
||||||
log_error("%s:%u: invalid UTF-8 for key '%s', ignoring.", strna(filename), line, t);
|
p = strjoin(key, "=", value);
|
||||||
return -EINVAL;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (value && !utf8_is_valid(value)) {
|
|
||||||
_cleanup_free_ char *t = utf8_escape_invalid(value);
|
|
||||||
|
|
||||||
log_error("%s:%u: invalid UTF-8 value for key %s: '%s', ignoring.", strna(filename), line, key, t);
|
|
||||||
return -EINVAL;
|
|
||||||
}
|
|
||||||
|
|
||||||
p = strjoin(key, "=", strempty(value));
|
|
||||||
if (!p)
|
if (!p)
|
||||||
return -ENOMEM;
|
return -ENOMEM;
|
||||||
|
|
||||||
r = strv_consume(m, p);
|
r = strv_env_replace(m, p);
|
||||||
if (r < 0)
|
if (r < 0) {
|
||||||
|
free(p);
|
||||||
return r;
|
return r;
|
||||||
|
}
|
||||||
|
|
||||||
if (n_pushed)
|
if (n_pushed)
|
||||||
(*n_pushed)++;
|
(*n_pushed)++;
|
||||||
@@ -718,19 +725,9 @@ static int load_env_file_push_pairs(
|
|||||||
char ***m = userdata;
|
char ***m = userdata;
|
||||||
int r;
|
int r;
|
||||||
|
|
||||||
if (!utf8_is_valid(key)) {
|
r = check_utf8ness_and_warn(filename, line, key, value);
|
||||||
_cleanup_free_ char *t = utf8_escape_invalid(key);
|
if (r < 0)
|
||||||
|
return r;
|
||||||
log_error("%s:%u: invalid UTF-8 for key '%s', ignoring.", strna(filename), line, t);
|
|
||||||
return -EINVAL;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (value && !utf8_is_valid(value)) {
|
|
||||||
_cleanup_free_ char *t = utf8_escape_invalid(value);
|
|
||||||
|
|
||||||
log_error("%s:%u: invalid UTF-8 value for key %s: '%s', ignoring.", strna(filename), line, key, t);
|
|
||||||
return -EINVAL;
|
|
||||||
}
|
|
||||||
|
|
||||||
r = strv_extend(m, key);
|
r = strv_extend(m, key);
|
||||||
if (r < 0)
|
if (r < 0)
|
||||||
@@ -769,6 +766,52 @@ int load_env_file_pairs(FILE *f, const char *fname, const char *newline, char **
|
|||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static int merge_env_file_push(
|
||||||
|
const char *filename, unsigned line,
|
||||||
|
const char *key, char *value,
|
||||||
|
void *userdata,
|
||||||
|
int *n_pushed) {
|
||||||
|
|
||||||
|
char ***env = userdata;
|
||||||
|
char *expanded_value;
|
||||||
|
|
||||||
|
assert(env);
|
||||||
|
|
||||||
|
if (!value) {
|
||||||
|
log_error("%s:%u: invalid syntax (around \"%s\"), ignoring.", strna(filename), line, key);
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!env_name_is_valid(key)) {
|
||||||
|
log_error("%s:%u: invalid variable name \"%s\", ignoring.", strna(filename), line, key);
|
||||||
|
free(value);
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
expanded_value = replace_env(value, *env,
|
||||||
|
REPLACE_ENV_USE_ENVIRONMENT|
|
||||||
|
REPLACE_ENV_ALLOW_BRACELESS|
|
||||||
|
REPLACE_ENV_ALLOW_EXTENDED);
|
||||||
|
if (!expanded_value)
|
||||||
|
return -ENOMEM;
|
||||||
|
|
||||||
|
free_and_replace(value, expanded_value);
|
||||||
|
|
||||||
|
return load_env_file_push(filename, line, key, value, env, n_pushed);
|
||||||
|
}
|
||||||
|
|
||||||
|
int merge_env_file(
|
||||||
|
char ***env,
|
||||||
|
FILE *f,
|
||||||
|
const char *fname) {
|
||||||
|
|
||||||
|
/* NOTE: this function supports braceful and braceless variable expansions,
|
||||||
|
* plus "extended" substitutions, unlike other exported parsing functions.
|
||||||
|
*/
|
||||||
|
|
||||||
|
return parse_env_file_internal(f, fname, NEWLINE, merge_env_file_push, env, NULL);
|
||||||
|
}
|
||||||
|
|
||||||
static void write_env_var(FILE *f, const char *v) {
|
static void write_env_var(FILE *f, const char *v) {
|
||||||
const char *p;
|
const char *p;
|
||||||
|
|
||||||
@@ -828,6 +871,7 @@ int write_env_file(const char *fname, char **l) {
|
|||||||
unlink(p);
|
unlink(p);
|
||||||
return r;
|
return r;
|
||||||
}
|
}
|
||||||
|
#endif /* NM_IGNORED */
|
||||||
|
|
||||||
int executable_is_script(const char *path, char **interpreter) {
|
int executable_is_script(const char *path, char **interpreter) {
|
||||||
int r;
|
int r;
|
||||||
@@ -1349,6 +1393,25 @@ int open_tmpfile_linkable(const char *target, int flags, char **ret_path) {
|
|||||||
return fd;
|
return fd;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
int open_serialization_fd(const char *ident) {
|
||||||
|
int fd = -1;
|
||||||
|
|
||||||
|
fd = memfd_create(ident, MFD_CLOEXEC);
|
||||||
|
if (fd < 0) {
|
||||||
|
const char *path;
|
||||||
|
|
||||||
|
path = getpid() == 1 ? "/run/systemd" : "/tmp";
|
||||||
|
fd = open_tmpfile_unlinkable(path, O_RDWR|O_CLOEXEC);
|
||||||
|
if (fd < 0)
|
||||||
|
return fd;
|
||||||
|
|
||||||
|
log_debug("Serializing %s to %s.", ident, path);
|
||||||
|
} else
|
||||||
|
log_debug("Serializing %s to memfd.", ident);
|
||||||
|
|
||||||
|
return fd;
|
||||||
|
}
|
||||||
|
|
||||||
int link_tmpfile(int fd, const char *path, const char *target) {
|
int link_tmpfile(int fd, const char *path, const char *target) {
|
||||||
|
|
||||||
assert(fd >= 0);
|
assert(fd >= 0);
|
||||||
|
@@ -48,6 +48,8 @@ int parse_env_file(const char *fname, const char *separator, ...) _sentinel_;
|
|||||||
int load_env_file(FILE *f, const char *fname, const char *separator, char ***l);
|
int load_env_file(FILE *f, const char *fname, const char *separator, char ***l);
|
||||||
int load_env_file_pairs(FILE *f, const char *fname, const char *separator, char ***l);
|
int load_env_file_pairs(FILE *f, const char *fname, const char *separator, char ***l);
|
||||||
|
|
||||||
|
int merge_env_file(char ***env, FILE *f, const char *fname);
|
||||||
|
|
||||||
int write_env_file(const char *fname, char **l);
|
int write_env_file(const char *fname, char **l);
|
||||||
|
|
||||||
int executable_is_script(const char *path, char **interpreter);
|
int executable_is_script(const char *path, char **interpreter);
|
||||||
@@ -84,6 +86,7 @@ int fputs_with_space(FILE *f, const char *s, const char *separator, bool *space)
|
|||||||
|
|
||||||
int open_tmpfile_unlinkable(const char *directory, int flags);
|
int open_tmpfile_unlinkable(const char *directory, int flags);
|
||||||
int open_tmpfile_linkable(const char *target, int flags, char **ret_path);
|
int open_tmpfile_linkable(const char *target, int flags, char **ret_path);
|
||||||
|
int open_serialization_fd(const char *ident);
|
||||||
|
|
||||||
int link_tmpfile(int fd, const char *path, const char *target);
|
int link_tmpfile(int fd, const char *path, const char *target);
|
||||||
|
|
||||||
|
@@ -91,3 +91,9 @@ static inline void rmdir_and_free(char *p) {
|
|||||||
free(p);
|
free(p);
|
||||||
}
|
}
|
||||||
DEFINE_TRIVIAL_CLEANUP_FUNC(char*, rmdir_and_free);
|
DEFINE_TRIVIAL_CLEANUP_FUNC(char*, rmdir_and_free);
|
||||||
|
|
||||||
|
static inline void unlink_and_free(char *p) {
|
||||||
|
(void) unlink(p);
|
||||||
|
free(p);
|
||||||
|
}
|
||||||
|
DEFINE_TRIVIAL_CLEANUP_FUNC(char*, unlink_and_free);
|
||||||
|
@@ -47,6 +47,7 @@ bool hostname_is_set(void) {
|
|||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#if 0 /* NM_IGNORED */
|
||||||
char* gethostname_malloc(void) {
|
char* gethostname_malloc(void) {
|
||||||
struct utsname u;
|
struct utsname u;
|
||||||
|
|
||||||
@@ -57,10 +58,11 @@ char* gethostname_malloc(void) {
|
|||||||
assert_se(uname(&u) >= 0);
|
assert_se(uname(&u) >= 0);
|
||||||
|
|
||||||
if (isempty(u.nodename) || streq(u.nodename, "(none)"))
|
if (isempty(u.nodename) || streq(u.nodename, "(none)"))
|
||||||
return strdup(u.sysname);
|
return strdup(FALLBACK_HOSTNAME);
|
||||||
|
|
||||||
return strdup(u.nodename);
|
return strdup(u.nodename);
|
||||||
}
|
}
|
||||||
|
#endif /* NM_IGNORED */
|
||||||
|
|
||||||
int gethostname_strict(char **ret) {
|
int gethostname_strict(char **ret) {
|
||||||
struct utsname u;
|
struct utsname u;
|
||||||
|
@@ -68,6 +68,18 @@ int in_addr_is_link_local(int family, const union in_addr_union *u) {
|
|||||||
return -EAFNOSUPPORT;
|
return -EAFNOSUPPORT;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
int in_addr_is_multicast(int family, const union in_addr_union *u) {
|
||||||
|
assert(u);
|
||||||
|
|
||||||
|
if (family == AF_INET)
|
||||||
|
return IN_MULTICAST(be32toh(u->in.s_addr));
|
||||||
|
|
||||||
|
if (family == AF_INET6)
|
||||||
|
return IN6_IS_ADDR_MULTICAST(&u->in6);
|
||||||
|
|
||||||
|
return -EAFNOSUPPORT;
|
||||||
|
}
|
||||||
|
|
||||||
bool in4_addr_is_localhost(const struct in_addr *a) {
|
bool in4_addr_is_localhost(const struct in_addr *a) {
|
||||||
assert(a);
|
assert(a);
|
||||||
|
|
||||||
|
@@ -39,6 +39,8 @@ struct in_addr_data {
|
|||||||
bool in4_addr_is_null(const struct in_addr *a);
|
bool in4_addr_is_null(const struct in_addr *a);
|
||||||
int in_addr_is_null(int family, const union in_addr_union *u);
|
int in_addr_is_null(int family, const union in_addr_union *u);
|
||||||
|
|
||||||
|
int in_addr_is_multicast(int family, const union in_addr_union *u);
|
||||||
|
|
||||||
bool in4_addr_is_link_local(const struct in_addr *a);
|
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);
|
int in_addr_is_link_local(int family, const union in_addr_union *u);
|
||||||
|
|
||||||
|
@@ -216,13 +216,13 @@ bool log_on_console(void) _pure_;
|
|||||||
const char *log_target_to_string(LogTarget target) _const_;
|
const char *log_target_to_string(LogTarget target) _const_;
|
||||||
LogTarget log_target_from_string(const char *s) _pure_;
|
LogTarget log_target_from_string(const char *s) _pure_;
|
||||||
|
|
||||||
/* Helpers to prepare various fields for structured logging */
|
/* Helper to prepare various field for structured logging */
|
||||||
#define LOG_MESSAGE(fmt, ...) "MESSAGE=" fmt, ##__VA_ARGS__
|
#define LOG_MESSAGE(fmt, ...) "MESSAGE=" fmt, ##__VA_ARGS__
|
||||||
#define LOG_MESSAGE_ID(x) "MESSAGE_ID=" SD_ID128_FORMAT_STR, SD_ID128_FORMAT_VAL(x)
|
|
||||||
|
|
||||||
void log_received_signal(int level, const struct signalfd_siginfo *si);
|
void log_received_signal(int level, const struct signalfd_siginfo *si);
|
||||||
|
|
||||||
void log_set_upgrade_syslog_to_journal(bool b);
|
void log_set_upgrade_syslog_to_journal(bool b);
|
||||||
|
void log_set_always_reopen_console(bool b);
|
||||||
|
|
||||||
int log_syntax_internal(
|
int log_syntax_internal(
|
||||||
const char *unit,
|
const char *unit,
|
||||||
|
@@ -903,6 +903,26 @@ bool ifname_valid(const char *p) {
|
|||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
bool address_label_valid(const char *p) {
|
||||||
|
|
||||||
|
if (isempty(p))
|
||||||
|
return false;
|
||||||
|
|
||||||
|
if (strlen(p) >= IFNAMSIZ)
|
||||||
|
return false;
|
||||||
|
|
||||||
|
while (*p) {
|
||||||
|
if ((uint8_t) *p >= 127U)
|
||||||
|
return false;
|
||||||
|
|
||||||
|
if ((uint8_t) *p <= 31U)
|
||||||
|
return false;
|
||||||
|
p++;
|
||||||
|
}
|
||||||
|
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
int getpeercred(int fd, struct ucred *ucred) {
|
int getpeercred(int fd, struct ucred *ucred) {
|
||||||
socklen_t n = sizeof(struct ucred);
|
socklen_t n = sizeof(struct ucred);
|
||||||
struct ucred u;
|
struct ucred u;
|
||||||
|
@@ -128,6 +128,7 @@ int ip_tos_to_string_alloc(int i, char **s);
|
|||||||
int ip_tos_from_string(const char *s);
|
int ip_tos_from_string(const char *s);
|
||||||
|
|
||||||
bool ifname_valid(const char *p);
|
bool ifname_valid(const char *p);
|
||||||
|
bool address_label_valid(const char *p);
|
||||||
|
|
||||||
int getpeercred(int fd, struct ucred *ucred);
|
int getpeercred(int fd, struct ucred *ucred);
|
||||||
int getpeersec(int fd, char **ret);
|
int getpeersec(int fd, char **ret);
|
||||||
|
@@ -825,6 +825,7 @@ int free_and_strdup(char **p, const char *s) {
|
|||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#if !HAVE_DECL_EXPLICIT_BZERO
|
||||||
/*
|
/*
|
||||||
* Pointer to memset is volatile so that compiler must de-reference
|
* Pointer to memset is volatile so that compiler must de-reference
|
||||||
* the pointer and can't assume that it points to any function in
|
* the pointer and can't assume that it points to any function in
|
||||||
@@ -835,19 +836,19 @@ typedef void *(*memset_t)(void *,int,size_t);
|
|||||||
|
|
||||||
static volatile memset_t memset_func = memset;
|
static volatile memset_t memset_func = memset;
|
||||||
|
|
||||||
void* memory_erase(void *p, size_t l) {
|
void explicit_bzero(void *p, size_t l) {
|
||||||
return memset_func(p, 'x', l);
|
memset_func(p, '\0', l);
|
||||||
}
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
char* string_erase(char *x) {
|
char* string_erase(char *x) {
|
||||||
|
|
||||||
if (!x)
|
if (!x)
|
||||||
return NULL;
|
return NULL;
|
||||||
|
|
||||||
/* A delicious drop of snake-oil! To be called on memory where
|
/* A delicious drop of snake-oil! To be called on memory where
|
||||||
* we stored passphrases or so, after we used them. */
|
* we stored passphrases or so, after we used them. */
|
||||||
|
explicit_bzero(x, strlen(x));
|
||||||
return memory_erase(x, strlen(x));
|
return x;
|
||||||
}
|
}
|
||||||
|
|
||||||
char *string_free_erase(char *s) {
|
char *string_free_erase(char *s) {
|
||||||
|
@@ -189,7 +189,10 @@ static inline void *memmem_safe(const void *haystack, size_t haystacklen, const
|
|||||||
return memmem(haystack, haystacklen, needle, needlelen);
|
return memmem(haystack, haystacklen, needle, needlelen);
|
||||||
}
|
}
|
||||||
|
|
||||||
void* memory_erase(void *p, size_t l);
|
#if !HAVE_DECL_EXPLICIT_BZERO
|
||||||
|
void explicit_bzero(void *p, size_t l);
|
||||||
|
#endif
|
||||||
|
|
||||||
char *string_erase(char *x);
|
char *string_erase(char *x);
|
||||||
|
|
||||||
char *string_free_erase(char *s);
|
char *string_free_erase(char *s);
|
||||||
|
@@ -61,9 +61,6 @@
|
|||||||
#include "user-util.h"
|
#include "user-util.h"
|
||||||
#include "util.h"
|
#include "util.h"
|
||||||
|
|
||||||
/* Put this test here for a lack of better place */
|
|
||||||
assert_cc(EAGAIN == EWOULDBLOCK);
|
|
||||||
|
|
||||||
#if 0 /* NM_IGNORED */
|
#if 0 /* NM_IGNORED */
|
||||||
int saved_argc = 0;
|
int saved_argc = 0;
|
||||||
char **saved_argv = NULL;
|
char **saved_argv = NULL;
|
||||||
@@ -85,146 +82,6 @@ size_t page_size(void) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
#if 0 /* NM_IGNORED */
|
#if 0 /* NM_IGNORED */
|
||||||
static int do_execute(char **directories, usec_t timeout, char *argv[]) {
|
|
||||||
_cleanup_hashmap_free_free_ Hashmap *pids = NULL;
|
|
||||||
_cleanup_set_free_free_ Set *seen = NULL;
|
|
||||||
char **directory;
|
|
||||||
|
|
||||||
/* We fork this all off from a child process so that we can
|
|
||||||
* somewhat cleanly make use of SIGALRM to set a time limit */
|
|
||||||
|
|
||||||
(void) reset_all_signal_handlers();
|
|
||||||
(void) reset_signal_mask();
|
|
||||||
|
|
||||||
assert_se(prctl(PR_SET_PDEATHSIG, SIGTERM) == 0);
|
|
||||||
|
|
||||||
pids = hashmap_new(NULL);
|
|
||||||
if (!pids)
|
|
||||||
return log_oom();
|
|
||||||
|
|
||||||
seen = set_new(&string_hash_ops);
|
|
||||||
if (!seen)
|
|
||||||
return log_oom();
|
|
||||||
|
|
||||||
STRV_FOREACH(directory, directories) {
|
|
||||||
_cleanup_closedir_ DIR *d;
|
|
||||||
struct dirent *de;
|
|
||||||
|
|
||||||
d = opendir(*directory);
|
|
||||||
if (!d) {
|
|
||||||
if (errno == ENOENT)
|
|
||||||
continue;
|
|
||||||
|
|
||||||
return log_error_errno(errno, "Failed to open directory %s: %m", *directory);
|
|
||||||
}
|
|
||||||
|
|
||||||
FOREACH_DIRENT(de, d, break) {
|
|
||||||
_cleanup_free_ char *path = NULL;
|
|
||||||
pid_t pid;
|
|
||||||
int r;
|
|
||||||
|
|
||||||
if (!dirent_is_file(de))
|
|
||||||
continue;
|
|
||||||
|
|
||||||
if (set_contains(seen, de->d_name)) {
|
|
||||||
log_debug("%1$s/%2$s skipped (%2$s was already seen).", *directory, de->d_name);
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
|
|
||||||
r = set_put_strdup(seen, de->d_name);
|
|
||||||
if (r < 0)
|
|
||||||
return log_oom();
|
|
||||||
|
|
||||||
path = strjoin(*directory, "/", de->d_name);
|
|
||||||
if (!path)
|
|
||||||
return log_oom();
|
|
||||||
|
|
||||||
if (null_or_empty_path(path)) {
|
|
||||||
log_debug("%s is empty (a mask).", path);
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
|
|
||||||
pid = fork();
|
|
||||||
if (pid < 0) {
|
|
||||||
log_error_errno(errno, "Failed to fork: %m");
|
|
||||||
continue;
|
|
||||||
} else if (pid == 0) {
|
|
||||||
char *_argv[2];
|
|
||||||
|
|
||||||
assert_se(prctl(PR_SET_PDEATHSIG, SIGTERM) == 0);
|
|
||||||
|
|
||||||
if (!argv) {
|
|
||||||
_argv[0] = path;
|
|
||||||
_argv[1] = NULL;
|
|
||||||
argv = _argv;
|
|
||||||
} else
|
|
||||||
argv[0] = path;
|
|
||||||
|
|
||||||
execv(path, argv);
|
|
||||||
return log_error_errno(errno, "Failed to execute %s: %m", path);
|
|
||||||
}
|
|
||||||
|
|
||||||
log_debug("Spawned %s as " PID_FMT ".", path, pid);
|
|
||||||
|
|
||||||
r = hashmap_put(pids, PID_TO_PTR(pid), path);
|
|
||||||
if (r < 0)
|
|
||||||
return log_oom();
|
|
||||||
path = NULL;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/* Abort execution of this process after the timout. We simply
|
|
||||||
* rely on SIGALRM as default action terminating the process,
|
|
||||||
* and turn on alarm(). */
|
|
||||||
|
|
||||||
if (timeout != USEC_INFINITY)
|
|
||||||
alarm((timeout + USEC_PER_SEC - 1) / USEC_PER_SEC);
|
|
||||||
|
|
||||||
while (!hashmap_isempty(pids)) {
|
|
||||||
_cleanup_free_ char *path = NULL;
|
|
||||||
pid_t pid;
|
|
||||||
|
|
||||||
pid = PTR_TO_PID(hashmap_first_key(pids));
|
|
||||||
assert(pid > 0);
|
|
||||||
|
|
||||||
path = hashmap_remove(pids, PID_TO_PTR(pid));
|
|
||||||
assert(path);
|
|
||||||
|
|
||||||
wait_for_terminate_and_warn(path, pid, true);
|
|
||||||
}
|
|
||||||
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
void execute_directories(const char* const* directories, usec_t timeout, char *argv[]) {
|
|
||||||
pid_t executor_pid;
|
|
||||||
int r;
|
|
||||||
char *name;
|
|
||||||
char **dirs = (char**) directories;
|
|
||||||
|
|
||||||
assert(!strv_isempty(dirs));
|
|
||||||
|
|
||||||
name = basename(dirs[0]);
|
|
||||||
assert(!isempty(name));
|
|
||||||
|
|
||||||
/* Executes all binaries in the directories in parallel and waits
|
|
||||||
* for them to finish. Optionally a timeout is applied. If a file
|
|
||||||
* with the same name exists in more than one directory, the
|
|
||||||
* earliest one wins. */
|
|
||||||
|
|
||||||
executor_pid = fork();
|
|
||||||
if (executor_pid < 0) {
|
|
||||||
log_error_errno(errno, "Failed to fork: %m");
|
|
||||||
return;
|
|
||||||
|
|
||||||
} else if (executor_pid == 0) {
|
|
||||||
r = do_execute(dirs, timeout, argv);
|
|
||||||
_exit(r < 0 ? EXIT_FAILURE : EXIT_SUCCESS);
|
|
||||||
}
|
|
||||||
|
|
||||||
wait_for_terminate_and_warn(name, executor_pid, true);
|
|
||||||
}
|
|
||||||
|
|
||||||
bool plymouth_running(void) {
|
bool plymouth_running(void) {
|
||||||
return access("/run/plymouth/pid", F_OK) >= 0;
|
return access("/run/plymouth/pid", F_OK) >= 0;
|
||||||
}
|
}
|
||||||
|
@@ -65,8 +65,6 @@ static inline const char* enable_disable(bool b) {
|
|||||||
return b ? "enable" : "disable";
|
return b ? "enable" : "disable";
|
||||||
}
|
}
|
||||||
|
|
||||||
void execute_directories(const char* const* directories, usec_t timeout, char *argv[]);
|
|
||||||
|
|
||||||
bool plymouth_running(void);
|
bool plymouth_running(void);
|
||||||
|
|
||||||
bool display_is_local(const char *display) _pure_;
|
bool display_is_local(const char *display) _pure_;
|
||||||
|
@@ -49,6 +49,13 @@ int lldp_network_bind_raw_socket(int ifindex) {
|
|||||||
.filter = (struct sock_filter*) filter,
|
.filter = (struct sock_filter*) filter,
|
||||||
};
|
};
|
||||||
|
|
||||||
|
struct packet_mreq mreq = {
|
||||||
|
.mr_ifindex = ifindex,
|
||||||
|
.mr_type = PACKET_MR_MULTICAST,
|
||||||
|
.mr_alen = ETH_ALEN,
|
||||||
|
.mr_address = { 0x01, 0x80, 0xC2, 0x00, 0x00, 0x00 }
|
||||||
|
};
|
||||||
|
|
||||||
union sockaddr_union saddrll = {
|
union sockaddr_union saddrll = {
|
||||||
.ll.sll_family = AF_PACKET,
|
.ll.sll_family = AF_PACKET,
|
||||||
.ll.sll_ifindex = ifindex,
|
.ll.sll_ifindex = ifindex,
|
||||||
@@ -68,6 +75,20 @@ int lldp_network_bind_raw_socket(int ifindex) {
|
|||||||
if (r < 0)
|
if (r < 0)
|
||||||
return -errno;
|
return -errno;
|
||||||
|
|
||||||
|
r = setsockopt(fd, SOL_PACKET, PACKET_ADD_MEMBERSHIP, &mreq, sizeof(mreq));
|
||||||
|
if (r < 0)
|
||||||
|
return -errno;
|
||||||
|
|
||||||
|
mreq.mr_address[ETH_ALEN - 1] = 0x03;
|
||||||
|
r = setsockopt(fd, SOL_PACKET, PACKET_ADD_MEMBERSHIP, &mreq, sizeof(mreq));
|
||||||
|
if (r < 0)
|
||||||
|
return -errno;
|
||||||
|
|
||||||
|
mreq.mr_address[ETH_ALEN - 1] = 0x0E;
|
||||||
|
r = setsockopt(fd, SOL_PACKET, PACKET_ADD_MEMBERSHIP, &mreq, sizeof(mreq));
|
||||||
|
if (r < 0)
|
||||||
|
return -errno;
|
||||||
|
|
||||||
r = bind(fd, &saddrll.sa, sizeof(saddrll.ll));
|
r = bind(fd, &saddrll.sa, sizeof(saddrll.ll));
|
||||||
if (r < 0)
|
if (r < 0)
|
||||||
return -errno;
|
return -errno;
|
||||||
|
@@ -829,6 +829,15 @@ static int client_send_request(sd_dhcp_client *client) {
|
|||||||
return r;
|
return r;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (client->vendor_class_identifier) {
|
||||||
|
r = dhcp_option_append(&request->dhcp, optlen, &optoffset, 0,
|
||||||
|
SD_DHCP_OPTION_VENDOR_CLASS_IDENTIFIER,
|
||||||
|
strlen(client->vendor_class_identifier),
|
||||||
|
client->vendor_class_identifier);
|
||||||
|
if (r < 0)
|
||||||
|
return r;
|
||||||
|
}
|
||||||
|
|
||||||
r = dhcp_option_append(&request->dhcp, optlen, &optoffset, 0,
|
r = dhcp_option_append(&request->dhcp, optlen, &optoffset, 0,
|
||||||
SD_DHCP_OPTION_END, 0, NULL);
|
SD_DHCP_OPTION_END, 0, NULL);
|
||||||
if (r < 0)
|
if (r < 0)
|
||||||
|
@@ -244,8 +244,6 @@ static int ipv4acd_on_timeout(sd_event_source *s, uint64_t usec, void *userdata)
|
|||||||
r = ipv4acd_set_next_wakeup(acd, RATE_LIMIT_INTERVAL_USEC, PROBE_WAIT_USEC);
|
r = ipv4acd_set_next_wakeup(acd, RATE_LIMIT_INTERVAL_USEC, PROBE_WAIT_USEC);
|
||||||
if (r < 0)
|
if (r < 0)
|
||||||
goto fail;
|
goto fail;
|
||||||
|
|
||||||
acd->n_conflict = 0;
|
|
||||||
} else {
|
} else {
|
||||||
r = ipv4acd_set_next_wakeup(acd, 0, PROBE_WAIT_USEC);
|
r = ipv4acd_set_next_wakeup(acd, 0, PROBE_WAIT_USEC);
|
||||||
if (r < 0)
|
if (r < 0)
|
||||||
|
@@ -732,7 +732,6 @@ static void event_unmask_signal_data(sd_event *e, struct signal_data *d, int sig
|
|||||||
|
|
||||||
/* If all the mask is all-zero we can get rid of the structure */
|
/* If all the mask is all-zero we can get rid of the structure */
|
||||||
hashmap_remove(e->signal_data, &d->priority);
|
hashmap_remove(e->signal_data, &d->priority);
|
||||||
assert(!d->current);
|
|
||||||
safe_close(d->fd);
|
safe_close(d->fd);
|
||||||
free(d);
|
free(d);
|
||||||
return;
|
return;
|
||||||
|
@@ -100,6 +100,9 @@ int sd_id128_get_invocation(sd_id128_t *ret);
|
|||||||
((x).bytes[15] & 15) >= 10 ? 'a' + ((x).bytes[15] & 15) - 10 : '0' + ((x).bytes[15] & 15), \
|
((x).bytes[15] & 15) >= 10 ? 'a' + ((x).bytes[15] & 15) - 10 : '0' + ((x).bytes[15] & 15), \
|
||||||
0 })
|
0 })
|
||||||
|
|
||||||
|
#define SD_ID128_MAKE_STR(a, b, c, d, e, f, g, h, i, j, k, l, m, n, o, p) \
|
||||||
|
#a #b #c #d #e #f #g #h #i #j #k #l #m #n #o #p
|
||||||
|
|
||||||
_sd_pure_ static __inline__ int sd_id128_equal(sd_id128_t a, sd_id128_t b) {
|
_sd_pure_ static __inline__ int sd_id128_equal(sd_id128_t a, sd_id128_t b) {
|
||||||
return memcmp(&a, &b, 16) == 0;
|
return memcmp(&a, &b, 16) == 0;
|
||||||
}
|
}
|
||||||
|
Reference in New Issue
Block a user