Commit ac170893 authored by Thomas Haller's avatar Thomas Haller

systemd: update code from upstream (2018-05-18)

This is a direct dump from systemd git.

======

SYSTEMD_DIR=../systemd
COMMIT=7fbb5dd5e2cc733a83af813b13e859a8172a6046

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

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

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

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

nm_copy_sd "src/basic/alloc-util.c"
nm_copy_sd "src/basic/alloc-util.h"
nm_copy_sd "src/basic/async.h"
nm_copy_sd "src/basic/escape.c"
nm_copy_sd "src/basic/escape.h"
nm_copy_sd "src/basic/ether-addr-util.c"
nm_copy_sd "src/basic/ether-addr-util.h"
nm_copy_sd "src/basic/extract-word.c"
nm_copy_sd "src/basic/extract-word.h"
nm_copy_sd "src/basic/fileio.c"
nm_copy_sd "src/basic/fileio.h"
nm_copy_sd "src/basic/fd-util.c"
nm_copy_sd "src/basic/fd-util.h"
nm_copy_sd "src/basic/fs-util.c"
nm_copy_sd "src/basic/fs-util.h"
nm_copy_sd "src/basic/hash-funcs.c"
nm_copy_sd "src/basic/hash-funcs.h"
nm_copy_sd "src/basic/hashmap.c"
nm_copy_sd "src/basic/hashmap.h"
nm_copy_sd "src/basic/hexdecoct.c"
nm_copy_sd "src/basic/hexdecoct.h"
nm_copy_sd "src/basic/hostname-util.c"
nm_copy_sd "src/basic/hostname-util.h"
nm_copy_sd "src/basic/in-addr-util.c"
nm_copy_sd "src/basic/in-addr-util.h"
nm_copy_sd "src/basic/io-util.c"
nm_copy_sd "src/basic/io-util.h"
nm_copy_sd "src/basic/list.h"
nm_copy_sd "src/basic/log.h"
nm_copy_sd "src/basic/macro.h"
nm_copy_sd "src/basic/mempool.h"
nm_copy_sd "src/basic/mempool.c"
nm_copy_sd "src/basic/parse-util.c"
nm_copy_sd "src/basic/parse-util.h"
nm_copy_sd "src/basic/path-util.c"
nm_copy_sd "src/basic/path-util.h"
nm_copy_sd "src/basic/prioq.h"
nm_copy_sd "src/basic/prioq.c"
nm_copy_sd "src/basic/process-util.h"
nm_copy_sd "src/basic/process-util.c"
nm_copy_sd "src/basic/random-util.c"
nm_copy_sd "src/basic/random-util.h"
nm_copy_sd "src/basic/refcnt.h"
nm_copy_sd "src/basic/set.h"
nm_copy_sd "src/basic/signal-util.h"
nm_copy_sd_shared "src/basic/siphash24.c"
nm_copy_sd_shared "src/basic/siphash24.h"
nm_copy_sd "src/basic/socket-util.c"
nm_copy_sd "src/basic/socket-util.h"
nm_copy_sd "src/basic/sparse-endian.h"
nm_copy_sd "src/basic/stat-util.c"
nm_copy_sd "src/basic/stat-util.h"
nm_copy_sd "src/basic/stdio-util.h"
nm_copy_sd "src/basic/string-table.c"
nm_copy_sd "src/basic/string-table.h"
nm_copy_sd "src/basic/string-util.c"
nm_copy_sd "src/basic/string-util.h"
nm_copy_sd "src/basic/strv.c"
nm_copy_sd "src/basic/strv.h"
nm_copy_sd "src/basic/time-util.c"
nm_copy_sd "src/basic/time-util.h"
nm_copy_sd "src/basic/umask-util.h"
nm_copy_sd_shared "src/basic/unaligned.h"
nm_copy_sd "src/basic/utf8.c"
nm_copy_sd "src/basic/utf8.h"
nm_copy_sd "src/basic/util.c"
nm_copy_sd "src/basic/util.h"
nm_copy_sd "src/libsystemd-network/arp-util.c"
nm_copy_sd "src/libsystemd-network/arp-util.h"
nm_copy_sd "src/libsystemd-network/dhcp6-internal.h"
nm_copy_sd "src/libsystemd-network/dhcp6-lease-internal.h"
nm_copy_sd "src/libsystemd-network/dhcp6-network.c"
nm_copy_sd "src/libsystemd-network/dhcp6-option.c"
nm_copy_sd "src/libsystemd-network/dhcp6-protocol.h"
nm_copy_sd "src/libsystemd-network/dhcp-identifier.c"
nm_copy_sd "src/libsystemd-network/dhcp-identifier.h"
nm_copy_sd "src/libsystemd-network/dhcp-internal.h"
nm_copy_sd "src/libsystemd-network/dhcp-lease-internal.h"
nm_copy_sd "src/libsystemd-network/dhcp-network.c"
nm_copy_sd "src/libsystemd-network/dhcp-option.c"
nm_copy_sd "src/libsystemd-network/dhcp-packet.c"
nm_copy_sd "src/libsystemd-network/dhcp-protocol.h"
nm_copy_sd "src/libsystemd-network/lldp-internal.h"
nm_copy_sd "src/libsystemd-network/lldp-neighbor.c"
nm_copy_sd "src/libsystemd-network/lldp-neighbor.h"
nm_copy_sd "src/libsystemd-network/lldp-network.c"
nm_copy_sd "src/libsystemd-network/lldp-network.h"
nm_copy_sd "src/libsystemd-network/network-internal.c"
nm_copy_sd "src/libsystemd-network/network-internal.h"
nm_copy_sd "src/libsystemd-network/sd-dhcp6-client.c"
nm_copy_sd "src/libsystemd-network/sd-dhcp6-lease.c"
nm_copy_sd "src/libsystemd-network/sd-dhcp-client.c"
nm_copy_sd "src/libsystemd-network/sd-dhcp-lease.c"
nm_copy_sd "src/libsystemd-network/sd-ipv4ll.c"
nm_copy_sd "src/libsystemd-network/sd-ipv4acd.c"
nm_copy_sd "src/libsystemd-network/sd-lldp.c"
nm_copy_sd "src/libsystemd/sd-event/sd-event.c"
nm_copy_sd "src/libsystemd/sd-id128/id128-util.c"
nm_copy_sd "src/libsystemd/sd-id128/id128-util.h"
nm_copy_sd "src/libsystemd/sd-id128/sd-id128.c"
nm_copy_sd "src/shared/dns-domain.c"
nm_copy_sd "src/shared/dns-domain.h"
nm_copy_sd "src/systemd/_sd-common.h"
nm_copy_sd "src/systemd/sd-dhcp6-client.h"
nm_copy_sd "src/systemd/sd-dhcp6-lease.h"
nm_copy_sd "src/systemd/sd-dhcp-client.h"
nm_copy_sd "src/systemd/sd-dhcp-lease.h"
nm_copy_sd "src/systemd/sd-event.h"
nm_copy_sd "src/systemd/sd-ndisc.h"
nm_copy_sd "src/systemd/sd-id128.h"
nm_copy_sd "src/systemd/sd-ipv4acd.h"
nm_copy_sd "src/systemd/sd-ipv4ll.h"
nm_copy_sd "src/systemd/sd-lldp.h"
parent c4dd6208
......@@ -18,9 +18,17 @@
#define new0(t, n) ((t*) calloc((n), sizeof(t)))
#define newa(t, n) ((t*) alloca(sizeof(t)*(n)))
#define newa(t, n) \
({ \
assert(!size_multiply_overflow(sizeof(t), n)); \
(t*) alloca(sizeof(t)*(n)); \
})
#define newa0(t, n) ((t*) alloca0(sizeof(t)*(n)))
#define newa0(t, n) \
({ \
assert(!size_multiply_overflow(sizeof(t), n)); \
(t*) alloca0(sizeof(t)*(n)); \
})
#define newdup(t, p, n) ((t*) memdup_multiply(p, sizeof(t), (n)))
......
......@@ -188,7 +188,7 @@ int cunescape_one(const char *p, size_t length, char32_t *ret, bool *eight_bit)
/* C++11 style 16bit unicode */
int a[4];
unsigned i;
size_t i;
uint32_t c;
if (length != (size_t) -1 && length < 5)
......@@ -215,7 +215,7 @@ int cunescape_one(const char *p, size_t length, char32_t *ret, bool *eight_bit)
/* C++11 style 32bit unicode */
int a[8];
unsigned i;
size_t i;
char32_t c;
if (length != (size_t) -1 && length < 9)
......
......@@ -33,19 +33,23 @@ char* ether_addr_to_string(const struct ether_addr *addr, char buffer[ETHER_ADDR
return buffer;
}
bool ether_addr_equal(const struct ether_addr *a, const struct ether_addr *b) {
int ether_addr_compare(const void *a, const void *b) {
assert(a);
assert(b);
return a->ether_addr_octet[0] == b->ether_addr_octet[0] &&
a->ether_addr_octet[1] == b->ether_addr_octet[1] &&
a->ether_addr_octet[2] == b->ether_addr_octet[2] &&
a->ether_addr_octet[3] == b->ether_addr_octet[3] &&
a->ether_addr_octet[4] == b->ether_addr_octet[4] &&
a->ether_addr_octet[5] == b->ether_addr_octet[5];
return memcmp(a, b, ETH_ALEN);
}
int ether_addr_from_string(const char *s, struct ether_addr *ret, size_t *offset) {
static void ether_addr_hash_func(const void *p, struct siphash *state) {
siphash24_compress(p, sizeof(struct ether_addr), state);
}
const struct hash_ops ether_addr_hash_ops = {
.hash = ether_addr_hash_func,
.compare = ether_addr_compare
};
int ether_addr_from_string(const char *s, struct ether_addr *ret) {
size_t pos = 0, n, field;
char sep = '\0';
const char *hex = HEXDIGITS, *hexoff;
......@@ -84,31 +88,35 @@ int ether_addr_from_string(const char *s, struct ether_addr *ret, size_t *offset
assert(s);
assert(ret);
s += strspn(s, WHITESPACE);
sep = s[strspn(s, hex)];
if (sep == '\n')
return -EINVAL;
if (!strchr(":.-", sep))
return -EINVAL;
if (sep == '.') {
uint16_t shorts[3] = { 0 };
parse_fields(shorts);
if (s[pos] != '\0')
return -EINVAL;
for (n = 0; n < ELEMENTSOF(shorts); n++) {
ret->ether_addr_octet[2*n] = ((shorts[n] & (uint16_t)0xff00) >> 8);
ret->ether_addr_octet[2*n + 1] = (shorts[n] & (uint16_t)0x00ff);
}
} else {
struct ether_addr out = { .ether_addr_octet = { 0 } };
} else if (IN_SET(sep, ':', '-')) {
struct ether_addr out = ETHER_ADDR_NULL;
parse_fields(out.ether_addr_octet);
if (s[pos] != '\0')
return -EINVAL;
for (n = 0; n < ELEMENTSOF(out.ether_addr_octet); n++)
ret->ether_addr_octet[n] = out.ether_addr_octet[n];
}
if (offset)
*offset = pos;
} else
return -EINVAL;
return 0;
}
......@@ -10,13 +10,18 @@
#include <net/ethernet.h>
#include <stdbool.h>
#include "hash-funcs.h"
#define ETHER_ADDR_FORMAT_STR "%02X%02X%02X%02X%02X%02X"
#define ETHER_ADDR_FORMAT_VAL(x) (x).ether_addr_octet[0], (x).ether_addr_octet[1], (x).ether_addr_octet[2], (x).ether_addr_octet[3], (x).ether_addr_octet[4], (x).ether_addr_octet[5]
#define ETHER_ADDR_TO_STRING_MAX (3*6)
char* ether_addr_to_string(const struct ether_addr *addr, char buffer[ETHER_ADDR_TO_STRING_MAX]);
bool ether_addr_equal(const struct ether_addr *a, const struct ether_addr *b);
int ether_addr_compare(const void *a, const void *b);
static inline bool ether_addr_equal(const struct ether_addr *a, const struct ether_addr *b) {
return ether_addr_compare(a, b) == 0;
}
#define ETHER_ADDR_NULL ((const struct ether_addr){})
......@@ -24,4 +29,6 @@ static inline bool ether_addr_is_null(const struct ether_addr *addr) {
return ether_addr_equal(addr, &ETHER_ADDR_NULL);
}
int ether_addr_from_string(const char *s, struct ether_addr *ret, size_t *offset);
int ether_addr_from_string(const char *s, struct ether_addr *ret);
extern const struct hash_ops ether_addr_hash_ops;
......@@ -85,8 +85,8 @@ void safe_close_pair(int p[]) {
p[1] = safe_close(p[1]);
}
void close_many(const int fds[], unsigned n_fd) {
unsigned i;
void close_many(const int fds[], size_t n_fd) {
size_t i;
assert(fds || n_fd <= 0);
......@@ -178,8 +178,8 @@ int fd_cloexec(int fd, bool cloexec) {
return 0;
}
_pure_ static bool fd_in_set(int fd, const int fdset[], unsigned n_fdset) {
unsigned i;
_pure_ static bool fd_in_set(int fd, const int fdset[], size_t n_fdset) {
size_t i;
assert(n_fdset == 0 || fdset);
......@@ -190,7 +190,7 @@ _pure_ static bool fd_in_set(int fd, const int fdset[], unsigned n_fdset) {
return false;
}
int close_all_fds(const int except[], unsigned n_except) {
int close_all_fds(const int except[], size_t n_except) {
_cleanup_closedir_ DIR *d = NULL;
struct dirent *de;
int r = 0;
......@@ -199,15 +199,22 @@ int close_all_fds(const int except[], unsigned n_except) {
d = opendir("/proc/self/fd");
if (!d) {
int fd;
struct rlimit rl;
int fd, max_fd;
/* When /proc isn't available (for example in chroots)
* the fallback is brute forcing through the fd
/* When /proc isn't available (for example in chroots) the fallback is brute forcing through the fd
* table */
assert_se(getrlimit(RLIMIT_NOFILE, &rl) >= 0);
for (fd = 3; fd < (int) rl.rlim_max; fd ++) {
if (rl.rlim_max == 0)
return -EINVAL;
/* Let's take special care if the resource limit is set to unlimited, or actually larger than the range
* of 'int'. Let's avoid implicit overflows. */
max_fd = (rl.rlim_max == RLIM_INFINITY || rl.rlim_max > INT_MAX) ? INT_MAX : (int) (rl.rlim_max - 1);
for (fd = 3; fd >= 0; fd = fd < max_fd ? fd + 1 : -1) {
int q;
if (fd_in_set(fd, except, n_except))
......
......@@ -29,7 +29,7 @@ static inline int safe_close_above_stdio(int fd) {
return safe_close(fd);
}
void close_many(const int fds[], unsigned n_fd);
void close_many(const int fds[], size_t n_fd);
int fclose_nointr(FILE *f);
FILE* safe_fclose(FILE *f);
......@@ -59,7 +59,7 @@ DEFINE_TRIVIAL_CLEANUP_FUNC(DIR*, closedir);
int fd_nonblock(int fd, bool nonblock);
int fd_cloexec(int fd, bool cloexec);
int close_all_fds(const int except[], unsigned n_except);
int close_all_fds(const int except[], size_t n_except);
int same_fd(int a, int b);
......
......@@ -50,6 +50,7 @@ int write_string_stream_ts(
struct timespec *ts) {
bool needs_nl;
int r;
assert(f);
assert(line);
......@@ -74,6 +75,13 @@ int write_string_stream_ts(
if (fputc('\n', f) == EOF)
return -errno;
if (flags & WRITE_STRING_FILE_SYNC)
r = fflush_sync_and_check(f);
else
r = fflush_and_check(f);
if (r < 0)
return r;
if (ts) {
struct timespec twice[2] = {*ts, *ts};
......@@ -81,10 +89,7 @@ int write_string_stream_ts(
return -errno;
}
if (flags & WRITE_STRING_FILE_SYNC)
return fflush_sync_and_check(f);
else
return fflush_and_check(f);
return 0;
}
static int write_string_file_atomic(
......
......@@ -241,6 +241,21 @@ int fchmod_umask(int fd, mode_t m) {
return r;
}
int fchmod_opath(int fd, mode_t m) {
char procfs_path[strlen("/proc/self/fd/") + DECIMAL_STR_MAX(int)];
/* This function operates also on fd that might have been opened with
* O_PATH. Indeed fchmodat() doesn't have the AT_EMPTY_PATH flag like
* fchownat() does. */
xsprintf(procfs_path, "/proc/self/fd/%i", fd);
if (chmod(procfs_path, m) < 0)
return -errno;
return 0;
}
int fd_warn_permissions(const char *path, int fd) {
struct stat st;
......@@ -904,25 +919,12 @@ int chase_symlinks(const char *path, const char *original_root, unsigned flags,
return exists;
chased_one:
if (ret) {
char *c;
if (done) {
if (todo) {
c = strjoin(done, todo);
if (!c)
return -ENOMEM;
} else
c = TAKE_PTR(done);
} else {
if (todo)
c = strdup(todo);
else
c = strdup("/");
if (!c)
return -ENOMEM;
}
c = strjoin(strempty(done), todo);
if (!c)
return -ENOMEM;
*ret = c;
}
......
......@@ -33,6 +33,7 @@ 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_umask(int fd, mode_t mode);
int fchmod_opath(int fd, mode_t m);
int fd_warn_permissions(const char *path, int fd);
......
......@@ -281,7 +281,7 @@ static const struct hashmap_type_info hashmap_type_info[_HASHMAP_TYPE_MAX] = {
},
};
#ifdef VALGRIND
#if VALGRIND
__attribute__((destructor)) static void cleanup_pools(void) {
_cleanup_free_ char *t = NULL;
int r;
......
......@@ -77,33 +77,69 @@ char *hexmem(const void *p, size_t l) {
return r;
}
int unhexmem(const char *p, size_t l, void **mem, size_t *len) {
_cleanup_free_ uint8_t *r = NULL;
uint8_t *z;
static int unhex_next(const char **p, size_t *l) {
int r;
assert(p);
assert(l);
/* Find the next non-whitespace character, and decode it. We
* greedily skip all preceeding and all following whitespace. */
for (;;) {
if (*l == 0)
return -EPIPE;
if (!strchr(WHITESPACE, **p))
break;
/* Skip leading whitespace */
(*p)++, (*l)--;
}
r = unhexchar(**p);
if (r < 0)
return r;
for (;;) {
(*p)++, (*l)--;
if (*l == 0 || !strchr(WHITESPACE, **p))
break;
/* Skip following whitespace */
}
return r;
}
int unhexmem(const char *p, size_t l, void **ret, size_t *ret_len) {
_cleanup_free_ uint8_t *buf = NULL;
const char *x;
uint8_t *z;
assert(mem);
assert(len);
assert(ret);
assert(ret_len);
assert(p || l == 0);
if (l == (size_t) -1)
l = strlen(p);
if (l % 2 != 0)
return -EINVAL;
z = r = malloc((l + 1) / 2 + 1);
if (!r)
/* Note that the calculation of memory size is an upper boundary, as we ignore whitespace while decoding */
buf = malloc((l + 1) / 2 + 1);
if (!buf)
return -ENOMEM;
for (x = p; x < p + l; x += 2) {
for (x = p, z = buf;;) {
int a, b;
a = unhexchar(x[0]);
a = unhex_next(&x, &l);
if (a == -EPIPE) /* End of string */
break;
if (a < 0)
return a;
b = unhexchar(x[1]);
b = unhex_next(&x, &l);
if (b < 0)
return b;
......@@ -112,8 +148,8 @@ int unhexmem(const char *p, size_t l, void **mem, size_t *len) {
*z = 0;
*mem = TAKE_PTR(r);
*len = (l + 1) / 2;
*ret_len = (size_t) (z - buf);
*ret = TAKE_PTR(buf);
return 0;
}
......@@ -181,7 +217,7 @@ char *base32hexmem(const void *p, size_t l, bool padding) {
for (x = p; x < (const uint8_t*) p + (l / 5) * 5; x += 5) {
/* x[0] == XXXXXXXX; x[1] == YYYYYYYY; x[2] == ZZZZZZZZ
x[3] == QQQQQQQQ; x[4] == WWWWWWWW */
* x[3] == QQQQQQQQ; x[4] == WWWWWWWW */
*(z++) = base32hexchar(x[0] >> 3); /* 000XXXXX */
*(z++) = base32hexchar((x[0] & 7) << 2 | x[1] >> 6); /* 000XXXYY */
*(z++) = base32hexchar((x[1] & 63) >> 1); /* 000YYYYY */
......@@ -281,7 +317,7 @@ int unbase32hexmem(const char *p, size_t l, bool padding, void **mem, size_t *_l
}
/* a group of eight input bytes needs five output bytes, in case of
padding we need to add some extra bytes */
* padding we need to add some extra bytes */
len = (l / 8) * 5;
switch (l % 8) {
......@@ -309,7 +345,7 @@ int unbase32hexmem(const char *p, size_t l, bool padding, void **mem, size_t *_l
for (x = p; x < p + (l / 8) * 8; x += 8) {
/* a == 000XXXXX; b == 000YYYYY; c == 000ZZZZZ; d == 000WWWWW
e == 000SSSSS; f == 000QQQQQ; g == 000VVVVV; h == 000RRRRR */
* e == 000SSSSS; f == 000QQQQQ; g == 000VVVVV; h == 000RRRRR */
a = unbase32hexchar(x[0]);
if (a < 0)
return -EINVAL;
......@@ -665,7 +701,7 @@ int unbase64mem(const char *p, size_t l, void **ret, size_t *ret_size) {
l = strlen(p);
/* A group of four input bytes needs three output bytes, in case of padding we need to add two or three extra
bytes. Note that this calculation is an upper boundary, as we ignore whitespace while decoding */
* bytes. Note that this calculation is an upper boundary, as we ignore whitespace while decoding */
len = (l / 4) * 3 + (l % 4 != 0 ? (l % 4) - 1 : 0);
buf = malloc(len + 1);
......@@ -733,9 +769,7 @@ int unbase64mem(const char *p, size_t l, void **ret, size_t *ret_size) {
*z = 0;
if (ret_size)
*ret_size = (size_t) (z - buf);
*ret_size = (size_t) (z - buf);
*ret = TAKE_PTR(buf);
return 0;
......
......@@ -28,9 +28,8 @@ int fd_wait_for_event(int fd, int event, usec_t timeout);
ssize_t sparse_write(int fd, const void *p, size_t sz, size_t run_length);
static inline size_t IOVEC_TOTAL_SIZE(const struct iovec *i, unsigned n) {
unsigned j;
size_t r = 0;
static inline size_t IOVEC_TOTAL_SIZE(const struct iovec *i, size_t n) {
size_t j, r = 0;
for (j = 0; j < n; j++)
r += i[j].iov_len;
......@@ -38,8 +37,8 @@ static inline size_t IOVEC_TOTAL_SIZE(const struct iovec *i, unsigned n) {
return r;
}
static inline size_t IOVEC_INCREMENT(struct iovec *i, unsigned n, size_t k) {
unsigned j;
static inline size_t IOVEC_INCREMENT(struct iovec *i, size_t n, size_t k) {
size_t j;
for (j = 0; j < n; j++) {
size_t sub;
......
......@@ -15,12 +15,12 @@
struct pool {
struct pool *next;
unsigned n_tiles;
unsigned n_used;
size_t n_tiles;
size_t n_used;
};
void* mempool_alloc_tile(struct mempool *mp) {
unsigned i;
size_t i;
/* When a tile is released we add it to the list and simply
* place the next pointer at its offset 0. */
......@@ -38,8 +38,7 @@ void* mempool_alloc_tile(struct mempool *mp) {
if (_unlikely_(!mp->first_pool) ||
_unlikely_(mp->first_pool->n_used >= mp->first_pool->n_tiles)) {
unsigned n;
size_t size;
size_t size, n;
struct pool *p;
n = mp->first_pool ? mp->first_pool->n_tiles : 0;
......@@ -77,7 +76,7 @@ void mempool_free_tile(struct mempool *mp, void *p) {
mp->freelist = p;
}
#ifdef VALGRIND
#if VALGRIND
void mempool_drop(struct mempool *mp) {
struct pool *p = mp->first_pool;
......
......@@ -30,6 +30,6 @@ static struct mempool pool_name = { \
}
#ifdef VALGRIND
#if VALGRIND
void mempool_drop(struct mempool *mp);
#endif
......@@ -11,12 +11,14 @@
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <sys/socket.h>
#include "alloc-util.h"
#include "errno-list.h"
#include "extract-word.h"
#include "locale-util.h"
#include "macro.h"
#include "missing.h"
#include "parse-util.h"
#include "process-util.h"
#include "string-util.h"
......@@ -93,6 +95,30 @@ int parse_ifindex(const char *s, int *ret) {
return 0;
}
int parse_mtu(int family, const char *s, uint32_t *ret) {
uint64_t u;
size_t m;
int r;
r = parse_size(s, 1024, &u);
if (r < 0)
return r;
if (u > UINT32_MAX)
return -ERANGE;
if (family == AF_INET6)
m = IPV6_MIN_MTU; /* This is 1280 */
else
m = IPV4_MIN_MTU; /* For all other protocols, including 'unspecified' we assume the IPv4 minimal MTU */
if (u < m)
return -ERANGE;
*ret = (uint32_t) u;
return 0;
}
int parse_size(const char *t, uint64_t base, uint64_t *size) {
/* Soo, sometimes we want to parse IEC binary suffixes, and
......@@ -650,3 +676,20 @@ int parse_dev(const char *s, dev_t *ret) {
*ret = d;
return 0;
}
int parse_oom_score_adjust(const char *s, int *ret) {
int r, v;
assert(s);
assert(ret);
r = safe_atoi(s, &v);
if (r < 0)
return r;
if (v < OOM_SCORE_ADJ_MIN || v > OOM_SCORE_ADJ_MAX)
return -ERANGE;
*ret = v;
return 0;
}
......@@ -22,6 +22,7 @@ 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);
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);
......@@ -117,3 +118,5 @@ int parse_percent(const char *p);
int parse_nice(const char *p, int *ret);
int parse_ip_port(const char *s, uint16_t *ret);
int parse_oom_score_adjust(const char *s, int *ret);
......@@ -685,11 +685,12 @@ int parse_path_argument_and_warn(const char *path, bool suppress_root, char **ar
return log_error_errno(r, "Failed to parse path \"%s\" and make it absolute: %m", path);
path_kill_slashes(p);
if (suppress_root && path_equal(p, "/"))
if (suppress_root && empty_or_root(p))
p = mfree(p);
free(*arg);
*arg = p;
return 0;
}
......
......@@ -164,3 +164,6 @@ static inline const char *skip_dev_prefix(const char *p) {
}
bool empty_or_root(const char *root);
static inline const char *empty_to_root(const char *path) {
return isempty(path) ? "/" : path;
}
......@@ -880,7 +880,7 @@ int getenv_for_pid(pid_t pid, const char *field, char **ret) {
do {
char line[LINE_MAX];
unsigned i;
size_t i;
for (i = 0; i < sizeof(line)-1; i++) {
int c;
......@@ -1375,9 +1375,9 @@ int safe_fork_full(
return 0;
}
int fork_agent(const char *name, const int except[], unsigned n_except, pid_t *ret_pid, const char *path, ...) {
int fork_agent(const char *name, const int except[], size_t n_except, pid_t *ret_pid, const char *path, ...) {
bool stdout_is_tty, stderr_is_tty;
unsigned n, i;
size_t n, i;
va_list ap;
char **l;
int r;
......@@ -1433,7 +1433,7 @@ int fork_agent(const char *name, const int except[], unsigned n_except, pid_t *r
va_end(ap);
/* Allocate strv */
l = alloca(sizeof(char *) * (n + 1));
l = newa(char*, n + 1);
/* Fill in arguments */
va_start(ap, path);
......@@ -1445,6 +1445,15 @@ int fork_agent(const char *name, const int except[], unsigned n_except, pid_t *r
_exit(EXIT_FAILURE);
}
int set_oom_score_adjust(int value) {
char t[DECIMAL_STR_MAX(int)];
sprintf(t, "%i", value);
return write_string_file("/proc/self/oom_score_adj", t,
WRITE_STRING_FILE_VERIFY_ON_FAILURE|WRITE_STRING_FILE_DISABLE_BUFFER);
}
static const char *const ioprio_class_table[] = {
[IOPRIO_CLASS_NONE] = "none",
[IOPRIO_CLASS_RT] = "realtime",
......
......@@ -171,7 +171,9 @@ static inline int safe_fork(const char *name, ForkFlags flags, pid_t *ret_pid) {
return safe_fork_full(name, NULL, 0, flags, ret_pid);
}
int fork_agent(const char *name, const int except[], unsigned n_except, pid_t *pid, const char *path, ...);
int fork_agent(const char *name, const int except[], size_t n_except, pid_t *pid, const char *path, ...);
int set_oom_score_adjust(int value);
#if SIZEOF_PID_T == 4
/* The highest possibly (theoretic) pid_t value on this architecture. */
......
......@@ -35,7 +35,7 @@ int acquire_random_bytes(void *p, size_t n, bool high_quality_required) {
static int have_syscall = -1;
_cleanup_close_ int fd = -1;