mirror of
https://gitlab.freedesktop.org/NetworkManager/NetworkManager
synced 2024-10-06 16:21:50 +00:00
systemd: merge branch systemd into master
- fix DHCP over Infiniband https://bugzilla.redhat.com/show_bug.cgi?id=1477678
This commit is contained in:
commit
e0cdaf9880
|
@ -1199,6 +1199,8 @@ src_libsystemd_nm_la_SOURCES = \
|
|||
src/systemd/src/basic/path-util.h \
|
||||
src/systemd/src/basic/prioq.c \
|
||||
src/systemd/src/basic/prioq.h \
|
||||
src/systemd/src/basic/process-util.c \
|
||||
src/systemd/src/basic/process-util.h \
|
||||
src/systemd/src/basic/random-util.c \
|
||||
src/systemd/src/basic/random-util.h \
|
||||
src/systemd/src/basic/refcnt.h \
|
||||
|
|
3
src/systemd/sd-adapt/ioprio.h
Normal file
3
src/systemd/sd-adapt/ioprio.h
Normal file
|
@ -0,0 +1,3 @@
|
|||
#pragma once
|
||||
|
||||
/* dummy header */
|
|
@ -168,10 +168,6 @@ static inline pid_t gettid(void) {
|
|||
return (pid_t) syscall(SYS_gettid);
|
||||
}
|
||||
|
||||
static inline bool is_main_thread(void) {
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
#endif /* (NETWORKMANAGER_COMPILATION) == NM_NETWORKMANAGER_COMPILATION_SYSTEMD */
|
||||
|
||||
#endif /* NM_SD_ADAPT_H */
|
||||
|
|
3
src/systemd/sd-adapt/raw-clone.h
Normal file
3
src/systemd/sd-adapt/raw-clone.h
Normal file
|
@ -0,0 +1,3 @@
|
|||
#pragma once
|
||||
|
||||
/* dummy header */
|
|
@ -27,16 +27,31 @@
|
|||
#include "util.h"
|
||||
|
||||
void* memdup(const void *p, size_t l) {
|
||||
void *r;
|
||||
void *ret;
|
||||
|
||||
assert(p);
|
||||
assert(l == 0 || p);
|
||||
|
||||
r = malloc(l);
|
||||
if (!r)
|
||||
ret = malloc(l);
|
||||
if (!ret)
|
||||
return NULL;
|
||||
|
||||
memcpy(r, p, l);
|
||||
return r;
|
||||
memcpy(ret, p, l);
|
||||
return ret;
|
||||
}
|
||||
|
||||
void* memdup_suffix0(const void*p, size_t l) {
|
||||
void *ret;
|
||||
|
||||
assert(l == 0 || p);
|
||||
|
||||
/* The same as memdup() but place a safety NUL byte after the allocated memory */
|
||||
|
||||
ret = malloc(l + 1);
|
||||
if (!ret)
|
||||
return NULL;
|
||||
|
||||
*((uint8_t*) mempcpy(ret, p, l)) = 0;
|
||||
return ret;
|
||||
}
|
||||
|
||||
void* greedy_realloc(void **p, size_t *allocated, size_t need, size_t size) {
|
||||
|
|
|
@ -36,6 +36,8 @@
|
|||
|
||||
#define newdup(t, p, n) ((t*) memdup_multiply(p, sizeof(t), (n)))
|
||||
|
||||
#define newdup_suffix0(t, p, n) ((t*) memdup_suffix0_multiply(p, sizeof(t), (n)))
|
||||
|
||||
#define malloc0(n) (calloc(1, (n)))
|
||||
|
||||
static inline void *mfree(void *memory) {
|
||||
|
@ -52,6 +54,7 @@ static inline void *mfree(void *memory) {
|
|||
})
|
||||
|
||||
void* memdup(const void *p, size_t l) _alloc_(2);
|
||||
void* memdup_suffix0(const void*p, size_t l) _alloc_(2);
|
||||
|
||||
static inline void freep(void *p) {
|
||||
free(*(void**) p);
|
||||
|
@ -84,6 +87,13 @@ _alloc_(2, 3) static inline void *memdup_multiply(const void *p, size_t size, si
|
|||
return memdup(p, size * need);
|
||||
}
|
||||
|
||||
_alloc_(2, 3) static inline void *memdup_suffix0_multiply(const void *p, size_t size, size_t need) {
|
||||
if (size_multiply_overflow(size, need))
|
||||
return NULL;
|
||||
|
||||
return memdup_suffix0(p, size * need);
|
||||
}
|
||||
|
||||
void* greedy_realloc(void **p, size_t *allocated, size_t need, size_t size);
|
||||
void* greedy_realloc0(void **p, size_t *allocated, size_t need, size_t size);
|
||||
|
||||
|
|
|
@ -316,7 +316,7 @@ int cunescape_length_with_prefix(const char *s, size_t length, const char *prefi
|
|||
|
||||
/* Undoes C style string escaping, and optionally prefixes it. */
|
||||
|
||||
pl = prefix ? strlen(prefix) : 0;
|
||||
pl = strlen_ptr(prefix);
|
||||
|
||||
r = new(char, pl+length+1);
|
||||
if (!r)
|
||||
|
@ -443,10 +443,16 @@ char *octescape(const char *s, size_t len) {
|
|||
|
||||
}
|
||||
|
||||
static char *strcpy_backslash_escaped(char *t, const char *s, const char *bad) {
|
||||
static char *strcpy_backslash_escaped(char *t, const char *s, const char *bad, bool escape_tab_nl) {
|
||||
assert(bad);
|
||||
|
||||
for (; *s; s++) {
|
||||
if (escape_tab_nl && IN_SET(*s, '\n', '\t')) {
|
||||
*(t++) = '\\';
|
||||
*(t++) = *s == '\n' ? 'n' : 't';
|
||||
continue;
|
||||
}
|
||||
|
||||
if (*s == '\\' || strchr(bad, *s))
|
||||
*(t++) = '\\';
|
||||
|
||||
|
@ -463,20 +469,21 @@ char *shell_escape(const char *s, const char *bad) {
|
|||
if (!r)
|
||||
return NULL;
|
||||
|
||||
t = strcpy_backslash_escaped(r, s, bad);
|
||||
t = strcpy_backslash_escaped(r, s, bad, false);
|
||||
*t = 0;
|
||||
|
||||
return r;
|
||||
}
|
||||
|
||||
char *shell_maybe_quote(const char *s) {
|
||||
char* shell_maybe_quote(const char *s, EscapeStyle style) {
|
||||
const char *p;
|
||||
char *r, *t;
|
||||
|
||||
assert(s);
|
||||
|
||||
/* Encloses a string in double quotes if necessary to make it
|
||||
* OK as shell string. */
|
||||
/* Encloses a string in quotes if necessary to make it OK as a shell
|
||||
* string. Note that we treat benign UTF-8 characters as needing
|
||||
* escaping too, but that should be OK. */
|
||||
|
||||
for (p = s; *p; p++)
|
||||
if (*p <= ' ' ||
|
||||
|
@ -487,17 +494,30 @@ char *shell_maybe_quote(const char *s) {
|
|||
if (!*p)
|
||||
return strdup(s);
|
||||
|
||||
r = new(char, 1+strlen(s)*2+1+1);
|
||||
r = new(char, (style == ESCAPE_POSIX) + 1 + strlen(s)*2 + 1 + 1);
|
||||
if (!r)
|
||||
return NULL;
|
||||
|
||||
t = r;
|
||||
*(t++) = '"';
|
||||
if (style == ESCAPE_BACKSLASH)
|
||||
*(t++) = '"';
|
||||
else if (style == ESCAPE_POSIX) {
|
||||
*(t++) = '$';
|
||||
*(t++) = '\'';
|
||||
} else
|
||||
assert_not_reached("Bad EscapeStyle");
|
||||
|
||||
t = mempcpy(t, s, p - s);
|
||||
|
||||
t = strcpy_backslash_escaped(t, p, SHELL_NEED_ESCAPE);
|
||||
if (style == ESCAPE_BACKSLASH)
|
||||
t = strcpy_backslash_escaped(t, p, SHELL_NEED_ESCAPE, false);
|
||||
else
|
||||
t = strcpy_backslash_escaped(t, p, SHELL_NEED_ESCAPE_POSIX, true);
|
||||
|
||||
*(t++)= '"';
|
||||
if (style == ESCAPE_BACKSLASH)
|
||||
*(t++) = '"';
|
||||
else
|
||||
*(t++) = '\'';
|
||||
*t = 0;
|
||||
|
||||
return r;
|
||||
|
|
|
@ -33,13 +33,30 @@
|
|||
/* What characters are special in the shell? */
|
||||
/* must be escaped outside and inside double-quotes */
|
||||
#define SHELL_NEED_ESCAPE "\"\\`$"
|
||||
/* can be escaped or double-quoted */
|
||||
#define SHELL_NEED_QUOTES SHELL_NEED_ESCAPE GLOB_CHARS "'()<>|&;"
|
||||
|
||||
/* Those that can be escaped or double-quoted.
|
||||
*
|
||||
* Stricly speaking, ! does not need to be escaped, except in interactive
|
||||
* mode, but let's be extra nice to the user and quote ! in case this
|
||||
* output is ever used in interactive mode. */
|
||||
#define SHELL_NEED_QUOTES SHELL_NEED_ESCAPE GLOB_CHARS "'()<>|&;!"
|
||||
|
||||
/* Note that we assume control characters would need to be escaped too in
|
||||
* addition to the "special" characters listed here, if they appear in the
|
||||
* string. Current users disallow control characters. Also '"' shall not
|
||||
* be escaped.
|
||||
*/
|
||||
#define SHELL_NEED_ESCAPE_POSIX "\\\'"
|
||||
|
||||
typedef enum UnescapeFlags {
|
||||
UNESCAPE_RELAX = 1,
|
||||
} UnescapeFlags;
|
||||
|
||||
typedef enum EscapeStyle {
|
||||
ESCAPE_BACKSLASH = 1,
|
||||
ESCAPE_POSIX = 2,
|
||||
} EscapeStyle;
|
||||
|
||||
char *cescape(const char *s);
|
||||
char *cescape_length(const char *s, size_t n);
|
||||
size_t cescape_char(char c, char *buf);
|
||||
|
@ -53,4 +70,4 @@ char *xescape(const char *s, const char *bad);
|
|||
char *octescape(const char *s, size_t len);
|
||||
|
||||
char *shell_escape(const char *s, const char *bad);
|
||||
char *shell_maybe_quote(const char *s);
|
||||
char* shell_maybe_quote(const char *s, EscapeStyle style);
|
||||
|
|
|
@ -33,6 +33,7 @@
|
|||
#include "missing.h"
|
||||
#include "parse-util.h"
|
||||
#include "path-util.h"
|
||||
#include "process-util.h"
|
||||
#include "socket-util.h"
|
||||
#include "stdio-util.h"
|
||||
#include "util.h"
|
||||
|
@ -285,7 +286,7 @@ int same_fd(int a, int b) {
|
|||
return true;
|
||||
|
||||
/* Try to use kcmp() if we have it. */
|
||||
pid = getpid();
|
||||
pid = getpid_cached();
|
||||
r = kcmp(pid, pid, KCMP_FILE, a, b);
|
||||
if (r == 0)
|
||||
return true;
|
||||
|
|
|
@ -43,6 +43,7 @@
|
|||
#include "missing.h"
|
||||
#include "parse-util.h"
|
||||
#include "path-util.h"
|
||||
#include "process-util.h"
|
||||
#include "random-util.h"
|
||||
#include "stdio-util.h"
|
||||
#include "string-util.h"
|
||||
|
@ -826,29 +827,29 @@ static void write_env_var(FILE *f, const char *v) {
|
|||
p = strchr(v, '=');
|
||||
if (!p) {
|
||||
/* Fallback */
|
||||
fputs(v, f);
|
||||
fputc('\n', f);
|
||||
fputs_unlocked(v, f);
|
||||
fputc_unlocked('\n', f);
|
||||
return;
|
||||
}
|
||||
|
||||
p++;
|
||||
fwrite(v, 1, p-v, f);
|
||||
fwrite_unlocked(v, 1, p-v, f);
|
||||
|
||||
if (string_has_cc(p, NULL) || chars_intersect(p, WHITESPACE SHELL_NEED_QUOTES)) {
|
||||
fputc('\"', f);
|
||||
fputc_unlocked('\"', f);
|
||||
|
||||
for (; *p; p++) {
|
||||
if (strchr(SHELL_NEED_ESCAPE, *p))
|
||||
fputc('\\', f);
|
||||
fputc_unlocked('\\', f);
|
||||
|
||||
fputc(*p, f);
|
||||
fputc_unlocked(*p, f);
|
||||
}
|
||||
|
||||
fputc('\"', f);
|
||||
fputc_unlocked('\"', f);
|
||||
} else
|
||||
fputs(p, f);
|
||||
fputs_unlocked(p, f);
|
||||
|
||||
fputc('\n', f);
|
||||
fputc_unlocked('\n', f);
|
||||
}
|
||||
|
||||
int write_env_file(const char *fname, char **l) {
|
||||
|
@ -1408,7 +1409,7 @@ int open_serialization_fd(const char *ident) {
|
|||
if (fd < 0) {
|
||||
const char *path;
|
||||
|
||||
path = getpid() == 1 ? "/run/systemd" : "/tmp";
|
||||
path = getpid_cached() == 1 ? "/run/systemd" : "/tmp";
|
||||
fd = open_tmpfile_unlinkable(path, O_RDWR|O_CLOEXEC);
|
||||
if (fd < 0)
|
||||
return fd;
|
||||
|
|
|
@ -314,7 +314,7 @@ int fd_warn_permissions(const char *path, int fd) {
|
|||
if (st.st_mode & 0002)
|
||||
log_warning("Configuration file %s is marked world-writable. Please remove world writability permission bits. Proceeding anyway.", path);
|
||||
|
||||
if (getpid() == 1 && (st.st_mode & 0044) != 0044)
|
||||
if (getpid_cached() == 1 && (st.st_mode & 0044) != 0044)
|
||||
log_warning("Configuration file %s is marked world-inaccessible. This has no effect as configuration data is accessible via APIs without restrictions. Proceeding anyway.", path);
|
||||
|
||||
return 0;
|
||||
|
|
|
@ -27,6 +27,7 @@
|
|||
#include "alloc-util.h"
|
||||
#include "hexdecoct.h"
|
||||
#include "macro.h"
|
||||
#include "string-util.h"
|
||||
#include "util.h"
|
||||
|
||||
char octchar(int x) {
|
||||
|
@ -571,7 +572,7 @@ static int base64_append_width(char **prefix, int plen,
|
|||
|
||||
lines = (len + width - 1) / width;
|
||||
|
||||
slen = sep ? strlen(sep) : 0;
|
||||
slen = strlen_ptr(sep);
|
||||
t = realloc(*prefix, plen + 1 + slen + (indent + width + 1) * lines);
|
||||
if (!t)
|
||||
return -ENOMEM;
|
||||
|
|
|
@ -201,8 +201,11 @@ bool is_gateway_hostname(const char *hostname) {
|
|||
* synthetic "gateway" host. */
|
||||
|
||||
return
|
||||
strcaseeq(hostname, "gateway") ||
|
||||
strcaseeq(hostname, "gateway.");
|
||||
strcaseeq(hostname, "_gateway") || strcaseeq(hostname, "_gateway.")
|
||||
#if ENABLE_COMPAT_GATEWAY_HOSTNAME
|
||||
|| strcaseeq(hostname, "gateway") || strcaseeq(hostname, "gateway.")
|
||||
#endif
|
||||
;
|
||||
}
|
||||
|
||||
int sethostname_idempotent(const char *s) {
|
||||
|
|
|
@ -30,6 +30,7 @@
|
|||
#include "sd-id128.h"
|
||||
|
||||
#include "macro.h"
|
||||
#include "process-util.h"
|
||||
|
||||
typedef enum LogRealm {
|
||||
LOG_REALM_SYSTEMD,
|
||||
|
@ -88,6 +89,11 @@ int log_get_max_level_realm(LogRealm realm) _pure_;
|
|||
#define log_get_max_level() \
|
||||
log_get_max_level_realm(LOG_REALM)
|
||||
|
||||
/* Functions below that open and close logs or configure logging based on the
|
||||
* environment should not be called from library code — this is always a job
|
||||
* for the application itself.
|
||||
*/
|
||||
|
||||
int log_open(void);
|
||||
void log_close(void);
|
||||
void log_forget_fds(void);
|
||||
|
@ -248,7 +254,7 @@ void log_assert_failed_return_realm(
|
|||
#define log_notice(...) log_full(LOG_NOTICE, __VA_ARGS__)
|
||||
#define log_warning(...) log_full(LOG_WARNING, __VA_ARGS__)
|
||||
#define log_error(...) log_full(LOG_ERR, __VA_ARGS__)
|
||||
#define log_emergency(...) log_full(getpid() == 1 ? LOG_EMERG : LOG_ERR, __VA_ARGS__)
|
||||
#define log_emergency(...) log_full(getpid_cached() == 1 ? LOG_EMERG : LOG_ERR, __VA_ARGS__)
|
||||
|
||||
/* Logging triggered by an errno-like error */
|
||||
#define log_debug_errno(error, ...) log_full_errno(LOG_DEBUG, error, __VA_ARGS__)
|
||||
|
@ -256,7 +262,7 @@ void log_assert_failed_return_realm(
|
|||
#define log_notice_errno(error, ...) log_full_errno(LOG_NOTICE, error, __VA_ARGS__)
|
||||
#define log_warning_errno(error, ...) log_full_errno(LOG_WARNING, error, __VA_ARGS__)
|
||||
#define log_error_errno(error, ...) log_full_errno(LOG_ERR, error, __VA_ARGS__)
|
||||
#define log_emergency_errno(error, ...) log_full_errno(getpid() == 1 ? LOG_EMERG : LOG_ERR, error, __VA_ARGS__)
|
||||
#define log_emergency_errno(error, ...) log_full_errno(getpid_cached() == 1 ? LOG_EMERG : LOG_ERR, error, __VA_ARGS__)
|
||||
|
||||
#ifdef LOG_TRACE
|
||||
# define log_trace(...) log_debug(__VA_ARGS__)
|
||||
|
|
|
@ -44,6 +44,7 @@ int parse_boolean(const char *v) {
|
|||
return -EINVAL;
|
||||
}
|
||||
|
||||
#if 0 /* NM_IGNORED */
|
||||
int parse_pid(const char *s, pid_t* ret_pid) {
|
||||
unsigned long ul = 0;
|
||||
pid_t pid;
|
||||
|
@ -61,12 +62,13 @@ int parse_pid(const char *s, pid_t* ret_pid) {
|
|||
if ((unsigned long) pid != ul)
|
||||
return -ERANGE;
|
||||
|
||||
if (pid <= 0)
|
||||
if (!pid_is_valid(pid))
|
||||
return -ERANGE;
|
||||
|
||||
*ret_pid = pid;
|
||||
return 0;
|
||||
}
|
||||
#endif /* NM_IGNORED */
|
||||
|
||||
int parse_mode(const char *s, mode_t *ret) {
|
||||
char *x;
|
||||
|
@ -594,4 +596,19 @@ int parse_ip_port(const char *s, uint16_t *ret) {
|
|||
|
||||
return 0;
|
||||
}
|
||||
|
||||
int parse_dev(const char *s, dev_t *ret) {
|
||||
unsigned x, y;
|
||||
dev_t d;
|
||||
|
||||
if (sscanf(s, "%u:%u", &x, &y) != 2)
|
||||
return -EINVAL;
|
||||
|
||||
d = makedev(x, y);
|
||||
if ((unsigned) major(d) != x || (unsigned) minor(d) != y)
|
||||
return -EINVAL;
|
||||
|
||||
*ret = d;
|
||||
return 0;
|
||||
}
|
||||
#endif /* NM_IGNORED */
|
||||
|
|
|
@ -30,6 +30,7 @@
|
|||
#define MODE_INVALID ((mode_t) -1)
|
||||
|
||||
int parse_boolean(const char *v) _pure_;
|
||||
int parse_dev(const char *s, dev_t *ret);
|
||||
int parse_pid(const char *s, pid_t* ret_pid);
|
||||
int parse_mode(const char *s, mode_t *ret);
|
||||
int parse_ifindex(const char *s, int *ret);
|
||||
|
|
|
@ -447,8 +447,8 @@ bool path_equal(const char *a, const char *b) {
|
|||
return path_compare(a, b) == 0;
|
||||
}
|
||||
|
||||
bool path_equal_or_files_same(const char *a, const char *b) {
|
||||
return path_equal(a, b) || files_same(a, b) > 0;
|
||||
bool path_equal_or_files_same(const char *a, const char *b, int flags) {
|
||||
return path_equal(a, b) || files_same(a, b, flags) > 0;
|
||||
}
|
||||
|
||||
char* path_join(const char *root, const char *path, const char *rest) {
|
||||
|
|
|
@ -46,7 +46,7 @@ char* path_kill_slashes(char *path);
|
|||
char* path_startswith(const char *path, const char *prefix) _pure_;
|
||||
int path_compare(const char *a, const char *b) _pure_;
|
||||
bool path_equal(const char *a, const char *b) _pure_;
|
||||
bool path_equal_or_files_same(const char *a, const char *b);
|
||||
bool path_equal_or_files_same(const char *a, const char *b, int flags);
|
||||
char* path_join(const char *root, const char *path, const char *rest);
|
||||
|
||||
static inline bool path_equal_ptr(const char *a, const char *b) {
|
||||
|
|
1051
src/systemd/src/basic/process-util.c
Normal file
1051
src/systemd/src/basic/process-util.c
Normal file
File diff suppressed because it is too large
Load diff
129
src/systemd/src/basic/process-util.h
Normal file
129
src/systemd/src/basic/process-util.h
Normal file
|
@ -0,0 +1,129 @@
|
|||
#pragma once
|
||||
|
||||
/***
|
||||
This file is part of systemd.
|
||||
|
||||
Copyright 2010 Lennart Poettering
|
||||
|
||||
systemd is free software; you can redistribute it and/or modify it
|
||||
under the terms of the GNU Lesser General Public License as published by
|
||||
the Free Software Foundation; either version 2.1 of the License, or
|
||||
(at your option) any later version.
|
||||
|
||||
systemd is distributed in the hope that it will be useful, but
|
||||
WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
Lesser General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU Lesser General Public License
|
||||
along with systemd; If not, see <http://www.gnu.org/licenses/>.
|
||||
***/
|
||||
|
||||
#include <alloca.h>
|
||||
#include <signal.h>
|
||||
#include <stdbool.h>
|
||||
#include <stddef.h>
|
||||
#include <stdio.h>
|
||||
#include <string.h>
|
||||
#include <sys/resource.h>
|
||||
#include <sys/types.h>
|
||||
|
||||
#include "format-util.h"
|
||||
#include "ioprio.h"
|
||||
#include "macro.h"
|
||||
|
||||
#define procfs_file_alloca(pid, field) \
|
||||
({ \
|
||||
pid_t _pid_ = (pid); \
|
||||
const char *_r_; \
|
||||
if (_pid_ == 0) { \
|
||||
_r_ = ("/proc/self/" field); \
|
||||
} else { \
|
||||
_r_ = alloca(strlen("/proc/") + DECIMAL_STR_MAX(pid_t) + 1 + sizeof(field)); \
|
||||
sprintf((char*) _r_, "/proc/"PID_FMT"/" field, _pid_); \
|
||||
} \
|
||||
_r_; \
|
||||
})
|
||||
|
||||
int get_process_state(pid_t pid);
|
||||
int get_process_comm(pid_t pid, char **name);
|
||||
int get_process_cmdline(pid_t pid, size_t max_length, bool comm_fallback, char **line);
|
||||
int get_process_exe(pid_t pid, char **name);
|
||||
int get_process_uid(pid_t pid, uid_t *uid);
|
||||
int get_process_gid(pid_t pid, gid_t *gid);
|
||||
int get_process_capeff(pid_t pid, char **capeff);
|
||||
int get_process_cwd(pid_t pid, char **cwd);
|
||||
int get_process_root(pid_t pid, char **root);
|
||||
int get_process_environ(pid_t pid, char **environ);
|
||||
int get_process_ppid(pid_t pid, pid_t *ppid);
|
||||
|
||||
int wait_for_terminate(pid_t pid, siginfo_t *status);
|
||||
int wait_for_terminate_and_warn(const char *name, pid_t pid, bool check_exit_code);
|
||||
|
||||
void sigkill_wait(pid_t pid);
|
||||
void sigkill_waitp(pid_t *pid);
|
||||
|
||||
int kill_and_sigcont(pid_t pid, int sig);
|
||||
|
||||
int rename_process(const char name[]);
|
||||
int is_kernel_thread(pid_t pid);
|
||||
|
||||
int getenv_for_pid(pid_t pid, const char *field, char **_value);
|
||||
|
||||
bool pid_is_alive(pid_t pid);
|
||||
bool pid_is_unwaited(pid_t pid);
|
||||
int pid_from_same_root_fs(pid_t pid);
|
||||
|
||||
bool is_main_thread(void);
|
||||
|
||||
noreturn void freeze(void);
|
||||
|
||||
bool oom_score_adjust_is_valid(int oa);
|
||||
|
||||
#ifndef PERSONALITY_INVALID
|
||||
/* personality(7) documents that 0xffffffffUL is used for querying the
|
||||
* current personality, hence let's use that here as error
|
||||
* indicator. */
|
||||
#define PERSONALITY_INVALID 0xffffffffLU
|
||||
#endif
|
||||
|
||||
unsigned long personality_from_string(const char *p);
|
||||
const char *personality_to_string(unsigned long);
|
||||
|
||||
int ioprio_class_to_string_alloc(int i, char **s);
|
||||
int ioprio_class_from_string(const char *s);
|
||||
|
||||
const char *sigchld_code_to_string(int i) _const_;
|
||||
int sigchld_code_from_string(const char *s) _pure_;
|
||||
|
||||
int sched_policy_to_string_alloc(int i, char **s);
|
||||
int sched_policy_from_string(const char *s);
|
||||
|
||||
#define PTR_TO_PID(p) ((pid_t) ((uintptr_t) p))
|
||||
#define PID_TO_PTR(p) ((void*) ((uintptr_t) p))
|
||||
|
||||
void valgrind_summary_hack(void);
|
||||
|
||||
int pid_compare_func(const void *a, const void *b);
|
||||
|
||||
#if 0 /* NM_IGNORED */
|
||||
static inline bool nice_is_valid(int n) {
|
||||
return n >= PRIO_MIN && n < PRIO_MAX;
|
||||
}
|
||||
|
||||
static inline bool ioprio_class_is_valid(int i) {
|
||||
return IN_SET(i, IOPRIO_CLASS_NONE, IOPRIO_CLASS_RT, IOPRIO_CLASS_BE, IOPRIO_CLASS_IDLE);
|
||||
}
|
||||
|
||||
static inline bool ioprio_priority_is_valid(int i) {
|
||||
return i >= 0 && i < IOPRIO_BE_NR;
|
||||
}
|
||||
|
||||
static inline bool pid_is_valid(pid_t p) {
|
||||
return p > 0;
|
||||
}
|
||||
#endif /* NM_IGNORED */
|
||||
|
||||
int ioprio_parse_priority(const char *s, int *ret);
|
||||
|
||||
pid_t getpid_cached(void);
|
|
@ -44,57 +44,64 @@
|
|||
#include "random-util.h"
|
||||
#include "time-util.h"
|
||||
|
||||
int dev_urandom(void *p, size_t n) {
|
||||
int acquire_random_bytes(void *p, size_t n, bool high_quality_required) {
|
||||
#if 0 /* NM_IGNORED */
|
||||
static int have_syscall = -1;
|
||||
|
||||
_cleanup_close_ int fd = -1;
|
||||
unsigned already_done = 0;
|
||||
int r;
|
||||
|
||||
/* Gathers some randomness from the kernel. This call will
|
||||
* never block, and will always return some data from the
|
||||
* kernel, regardless if the random pool is fully initialized
|
||||
* or not. It thus makes no guarantee for the quality of the
|
||||
* returned entropy, but is good enough for our usual usecases
|
||||
* of seeding the hash functions for hashtable */
|
||||
/* Gathers some randomness from the kernel. This call will never block. If
|
||||
* high_quality_required, it will always return some data from the kernel,
|
||||
* regardless of whether the random pool is fully initialized or not.
|
||||
* Otherwise, it will return success if at least some random bytes were
|
||||
* successfully acquired, and an error if the kernel has no entropy whatsover
|
||||
* for us. */
|
||||
|
||||
/* Use the getrandom() syscall unless we know we don't have
|
||||
* it, or when the requested size is too large for it. */
|
||||
if (have_syscall != 0 || (size_t) (int) n != n) {
|
||||
/* Use the getrandom() syscall unless we know we don't have it. */
|
||||
if (have_syscall != 0) {
|
||||
r = getrandom(p, n, GRND_NONBLOCK);
|
||||
if (r == (int) n) {
|
||||
if (r > 0) {
|
||||
have_syscall = true;
|
||||
return 0;
|
||||
}
|
||||
if ((size_t) r == n)
|
||||
return 0;
|
||||
if (!high_quality_required) {
|
||||
/* Fill in the remaining bytes using pseudorandom values */
|
||||
pseudorandom_bytes((uint8_t*) p + r, n - r);
|
||||
return 0;
|
||||
}
|
||||
|
||||
if (r < 0) {
|
||||
if (errno == ENOSYS)
|
||||
/* we lack the syscall, continue with
|
||||
* reading from /dev/urandom */
|
||||
have_syscall = false;
|
||||
else if (errno == EAGAIN)
|
||||
/* not enough entropy for now. Let's
|
||||
* remember to use the syscall the
|
||||
* next time, again, but also read
|
||||
* from /dev/urandom for now, which
|
||||
* doesn't care about the current
|
||||
* amount of entropy. */
|
||||
have_syscall = true;
|
||||
else
|
||||
return -errno;
|
||||
already_done = r;
|
||||
} else if (errno == ENOSYS)
|
||||
/* We lack the syscall, continue with reading from /dev/urandom. */
|
||||
have_syscall = false;
|
||||
else if (errno == EAGAIN) {
|
||||
/* The kernel has no entropy whatsoever. Let's remember to
|
||||
* use the syscall the next time again though.
|
||||
*
|
||||
* If high_quality_required is false, return an error so that
|
||||
* random_bytes() can produce some pseudorandom
|
||||
* bytes. Otherwise, fall back to /dev/urandom, which we know
|
||||
* is empty, but the kernel will produce some bytes for us on
|
||||
* a best-effort basis. */
|
||||
have_syscall = true;
|
||||
|
||||
if (!high_quality_required)
|
||||
return -ENODATA;
|
||||
} else
|
||||
/* too short read? */
|
||||
return -ENODATA;
|
||||
return -errno;
|
||||
}
|
||||
#else /* NM_IGNORED */
|
||||
_cleanup_close_ int fd = -1;
|
||||
unsigned already_done = 0;
|
||||
#endif /* NM_IGNORED */
|
||||
|
||||
fd = open("/dev/urandom", O_RDONLY|O_CLOEXEC|O_NOCTTY);
|
||||
if (fd < 0)
|
||||
return errno == ENOENT ? -ENOSYS : -errno;
|
||||
|
||||
return loop_read_exact(fd, p, n, true);
|
||||
return loop_read_exact(fd, (uint8_t*) p + already_done, n - already_done, true);
|
||||
}
|
||||
|
||||
void initialize_srand(void) {
|
||||
|
@ -108,12 +115,13 @@ void initialize_srand(void) {
|
|||
return;
|
||||
|
||||
#ifdef HAVE_SYS_AUXV_H
|
||||
/* The kernel provides us with 16 bytes of entropy in auxv, so let's try to make use of that to seed the
|
||||
* pseudo-random generator. It's better than nothing... */
|
||||
/* The kernel provides us with 16 bytes of entropy in auxv, so let's
|
||||
* try to make use of that to seed the pseudo-random generator. It's
|
||||
* better than nothing... */
|
||||
|
||||
auxv = (void*) getauxval(AT_RANDOM);
|
||||
if (auxv) {
|
||||
assert_cc(sizeof(x) < 16);
|
||||
assert_cc(sizeof(x) <= 16);
|
||||
memcpy(&x, auxv, sizeof(x));
|
||||
} else
|
||||
#endif
|
||||
|
@ -127,19 +135,44 @@ void initialize_srand(void) {
|
|||
srand_called = true;
|
||||
}
|
||||
|
||||
void random_bytes(void *p, size_t n) {
|
||||
/* INT_MAX gives us only 31 bits, so use 24 out of that. */
|
||||
#if RAND_MAX >= INT_MAX
|
||||
# define RAND_STEP 3
|
||||
#else
|
||||
/* SHORT_INT_MAX or lower gives at most 15 bits, we just just 8 out of that. */
|
||||
# define RAND_STEP 1
|
||||
#endif
|
||||
|
||||
void pseudorandom_bytes(void *p, size_t n) {
|
||||
uint8_t *q;
|
||||
int r;
|
||||
|
||||
r = dev_urandom(p, n);
|
||||
if (r >= 0)
|
||||
return;
|
||||
|
||||
/* If some idiot made /dev/urandom unavailable to us, he'll
|
||||
* get a PRNG instead. */
|
||||
|
||||
initialize_srand();
|
||||
|
||||
for (q = p; q < (uint8_t*) p + n; q ++)
|
||||
*q = rand();
|
||||
for (q = p; q < (uint8_t*) p + n; q += RAND_STEP) {
|
||||
unsigned rr;
|
||||
|
||||
rr = (unsigned) rand();
|
||||
|
||||
#if RAND_STEP >= 3
|
||||
if ((size_t) (q - (uint8_t*) p + 2) < n)
|
||||
q[2] = rr >> 16;
|
||||
#endif
|
||||
#if RAND_STEP >= 2
|
||||
if ((size_t) (q - (uint8_t*) p + 1) < n)
|
||||
q[1] = rr >> 8;
|
||||
#endif
|
||||
q[0] = rr;
|
||||
}
|
||||
}
|
||||
|
||||
void random_bytes(void *p, size_t n) {
|
||||
int r;
|
||||
|
||||
r = acquire_random_bytes(p, n, false);
|
||||
if (r >= 0)
|
||||
return;
|
||||
|
||||
/* If some idiot made /dev/urandom unavailable to us, or the
|
||||
* kernel has no entropy, use a PRNG instead. */
|
||||
return pseudorandom_bytes(p, n);
|
||||
}
|
||||
|
|
|
@ -19,10 +19,12 @@
|
|||
along with systemd; If not, see <http://www.gnu.org/licenses/>.
|
||||
***/
|
||||
|
||||
#include <stdbool.h>
|
||||
#include <stddef.h>
|
||||
#include <stdint.h>
|
||||
|
||||
int dev_urandom(void *p, size_t n);
|
||||
int acquire_random_bytes(void *p, size_t n, bool high_quality_required);
|
||||
void pseudorandom_bytes(void *p, size_t n);
|
||||
void random_bytes(void *p, size_t n);
|
||||
void initialize_srand(void);
|
||||
|
||||
|
|
|
@ -51,6 +51,12 @@
|
|||
#include "util.h"
|
||||
|
||||
#if 0 /* NM_IGNORED */
|
||||
#ifdef ENABLE_IDN
|
||||
# define IDN_FLAGS (NI_IDN|NI_IDN_USE_STD3_ASCII_RULES)
|
||||
#else
|
||||
# define IDN_FLAGS 0
|
||||
#endif
|
||||
|
||||
int socket_address_parse(SocketAddress *a, const char *s) {
|
||||
char *e, *n;
|
||||
unsigned u;
|
||||
|
@ -409,7 +415,7 @@ bool socket_address_equal(const SocketAddress *a, const SocketAddress *b) {
|
|||
return false;
|
||||
|
||||
if (a->sockaddr.un.sun_path[0]) {
|
||||
if (!path_equal_or_files_same(a->sockaddr.un.sun_path, b->sockaddr.un.sun_path))
|
||||
if (!path_equal_or_files_same(a->sockaddr.un.sun_path, b->sockaddr.un.sun_path, 0))
|
||||
return false;
|
||||
} else {
|
||||
if (a->size != b->size)
|
||||
|
@ -726,8 +732,7 @@ int socknameinfo_pretty(union sockaddr_union *sa, socklen_t salen, char **_ret)
|
|||
|
||||
assert(_ret);
|
||||
|
||||
r = getnameinfo(&sa->sa, salen, host, sizeof(host), NULL, 0,
|
||||
NI_IDN|NI_IDN_USE_STD3_ASCII_RULES);
|
||||
r = getnameinfo(&sa->sa, salen, host, sizeof(host), NULL, 0, IDN_FLAGS);
|
||||
if (r != 0) {
|
||||
int saved_errno = errno;
|
||||
|
||||
|
|
|
@ -27,6 +27,7 @@
|
|||
#include <sys/types.h>
|
||||
#include <sys/un.h>
|
||||
#include <linux/netlink.h>
|
||||
#include <linux/if_infiniband.h>
|
||||
#include <linux/if_packet.h>
|
||||
|
||||
#include "macro.h"
|
||||
|
@ -44,6 +45,8 @@ union sockaddr_union {
|
|||
#if 0 /* NM_IGNORED */
|
||||
struct sockaddr_vm vm;
|
||||
#endif /* NM_IGNORED */
|
||||
/* Ensure there is enough space to store Infiniband addresses */
|
||||
uint8_t ll_buffer[offsetof(struct sockaddr_ll, sll_addr) + CONST_MAX(ETH_ALEN, INFINIBAND_ALEN)];
|
||||
};
|
||||
|
||||
typedef struct SocketAddress {
|
||||
|
@ -149,6 +152,23 @@ int flush_accept(int fd);
|
|||
|
||||
struct cmsghdr* cmsg_find(struct msghdr *mh, int level, int type, socklen_t length);
|
||||
|
||||
/*
|
||||
* Certain hardware address types (e.g Infiniband) do not fit into sll_addr
|
||||
* (8 bytes) and run over the structure. This macro returns the correct size that
|
||||
* must be passed to kernel.
|
||||
*/
|
||||
#define SOCKADDR_LL_LEN(sa) \
|
||||
({ \
|
||||
const struct sockaddr_ll *_sa = &(sa); \
|
||||
size_t _mac_len = sizeof(_sa->sll_addr); \
|
||||
assert(_sa->sll_family == AF_PACKET); \
|
||||
if (be16toh(_sa->sll_hatype) == ARPHRD_ETHER) \
|
||||
_mac_len = MAX(_mac_len, (size_t) ETH_ALEN); \
|
||||
if (be16toh(_sa->sll_hatype) == ARPHRD_INFINIBAND) \
|
||||
_mac_len = MAX(_mac_len, (size_t) INFINIBAND_ALEN); \
|
||||
offsetof(struct sockaddr_ll, sll_addr) + _mac_len; \
|
||||
})
|
||||
|
||||
/* Covers only file system and abstract AF_UNIX socket addresses, but not unnamed socket addresses. */
|
||||
#define SOCKADDR_UN_LEN(sa) \
|
||||
({ \
|
||||
|
|
|
@ -217,7 +217,7 @@ char *strnappend(const char *s, const char *suffix, size_t b) {
|
|||
}
|
||||
|
||||
char *strappend(const char *s, const char *suffix) {
|
||||
return strnappend(s, suffix, suffix ? strlen(suffix) : 0);
|
||||
return strnappend(s, suffix, strlen_ptr(suffix));
|
||||
}
|
||||
|
||||
char *strjoin_real(const char *x, ...) {
|
||||
|
@ -546,7 +546,7 @@ char *ellipsize(const char *s, size_t length, unsigned percent) {
|
|||
}
|
||||
#endif /* NM_IGNORED */
|
||||
|
||||
bool nulstr_contains(const char*nulstr, const char *needle) {
|
||||
bool nulstr_contains(const char *nulstr, const char *needle) {
|
||||
const char *i;
|
||||
|
||||
if (!nulstr)
|
||||
|
@ -562,7 +562,7 @@ bool nulstr_contains(const char*nulstr, const char *needle) {
|
|||
char* strshorten(char *s, size_t l) {
|
||||
assert(s);
|
||||
|
||||
if (l < strlen(s))
|
||||
if (strnlen(s, l+1) > l)
|
||||
s[l] = 0;
|
||||
|
||||
return s;
|
||||
|
@ -639,6 +639,11 @@ char *strip_tab_ansi(char **ibuf, size_t *_isz) {
|
|||
if (!f)
|
||||
return NULL;
|
||||
|
||||
/* Note we use the _unlocked() stdio variants on f for performance
|
||||
* reasons. It's safe to do so since we created f here and it
|
||||
* doesn't leave our scope.
|
||||
*/
|
||||
|
||||
for (i = *ibuf; i < *ibuf + isz + 1; i++) {
|
||||
|
||||
switch (state) {
|
||||
|
@ -649,21 +654,21 @@ char *strip_tab_ansi(char **ibuf, size_t *_isz) {
|
|||
else if (*i == '\x1B')
|
||||
state = STATE_ESCAPE;
|
||||
else if (*i == '\t')
|
||||
fputs(" ", f);
|
||||
fputs_unlocked(" ", f);
|
||||
else
|
||||
fputc(*i, f);
|
||||
fputc_unlocked(*i, f);
|
||||
break;
|
||||
|
||||
case STATE_ESCAPE:
|
||||
if (i >= *ibuf + isz) { /* EOT */
|
||||
fputc('\x1B', f);
|
||||
fputc_unlocked('\x1B', f);
|
||||
break;
|
||||
} else if (*i == '[') {
|
||||
state = STATE_BRACKET;
|
||||
begin = i + 1;
|
||||
} else {
|
||||
fputc('\x1B', f);
|
||||
fputc(*i, f);
|
||||
fputc_unlocked('\x1B', f);
|
||||
fputc_unlocked(*i, f);
|
||||
state = STATE_OTHER;
|
||||
}
|
||||
|
||||
|
@ -673,8 +678,8 @@ char *strip_tab_ansi(char **ibuf, size_t *_isz) {
|
|||
|
||||
if (i >= *ibuf + isz || /* EOT */
|
||||
(!(*i >= '0' && *i <= '9') && *i != ';' && *i != 'm')) {
|
||||
fputc('\x1B', f);
|
||||
fputc('[', f);
|
||||
fputc_unlocked('\x1B', f);
|
||||
fputc_unlocked('[', f);
|
||||
state = STATE_OTHER;
|
||||
i = begin-1;
|
||||
} else if (*i == 'm')
|
||||
|
@ -706,7 +711,7 @@ char *strextend(char **x, ...) {
|
|||
|
||||
assert(x);
|
||||
|
||||
l = f = *x ? strlen(*x) : 0;
|
||||
l = f = strlen_ptr(*x);
|
||||
|
||||
va_start(ap, x);
|
||||
for (;;) {
|
||||
|
|
|
@ -158,7 +158,7 @@ bool string_has_cc(const char *p, const char *ok) _pure_;
|
|||
char *ellipsize_mem(const char *s, size_t old_length_bytes, size_t new_length_columns, unsigned percent);
|
||||
char *ellipsize(const char *s, size_t length, unsigned percent);
|
||||
|
||||
bool nulstr_contains(const char*nulstr, const char *needle);
|
||||
bool nulstr_contains(const char *nulstr, const char *needle);
|
||||
|
||||
char* strshorten(char *s, size_t l);
|
||||
|
||||
|
@ -200,3 +200,10 @@ DEFINE_TRIVIAL_CLEANUP_FUNC(char *, string_free_erase);
|
|||
#define _cleanup_string_free_erase_ _cleanup_(string_free_erasep)
|
||||
|
||||
bool string_is_safe(const char *p) _pure_;
|
||||
|
||||
static inline size_t strlen_ptr(const char *s) {
|
||||
if (!s)
|
||||
return 0;
|
||||
|
||||
return strlen(s);
|
||||
}
|
||||
|
|
|
@ -774,11 +774,7 @@ static int str_compare(const void *_a, const void *_b) {
|
|||
}
|
||||
|
||||
char **strv_sort(char **l) {
|
||||
|
||||
if (strv_isempty(l))
|
||||
return l;
|
||||
|
||||
qsort(l, strv_length(l), sizeof(char*), str_compare);
|
||||
qsort_safe(l, strv_length(l), sizeof(char*), str_compare);
|
||||
return l;
|
||||
}
|
||||
|
||||
|
|
|
@ -109,7 +109,7 @@ dual_timestamp* dual_timestamp_from_realtime(dual_timestamp *ts, usec_t u) {
|
|||
ts->realtime = u;
|
||||
|
||||
delta = (int64_t) now(CLOCK_REALTIME) - (int64_t) u;
|
||||
ts->monotonic = usec_sub(now(CLOCK_MONOTONIC), delta);
|
||||
ts->monotonic = usec_sub_signed(now(CLOCK_MONOTONIC), delta);
|
||||
|
||||
return ts;
|
||||
}
|
||||
|
@ -126,8 +126,8 @@ triple_timestamp* triple_timestamp_from_realtime(triple_timestamp *ts, usec_t u)
|
|||
|
||||
ts->realtime = u;
|
||||
delta = (int64_t) now(CLOCK_REALTIME) - (int64_t) u;
|
||||
ts->monotonic = usec_sub(now(CLOCK_MONOTONIC), delta);
|
||||
ts->boottime = clock_boottime_supported() ? usec_sub(now(CLOCK_BOOTTIME), delta) : USEC_INFINITY;
|
||||
ts->monotonic = usec_sub_signed(now(CLOCK_MONOTONIC), delta);
|
||||
ts->boottime = clock_boottime_supported() ? usec_sub_signed(now(CLOCK_BOOTTIME), delta) : USEC_INFINITY;
|
||||
|
||||
return ts;
|
||||
}
|
||||
|
@ -143,7 +143,7 @@ dual_timestamp* dual_timestamp_from_monotonic(dual_timestamp *ts, usec_t u) {
|
|||
|
||||
ts->monotonic = u;
|
||||
delta = (int64_t) now(CLOCK_MONOTONIC) - (int64_t) u;
|
||||
ts->realtime = usec_sub(now(CLOCK_REALTIME), delta);
|
||||
ts->realtime = usec_sub_signed(now(CLOCK_REALTIME), delta);
|
||||
|
||||
return ts;
|
||||
}
|
||||
|
@ -158,8 +158,8 @@ dual_timestamp* dual_timestamp_from_boottime_or_monotonic(dual_timestamp *ts, us
|
|||
|
||||
dual_timestamp_get(ts);
|
||||
delta = (int64_t) now(clock_boottime_or_monotonic()) - (int64_t) u;
|
||||
ts->realtime = usec_sub(ts->realtime, delta);
|
||||
ts->monotonic = usec_sub(ts->monotonic, delta);
|
||||
ts->realtime = usec_sub_signed(ts->realtime, delta);
|
||||
ts->monotonic = usec_sub_signed(ts->monotonic, delta);
|
||||
|
||||
return ts;
|
||||
}
|
||||
|
@ -244,7 +244,7 @@ usec_t timeval_load(const struct timeval *tv) {
|
|||
struct timeval *timeval_store(struct timeval *tv, usec_t u) {
|
||||
assert(tv);
|
||||
|
||||
if (u == USEC_INFINITY||
|
||||
if (u == USEC_INFINITY ||
|
||||
u / USEC_PER_SEC > TIME_T_MAX) {
|
||||
tv->tv_sec = (time_t) -1;
|
||||
tv->tv_usec = (suseconds_t) -1;
|
||||
|
@ -869,10 +869,10 @@ finish:
|
|||
if (ret > USEC_TIMESTAMP_FORMATTABLE_MAX)
|
||||
return -EINVAL;
|
||||
|
||||
if (ret > minus)
|
||||
if (ret >= minus)
|
||||
ret -= minus;
|
||||
else
|
||||
ret = 0;
|
||||
return -EINVAL;
|
||||
|
||||
*usec = ret;
|
||||
|
||||
|
@ -1014,6 +1014,16 @@ int parse_sec(const char *t, usec_t *usec) {
|
|||
return parse_time(t, usec, USEC_PER_SEC);
|
||||
}
|
||||
|
||||
int parse_sec_fix_0(const char *t, usec_t *usec) {
|
||||
t += strspn(t, WHITESPACE);
|
||||
if (streq(t, "0")) {
|
||||
*usec = USEC_INFINITY;
|
||||
return 0;
|
||||
}
|
||||
|
||||
return parse_sec(t, usec);
|
||||
}
|
||||
|
||||
int parse_nsec(const char *t, nsec_t *nsec) {
|
||||
static const struct {
|
||||
const char *suffix;
|
||||
|
@ -1358,4 +1368,23 @@ unsigned long usec_to_jiffies(usec_t u) {
|
|||
|
||||
return DIV_ROUND_UP(u , USEC_PER_SEC / hz);
|
||||
}
|
||||
|
||||
usec_t usec_shift_clock(usec_t x, clockid_t from, clockid_t to) {
|
||||
usec_t a, b;
|
||||
|
||||
if (x == USEC_INFINITY)
|
||||
return USEC_INFINITY;
|
||||
if (map_clock_id(from) == map_clock_id(to))
|
||||
return x;
|
||||
|
||||
a = now(from);
|
||||
b = now(to);
|
||||
|
||||
if (x > a)
|
||||
/* x lies in the future */
|
||||
return usec_add(b, usec_sub_unsigned(x, a));
|
||||
else
|
||||
/* x lies in the past */
|
||||
return usec_sub_unsigned(b, usec_sub_unsigned(a, x));
|
||||
}
|
||||
#endif /* NM_IGNORED */
|
||||
|
|
|
@ -133,6 +133,7 @@ int timestamp_deserialize(const char *value, usec_t *timestamp);
|
|||
int parse_timestamp(const char *t, usec_t *usec);
|
||||
|
||||
int parse_sec(const char *t, usec_t *usec);
|
||||
int parse_sec_fix_0(const char *t, usec_t *usec);
|
||||
int parse_time(const char *t, usec_t *usec, usec_t default_unit);
|
||||
int parse_nsec(const char *t, nsec_t *nsec);
|
||||
|
||||
|
@ -145,6 +146,8 @@ bool clock_boottime_supported(void);
|
|||
bool clock_supported(clockid_t clock);
|
||||
clockid_t clock_boottime_or_monotonic(void);
|
||||
|
||||
usec_t usec_shift_clock(usec_t, clockid_t from, clockid_t to);
|
||||
|
||||
#define xstrftime(buf, fmt, tm) \
|
||||
assert_message_se(strftime(buf, ELEMENTSOF(buf), fmt, tm) > 0, \
|
||||
"xstrftime: " #buf "[] must be big enough")
|
||||
|
@ -169,19 +172,23 @@ static inline usec_t usec_add(usec_t a, usec_t b) {
|
|||
return c;
|
||||
}
|
||||
|
||||
static inline usec_t usec_sub(usec_t timestamp, int64_t delta) {
|
||||
if (delta < 0)
|
||||
return usec_add(timestamp, (usec_t) (-delta));
|
||||
static inline usec_t usec_sub_unsigned(usec_t timestamp, usec_t delta) {
|
||||
|
||||
if (timestamp == USEC_INFINITY) /* Make sure infinity doesn't degrade */
|
||||
return USEC_INFINITY;
|
||||
|
||||
if (timestamp < (usec_t) delta)
|
||||
if (timestamp < delta)
|
||||
return 0;
|
||||
|
||||
return timestamp - delta;
|
||||
}
|
||||
|
||||
static inline usec_t usec_sub_signed(usec_t timestamp, int64_t delta) {
|
||||
if (delta < 0)
|
||||
return usec_add(timestamp, (usec_t) (-delta));
|
||||
else
|
||||
return usec_sub_unsigned(timestamp, (usec_t) delta);
|
||||
}
|
||||
|
||||
#if SIZEOF_TIME_T == 8
|
||||
/* The last second we can format is 31. Dec 9999, 1s before midnight, because otherwise we'd enter 5 digit year
|
||||
* territory. However, since we want to stay away from this in all timezones we take one day off. */
|
||||
|
|
|
@ -224,7 +224,7 @@ int fork_agent(pid_t *pid, const int except[], unsigned n_except, const char *pa
|
|||
/* Spawns a temporary TTY agent, making sure it goes away when
|
||||
* we go away */
|
||||
|
||||
parent_pid = getpid();
|
||||
parent_pid = getpid_cached();
|
||||
|
||||
/* First we temporarily block all signals, so that the new
|
||||
* child has them blocked initially. This way, we can be sure
|
||||
|
@ -546,7 +546,7 @@ int namespace_enter(int pidns_fd, int mntns_fd, int netns_fd, int userns_fd, int
|
|||
if (asprintf(&userns_fd_path, "/proc/self/fd/%d", userns_fd) < 0)
|
||||
return -ENOMEM;
|
||||
|
||||
r = files_same(userns_fd_path, "/proc/self/ns/user");
|
||||
r = files_same(userns_fd_path, "/proc/self/ns/user", 0);
|
||||
if (r < 0)
|
||||
return r;
|
||||
if (r)
|
||||
|
|
|
@ -110,14 +110,16 @@ static int _bind_raw_socket(int ifindex, union sockaddr_union *link,
|
|||
if (r < 0)
|
||||
return -errno;
|
||||
|
||||
link->ll.sll_family = AF_PACKET;
|
||||
link->ll.sll_protocol = htobe16(ETH_P_IP);
|
||||
link->ll.sll_ifindex = ifindex;
|
||||
link->ll.sll_hatype = htobe16(arp_type);
|
||||
link->ll.sll_halen = mac_addr_len;
|
||||
link->ll = (struct sockaddr_ll) {
|
||||
.sll_family = AF_PACKET,
|
||||
.sll_protocol = htobe16(ETH_P_IP),
|
||||
.sll_ifindex = ifindex,
|
||||
.sll_hatype = htobe16(arp_type),
|
||||
.sll_halen = mac_addr_len,
|
||||
};
|
||||
memcpy(link->ll.sll_addr, bcast_addr, mac_addr_len);
|
||||
|
||||
r = bind(s, &link->sa, sizeof(link->ll));
|
||||
r = bind(s, &link->sa, SOCKADDR_LL_LEN(link->ll));
|
||||
if (r < 0)
|
||||
return -errno;
|
||||
|
||||
|
@ -223,7 +225,7 @@ int dhcp_network_send_raw_socket(int s, const union sockaddr_union *link,
|
|||
assert(packet);
|
||||
assert(len);
|
||||
|
||||
r = sendto(s, packet, len, 0, &link->sa, sizeof(link->ll));
|
||||
r = sendto(s, packet, len, 0, &link->sa, SOCKADDR_LL_LEN(link->ll));
|
||||
if (r < 0)
|
||||
return -errno;
|
||||
|
||||
|
|
|
@ -251,10 +251,9 @@ int lldp_neighbor_parse(sd_lldp_neighbor *n) {
|
|||
log_lldp("End marker TLV not zero-sized, ignoring datagram.");
|
||||
return -EBADMSG;
|
||||
}
|
||||
if (left != 0) {
|
||||
log_lldp("Trailing garbage in datagram, ignoring datagram.");
|
||||
return -EBADMSG;
|
||||
}
|
||||
|
||||
/* Note that after processing the SD_LLDP_TYPE_END left could still be > 0
|
||||
* as the message may contain padding (see IEEE 802.1AB-2016, sec. 8.5.12) */
|
||||
|
||||
goto end_marker;
|
||||
|
||||
|
|
|
@ -928,16 +928,16 @@ int dhcp_lease_save(sd_dhcp_lease *lease, const char *lease_file) {
|
|||
|
||||
r = sd_dhcp_lease_get_dns(lease, &addresses);
|
||||
if (r > 0) {
|
||||
fputs("DNS=", f);
|
||||
fputs_unlocked("DNS=", f);
|
||||
serialize_in_addrs(f, addresses, r);
|
||||
fputs("\n", f);
|
||||
fputs_unlocked("\n", f);
|
||||
}
|
||||
|
||||
r = sd_dhcp_lease_get_ntp(lease, &addresses);
|
||||
if (r > 0) {
|
||||
fputs("NTP=", f);
|
||||
fputs_unlocked("NTP=", f);
|
||||
serialize_in_addrs(f, addresses, r);
|
||||
fputs("\n", f);
|
||||
fputs_unlocked("\n", f);
|
||||
}
|
||||
|
||||
r = sd_dhcp_lease_get_domainname(lease, &string);
|
||||
|
@ -946,9 +946,9 @@ int dhcp_lease_save(sd_dhcp_lease *lease, const char *lease_file) {
|
|||
|
||||
r = sd_dhcp_lease_get_search_domains(lease, &search_domains);
|
||||
if (r > 0) {
|
||||
fputs("DOMAIN_SEARCH_LIST=", f);
|
||||
fputs_unlocked("DOMAIN_SEARCH_LIST=", f);
|
||||
fputstrv(f, search_domains, NULL, NULL);
|
||||
fputs("\n", f);
|
||||
fputs_unlocked("\n", f);
|
||||
}
|
||||
|
||||
r = sd_dhcp_lease_get_hostname(lease, &string);
|
||||
|
|
|
@ -438,7 +438,7 @@ _public_ int sd_event_new(sd_event** ret) {
|
|||
e->watchdog_fd = e->epoll_fd = e->realtime.fd = e->boottime.fd = e->monotonic.fd = e->realtime_alarm.fd = e->boottime_alarm.fd = -1;
|
||||
e->realtime.next = e->boottime.next = e->monotonic.next = e->realtime_alarm.next = e->boottime_alarm.next = USEC_INFINITY;
|
||||
e->realtime.wakeup = e->boottime.wakeup = e->monotonic.wakeup = e->realtime_alarm.wakeup = e->boottime_alarm.wakeup = WAKEUP_CLOCK_DATA;
|
||||
e->original_pid = getpid();
|
||||
e->original_pid = getpid_cached();
|
||||
e->perturb = USEC_INFINITY;
|
||||
|
||||
r = prioq_ensure_allocated(&e->pending, pending_prioq_compare);
|
||||
|
@ -495,7 +495,7 @@ static bool event_pid_changed(sd_event *e) {
|
|||
/* We don't support people creating an event loop and keeping
|
||||
* it around over a fork(). Let's complain. */
|
||||
|
||||
return e->original_pid != getpid();
|
||||
return e->original_pid != getpid_cached();
|
||||
}
|
||||
|
||||
static void source_io_unregister(sd_event_source *s) {
|
||||
|
|
|
@ -294,7 +294,7 @@ _public_ int sd_id128_randomize(sd_id128_t *ret) {
|
|||
|
||||
assert_return(ret, -EINVAL);
|
||||
|
||||
r = dev_urandom(&t, sizeof(t));
|
||||
r = acquire_random_bytes(&t, sizeof t, true);
|
||||
if (r < 0)
|
||||
return r;
|
||||
|
||||
|
|
|
@ -1283,18 +1283,44 @@ int dns_name_apply_idna(const char *name, char **ret) {
|
|||
|
||||
#if defined(HAVE_LIBIDN2)
|
||||
int r;
|
||||
_cleanup_free_ char *t = NULL;
|
||||
|
||||
assert(name);
|
||||
assert(ret);
|
||||
|
||||
r = idn2_lookup_u8((uint8_t*) name, (uint8_t**) ret,
|
||||
r = idn2_lookup_u8((uint8_t*) name, (uint8_t**) &t,
|
||||
IDN2_NFC_INPUT | IDN2_NONTRANSITIONAL);
|
||||
if (r == IDN2_OK)
|
||||
log_debug("idn2_lookup_u8: %s → %s", name, t);
|
||||
if (r == IDN2_OK) {
|
||||
if (!startswith(name, "xn--")) {
|
||||
_cleanup_free_ char *s = NULL;
|
||||
|
||||
r = idn2_to_unicode_8z8z(t, &s, 0);
|
||||
if (r != IDN2_OK) {
|
||||
log_debug("idn2_to_unicode_8z8z(\"%s\") failed: %d/%s",
|
||||
t, r, idn2_strerror(r));
|
||||
return 0;
|
||||
}
|
||||
|
||||
if (!streq_ptr(name, s)) {
|
||||
log_debug("idn2 roundtrip failed: \"%s\" → \"%s\" → \"%s\", ignoring.",
|
||||
name, t, s);
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
|
||||
*ret = t;
|
||||
t = NULL;
|
||||
return 1; /* *ret has been written */
|
||||
else if (IN_SET(r, IDN2_TOO_BIG_DOMAIN, IDN2_TOO_BIG_LABEL))
|
||||
}
|
||||
|
||||
log_debug("idn2_lookup_u8(\"%s\") failed: %d/%s", name, r, idn2_strerror(r));
|
||||
if (r == IDN2_2HYPHEN)
|
||||
/* The name has two hypens — forbidden by IDNA2008 in some cases */
|
||||
return 0;
|
||||
if (IN_SET(r, IDN2_TOO_BIG_DOMAIN, IDN2_TOO_BIG_LABEL))
|
||||
return -ENOSPC;
|
||||
else
|
||||
return -EINVAL;
|
||||
return -EINVAL;
|
||||
#elif defined(HAVE_LIBIDN)
|
||||
_cleanup_free_ char *buf = NULL;
|
||||
size_t n = 0, allocated = 0;
|
||||
|
@ -1331,7 +1357,7 @@ int dns_name_apply_idna(const char *name, char **ret) {
|
|||
else
|
||||
buf[n++] = '.';
|
||||
|
||||
n +=r;
|
||||
n += r;
|
||||
}
|
||||
|
||||
if (n > DNS_HOSTNAME_MAX)
|
||||
|
@ -1344,7 +1370,7 @@ int dns_name_apply_idna(const char *name, char **ret) {
|
|||
*ret = buf;
|
||||
buf = NULL;
|
||||
|
||||
return (int) n;
|
||||
return 1;
|
||||
#else
|
||||
return 0;
|
||||
#endif
|
||||
|
|
Loading…
Reference in a new issue