dhcp: update systemd DHCP code
This is a direct dump from systemd git on 2015-03-23, git commit eaa5251d9167027. Only relevant files were included. SYSTEMD_DIR=../systemd COMMIT=eaa5251d9167027275d8275862e23e0b7dc8866e ( cd "$SYSTEMD_DIR" git checkout "$COMMIT" git reset --hard git clean -fdx ) /bin/cp "$SYSTEMD_DIR"/src/libsystemd/sd-id128/sd-id128.c ./src/dhcp-manager/systemd-dhcp/src/libsystemd/sd-id128/sd-id128.c /bin/cp "$SYSTEMD_DIR"/src/libsystemd-network/dhcp-identifier.c ./src/dhcp-manager/systemd-dhcp/src/libsystemd-network/dhcp-identifier.c /bin/cp "$SYSTEMD_DIR"/src/libsystemd-network/dhcp-identifier.h ./src/dhcp-manager/systemd-dhcp/src/libsystemd-network/dhcp-identifier.h /bin/cp "$SYSTEMD_DIR"/src/libsystemd-network/dhcp-internal.h ./src/dhcp-manager/systemd-dhcp/src/libsystemd-network/dhcp-internal.h /bin/cp "$SYSTEMD_DIR"/src/libsystemd-network/dhcp-lease-internal.h ./src/dhcp-manager/systemd-dhcp/src/libsystemd-network/dhcp-lease-internal.h /bin/cp "$SYSTEMD_DIR"/src/libsystemd-network/dhcp-network.c ./src/dhcp-manager/systemd-dhcp/src/libsystemd-network/dhcp-network.c /bin/cp "$SYSTEMD_DIR"/src/libsystemd-network/dhcp-option.c ./src/dhcp-manager/systemd-dhcp/src/libsystemd-network/dhcp-option.c /bin/cp "$SYSTEMD_DIR"/src/libsystemd-network/dhcp-packet.c ./src/dhcp-manager/systemd-dhcp/src/libsystemd-network/dhcp-packet.c /bin/cp "$SYSTEMD_DIR"/src/libsystemd-network/dhcp-protocol.h ./src/dhcp-manager/systemd-dhcp/src/libsystemd-network/dhcp-protocol.h /bin/cp "$SYSTEMD_DIR"/src/libsystemd-network/dhcp6-internal.h ./src/dhcp-manager/systemd-dhcp/src/libsystemd-network/dhcp6-internal.h /bin/cp "$SYSTEMD_DIR"/src/libsystemd-network/dhcp6-lease-internal.h ./src/dhcp-manager/systemd-dhcp/src/libsystemd-network/dhcp6-lease-internal.h /bin/cp "$SYSTEMD_DIR"/src/libsystemd-network/dhcp6-network.c ./src/dhcp-manager/systemd-dhcp/src/libsystemd-network/dhcp6-network.c /bin/cp "$SYSTEMD_DIR"/src/libsystemd-network/dhcp6-option.c ./src/dhcp-manager/systemd-dhcp/src/libsystemd-network/dhcp6-option.c /bin/cp "$SYSTEMD_DIR"/src/libsystemd-network/dhcp6-protocol.h ./src/dhcp-manager/systemd-dhcp/src/libsystemd-network/dhcp6-protocol.h /bin/cp "$SYSTEMD_DIR"/src/libsystemd-network/network-internal.c ./src/dhcp-manager/systemd-dhcp/src/libsystemd-network/network-internal.c /bin/cp "$SYSTEMD_DIR"/src/libsystemd-network/network-internal.h ./src/dhcp-manager/systemd-dhcp/src/libsystemd-network/network-internal.h /bin/cp "$SYSTEMD_DIR"/src/libsystemd-network/sd-dhcp-client.c ./src/dhcp-manager/systemd-dhcp/src/libsystemd-network/sd-dhcp-client.c /bin/cp "$SYSTEMD_DIR"/src/libsystemd-network/sd-dhcp-lease.c ./src/dhcp-manager/systemd-dhcp/src/libsystemd-network/sd-dhcp-lease.c /bin/cp "$SYSTEMD_DIR"/src/libsystemd-network/sd-dhcp6-client.c ./src/dhcp-manager/systemd-dhcp/src/libsystemd-network/sd-dhcp6-client.c /bin/cp "$SYSTEMD_DIR"/src/libsystemd-network/sd-dhcp6-lease.c ./src/dhcp-manager/systemd-dhcp/src/libsystemd-network/sd-dhcp6-lease.c /bin/cp "$SYSTEMD_DIR"/src/shared/async.h ./src/dhcp-manager/systemd-dhcp/src/shared/async.h /bin/cp "$SYSTEMD_DIR"/src/shared/fileio.c ./src/dhcp-manager/systemd-dhcp/src/shared/fileio.c /bin/cp "$SYSTEMD_DIR"/src/shared/fileio.h ./src/dhcp-manager/systemd-dhcp/src/shared/fileio.h /bin/cp "$SYSTEMD_DIR"/src/shared/list.h ./src/dhcp-manager/systemd-dhcp/src/shared/list.h /bin/cp "$SYSTEMD_DIR"/src/shared/log.h ./src/dhcp-manager/systemd-dhcp/src/shared/log.h /bin/cp "$SYSTEMD_DIR"/src/shared/macro.h ./src/dhcp-manager/systemd-dhcp/src/shared/macro.h /bin/cp "$SYSTEMD_DIR"/src/shared/path-util.c ./src/dhcp-manager/systemd-dhcp/src/shared/path-util.c /bin/cp "$SYSTEMD_DIR"/src/shared/path-util.h ./src/dhcp-manager/systemd-dhcp/src/shared/path-util.h /bin/cp "$SYSTEMD_DIR"/src/shared/refcnt.h ./src/dhcp-manager/systemd-dhcp/src/shared/refcnt.h /bin/cp "$SYSTEMD_DIR"/src/shared/siphash24.c ./src/dhcp-manager/systemd-dhcp/src/shared/siphash24.c /bin/cp "$SYSTEMD_DIR"/src/shared/siphash24.h ./src/dhcp-manager/systemd-dhcp/src/shared/siphash24.h /bin/cp "$SYSTEMD_DIR"/src/shared/socket-util.h ./src/dhcp-manager/systemd-dhcp/src/shared/socket-util.h /bin/cp "$SYSTEMD_DIR"/src/shared/sparse-endian.h ./src/dhcp-manager/systemd-dhcp/src/shared/sparse-endian.h /bin/cp "$SYSTEMD_DIR"/src/shared/strv.c ./src/dhcp-manager/systemd-dhcp/src/shared/strv.c /bin/cp "$SYSTEMD_DIR"/src/shared/strv.h ./src/dhcp-manager/systemd-dhcp/src/shared/strv.h /bin/cp "$SYSTEMD_DIR"/src/shared/time-util.c ./src/dhcp-manager/systemd-dhcp/src/shared/time-util.c /bin/cp "$SYSTEMD_DIR"/src/shared/time-util.h ./src/dhcp-manager/systemd-dhcp/src/shared/time-util.h /bin/cp "$SYSTEMD_DIR"/src/shared/utf8.c ./src/dhcp-manager/systemd-dhcp/src/shared/utf8.c /bin/cp "$SYSTEMD_DIR"/src/shared/utf8.h ./src/dhcp-manager/systemd-dhcp/src/shared/utf8.h /bin/cp "$SYSTEMD_DIR"/src/shared/util.c ./src/dhcp-manager/systemd-dhcp/src/shared/util.c /bin/cp "$SYSTEMD_DIR"/src/shared/util.h ./src/dhcp-manager/systemd-dhcp/src/shared/util.h /bin/cp "$SYSTEMD_DIR"/src/shared/unaligned.h ./src/dhcp-manager/systemd-dhcp/src/shared/unaligned.h /bin/cp "$SYSTEMD_DIR"/src/shared/in-addr-util.c ./src/dhcp-manager/systemd-dhcp/src/shared/in-addr-util.c /bin/cp "$SYSTEMD_DIR"/src/shared/in-addr-util.h ./src/dhcp-manager/systemd-dhcp/src/shared/in-addr-util.h /bin/cp "$SYSTEMD_DIR"/src/systemd/_sd-common.h ./src/dhcp-manager/systemd-dhcp/src/systemd/_sd-common.h /bin/cp "$SYSTEMD_DIR"/src/systemd/sd-dhcp-client.h ./src/dhcp-manager/systemd-dhcp/src/systemd/sd-dhcp-client.h /bin/cp "$SYSTEMD_DIR"/src/systemd/sd-dhcp-lease.h ./src/dhcp-manager/systemd-dhcp/src/systemd/sd-dhcp-lease.h /bin/cp "$SYSTEMD_DIR"/src/systemd/sd-dhcp6-client.h ./src/dhcp-manager/systemd-dhcp/src/systemd/sd-dhcp6-client.h /bin/cp "$SYSTEMD_DIR"/src/systemd/sd-dhcp6-lease.h ./src/dhcp-manager/systemd-dhcp/src/systemd/sd-dhcp6-lease.h /bin/cp "$SYSTEMD_DIR"/src/systemd/sd-event.h ./src/dhcp-manager/systemd-dhcp/src/systemd/sd-event.h /bin/cp "$SYSTEMD_DIR"/src/systemd/sd-id128.h ./src/dhcp-manager/systemd-dhcp/src/systemd/sd-id128.h
This commit is contained in:
@@ -1469,7 +1469,7 @@ static int client_receive_message_udp(sd_event_source *s, int fd,
|
||||
_cleanup_free_ DHCPMessage *message = NULL;
|
||||
int buflen = 0, len, r;
|
||||
const struct ether_addr zero_mac = { { 0, 0, 0, 0, 0, 0 } };
|
||||
const struct ether_addr *expected_chaddr = NULL;
|
||||
bool expect_chaddr;
|
||||
uint8_t expected_hlen = 0;
|
||||
|
||||
assert(s);
|
||||
@@ -1514,11 +1514,11 @@ static int client_receive_message_udp(sd_event_source *s, int fd,
|
||||
|
||||
if (client->arp_type == ARPHRD_ETHER) {
|
||||
expected_hlen = ETH_ALEN;
|
||||
expected_chaddr = (const struct ether_addr *) &client->mac_addr;
|
||||
expect_chaddr = true;
|
||||
} else {
|
||||
/* Non-ethernet links expect zero chaddr */
|
||||
expected_hlen = 0;
|
||||
expected_chaddr = &zero_mac;
|
||||
expect_chaddr = false;
|
||||
}
|
||||
|
||||
if (message->hlen != expected_hlen) {
|
||||
@@ -1526,7 +1526,10 @@ static int client_receive_message_udp(sd_event_source *s, int fd,
|
||||
return 0;
|
||||
}
|
||||
|
||||
if (memcmp(&message->chaddr[0], expected_chaddr, ETH_ALEN)) {
|
||||
if (memcmp(&message->chaddr[0], expect_chaddr ?
|
||||
(void *)&client->mac_addr :
|
||||
(void *)&zero_mac,
|
||||
ETH_ALEN)) {
|
||||
log_dhcp_client(client, "received chaddr does not match "
|
||||
"expected: ignoring");
|
||||
return 0;
|
||||
|
@@ -108,9 +108,9 @@ _public_ int sd_id128_get_machine(sd_id128_t *ret) {
|
||||
static thread_local bool saved_machine_id_valid = false;
|
||||
_cleanup_close_ int fd = -1;
|
||||
char buf[33];
|
||||
ssize_t k;
|
||||
unsigned j;
|
||||
sd_id128_t t;
|
||||
int r;
|
||||
|
||||
assert_return(ret, -EINVAL);
|
||||
|
||||
@@ -123,13 +123,9 @@ _public_ int sd_id128_get_machine(sd_id128_t *ret) {
|
||||
if (fd < 0)
|
||||
return -errno;
|
||||
|
||||
k = loop_read(fd, buf, 33, false);
|
||||
if (k < 0)
|
||||
return (int) k;
|
||||
|
||||
if (k != 33)
|
||||
return -EIO;
|
||||
|
||||
r = loop_read_exact(fd, buf, 33, false);
|
||||
if (r < 0)
|
||||
return r;
|
||||
if (buf[32] !='\n')
|
||||
return -EIO;
|
||||
|
||||
@@ -157,10 +153,10 @@ _public_ int sd_id128_get_boot(sd_id128_t *ret) {
|
||||
static thread_local bool saved_boot_id_valid = false;
|
||||
_cleanup_close_ int fd = -1;
|
||||
char buf[36];
|
||||
ssize_t k;
|
||||
unsigned j;
|
||||
sd_id128_t t;
|
||||
char *p;
|
||||
int r;
|
||||
|
||||
assert_return(ret, -EINVAL);
|
||||
|
||||
@@ -173,22 +169,19 @@ _public_ int sd_id128_get_boot(sd_id128_t *ret) {
|
||||
if (fd < 0)
|
||||
return -errno;
|
||||
|
||||
k = loop_read(fd, buf, 36, false);
|
||||
if (k < 0)
|
||||
return (int) k;
|
||||
|
||||
if (k != 36)
|
||||
return -EIO;
|
||||
r = loop_read_exact(fd, buf, 36, false);
|
||||
if (r < 0)
|
||||
return r;
|
||||
|
||||
for (j = 0, p = buf; j < 16; j++) {
|
||||
int a, b;
|
||||
|
||||
if (p >= buf + k - 1)
|
||||
if (p >= buf + 35)
|
||||
return -EIO;
|
||||
|
||||
if (*p == '-') {
|
||||
p++;
|
||||
if (p >= buf + k - 1)
|
||||
if (p >= buf + 35)
|
||||
return -EIO;
|
||||
}
|
||||
|
||||
|
@@ -23,6 +23,7 @@
|
||||
|
||||
#include <stdbool.h>
|
||||
#include <stdarg.h>
|
||||
#include <stdlib.h>
|
||||
#include <syslog.h>
|
||||
#include <sys/signalfd.h>
|
||||
#include <errno.h>
|
||||
|
@@ -400,12 +400,18 @@ char* path_startswith(const char *path, const char *prefix) {
|
||||
}
|
||||
}
|
||||
|
||||
bool path_equal(const char *a, const char *b) {
|
||||
int path_compare(const char *a, const char *b) {
|
||||
int d;
|
||||
|
||||
assert(a);
|
||||
assert(b);
|
||||
|
||||
if ((a[0] == '/') != (b[0] == '/'))
|
||||
return false;
|
||||
/* A relative path and an abolute path must not compare as equal.
|
||||
* Which one is sorted before the other does not really matter.
|
||||
* Here a relative path is ordered before an absolute path. */
|
||||
d = (a[0] == '/') - (b[0] == '/');
|
||||
if (d)
|
||||
return d;
|
||||
|
||||
for (;;) {
|
||||
size_t j, k;
|
||||
@@ -414,25 +420,36 @@ bool path_equal(const char *a, const char *b) {
|
||||
b += strspn(b, "/");
|
||||
|
||||
if (*a == 0 && *b == 0)
|
||||
return true;
|
||||
return 0;
|
||||
|
||||
if (*a == 0 || *b == 0)
|
||||
return false;
|
||||
/* Order prefixes first: "/foo" before "/foo/bar" */
|
||||
if (*a == 0)
|
||||
return -1;
|
||||
if (*b == 0)
|
||||
return 1;
|
||||
|
||||
j = strcspn(a, "/");
|
||||
k = strcspn(b, "/");
|
||||
|
||||
if (j != k)
|
||||
return false;
|
||||
/* Alphabetical sort: "/foo/aaa" before "/foo/b" */
|
||||
d = memcmp(a, b, MIN(j, k));
|
||||
if (d)
|
||||
return (d > 0) - (d < 0); /* sign of d */
|
||||
|
||||
if (memcmp(a, b, j) != 0)
|
||||
return false;
|
||||
/* Sort "/foo/a" before "/foo/aaa" */
|
||||
d = (j > k) - (j < k); /* sign of (j - k) */
|
||||
if (d)
|
||||
return d;
|
||||
|
||||
a += j;
|
||||
b += k;
|
||||
}
|
||||
}
|
||||
|
||||
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;
|
||||
}
|
||||
@@ -457,9 +474,9 @@ int path_is_mount_point(const char *t, bool allow_symlink) {
|
||||
|
||||
union file_handle_union h = FILE_HANDLE_INIT;
|
||||
int mount_id = -1, mount_id_parent = -1;
|
||||
_cleanup_free_ char *parent = NULL;
|
||||
struct stat a, b;
|
||||
int r;
|
||||
_cleanup_close_ int fd = -1;
|
||||
bool nosupp = false;
|
||||
|
||||
/* We are not actually interested in the file handles, but
|
||||
@@ -469,7 +486,15 @@ int path_is_mount_point(const char *t, bool allow_symlink) {
|
||||
if (path_equal(t, "/"))
|
||||
return 1;
|
||||
|
||||
r = name_to_handle_at(AT_FDCWD, t, &h.handle, &mount_id, allow_symlink ? AT_SYMLINK_FOLLOW : 0);
|
||||
fd = openat(AT_FDCWD, t, O_RDONLY|O_NONBLOCK|O_DIRECTORY|O_CLOEXEC|(allow_symlink ? 0 : O_PATH));
|
||||
if (fd < 0) {
|
||||
if (errno == ENOENT)
|
||||
return 0;
|
||||
|
||||
return -errno;
|
||||
}
|
||||
|
||||
r = name_to_handle_at(fd, "", &h.handle, &mount_id, AT_EMPTY_PATH);
|
||||
if (r < 0) {
|
||||
if (errno == ENOSYS)
|
||||
/* This kernel does not support name_to_handle_at()
|
||||
@@ -486,12 +511,9 @@ int path_is_mount_point(const char *t, bool allow_symlink) {
|
||||
return -errno;
|
||||
}
|
||||
|
||||
r = path_get_parent(t, &parent);
|
||||
if (r < 0)
|
||||
return r;
|
||||
|
||||
h.handle.handle_bytes = MAX_HANDLE_SZ;
|
||||
r = name_to_handle_at(AT_FDCWD, parent, &h.handle, &mount_id_parent, AT_SYMLINK_FOLLOW);
|
||||
r = name_to_handle_at(fd, "..", &h.handle, &mount_id_parent, 0);
|
||||
if (r < 0)
|
||||
if (errno == EOPNOTSUPP)
|
||||
if (nosupp)
|
||||
@@ -510,10 +532,7 @@ int path_is_mount_point(const char *t, bool allow_symlink) {
|
||||
return mount_id != mount_id_parent;
|
||||
|
||||
fallback:
|
||||
if (allow_symlink)
|
||||
r = stat(t, &a);
|
||||
else
|
||||
r = lstat(t, &a);
|
||||
r = fstatat(fd, "", &a, AT_EMPTY_PATH);
|
||||
|
||||
if (r < 0) {
|
||||
if (errno == ENOENT)
|
||||
@@ -522,14 +541,8 @@ fallback:
|
||||
return -errno;
|
||||
}
|
||||
|
||||
free(parent);
|
||||
parent = NULL;
|
||||
|
||||
r = path_get_parent(t, &parent);
|
||||
if (r < 0)
|
||||
return r;
|
||||
|
||||
r = stat(parent, &b);
|
||||
r = fstatat(fd, "..", &b, 0);
|
||||
if (r < 0)
|
||||
return -errno;
|
||||
|
||||
|
@@ -44,6 +44,7 @@ char* path_make_absolute_cwd(const char *p);
|
||||
int path_make_relative(const char *from_dir, const char *to_path, char **_r);
|
||||
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);
|
||||
char* path_join(const char *root, const char *path, const char *rest);
|
||||
|
@@ -97,7 +97,9 @@ const char* socket_address_get_path(const SocketAddress *a);
|
||||
|
||||
bool socket_ipv6_is_supported(void);
|
||||
|
||||
int sockaddr_pretty(const struct sockaddr *_sa, socklen_t salen, bool translate_ipv6, char **ret);
|
||||
int sockaddr_port(const struct sockaddr *_sa) _pure_;
|
||||
|
||||
int sockaddr_pretty(const struct sockaddr *_sa, socklen_t salen, bool translate_ipv6, bool include_port, char **ret);
|
||||
int getpeername_pretty(int fd, char **ret);
|
||||
int getsockname_pretty(int fd, char **ret);
|
||||
|
||||
|
@@ -80,9 +80,10 @@ void strv_clear(char **l) {
|
||||
*l = NULL;
|
||||
}
|
||||
|
||||
void strv_free(char **l) {
|
||||
char **strv_free(char **l) {
|
||||
strv_clear(l);
|
||||
free(l);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
char **strv_copy(char * const *l) {
|
||||
|
@@ -31,7 +31,7 @@ char *strv_find(char **l, const char *name) _pure_;
|
||||
char *strv_find_prefix(char **l, const char *name) _pure_;
|
||||
char *strv_find_startswith(char **l, const char *name) _pure_;
|
||||
|
||||
void strv_free(char **l);
|
||||
char **strv_free(char **l);
|
||||
DEFINE_TRIVIAL_CLEANUP_FUNC(char**, strv_free);
|
||||
#define _cleanup_strv_free_ _cleanup_(strv_freep)
|
||||
|
||||
|
@@ -94,6 +94,9 @@
|
||||
#include "def.h"
|
||||
#include "sparse-endian.h"
|
||||
|
||||
/* Put this test here for a lack of better place */
|
||||
assert_cc(EAGAIN == EWOULDBLOCK);
|
||||
|
||||
int saved_argc = 0;
|
||||
char **saved_argv = NULL;
|
||||
|
||||
@@ -2326,6 +2329,17 @@ ssize_t loop_read(int fd, void *buf, size_t nbytes, bool do_poll) {
|
||||
return n;
|
||||
}
|
||||
|
||||
int loop_read_exact(int fd, void *buf, size_t nbytes, bool do_poll) {
|
||||
ssize_t n;
|
||||
|
||||
n = loop_read(fd, buf, nbytes, do_poll);
|
||||
if (n < 0)
|
||||
return n;
|
||||
if ((size_t) n != nbytes)
|
||||
return -EIO;
|
||||
return 0;
|
||||
}
|
||||
|
||||
int loop_write(int fd, const void *buf, size_t nbytes, bool do_poll) {
|
||||
const uint8_t *p = buf;
|
||||
|
||||
@@ -2580,8 +2594,9 @@ char* dirname_malloc(const char *path) {
|
||||
|
||||
int dev_urandom(void *p, size_t n) {
|
||||
static int have_syscall = -1;
|
||||
int r, fd;
|
||||
ssize_t k;
|
||||
|
||||
_cleanup_close_ int fd = -1;
|
||||
int r;
|
||||
|
||||
/* Gathers some randomness from the kernel. This call will
|
||||
* never block, and will always return some data from the
|
||||
@@ -2616,22 +2631,14 @@ int dev_urandom(void *p, size_t n) {
|
||||
return -errno;
|
||||
} else
|
||||
/* too short read? */
|
||||
return -EIO;
|
||||
return -ENODATA;
|
||||
}
|
||||
|
||||
fd = open("/dev/urandom", O_RDONLY|O_CLOEXEC|O_NOCTTY);
|
||||
if (fd < 0)
|
||||
return errno == ENOENT ? -ENOSYS : -errno;
|
||||
|
||||
k = loop_read(fd, p, n, true);
|
||||
safe_close(fd);
|
||||
|
||||
if (k < 0)
|
||||
return (int) k;
|
||||
if ((size_t) k != n)
|
||||
return -EIO;
|
||||
|
||||
return 0;
|
||||
return loop_read_exact(fd, p, n, true);
|
||||
}
|
||||
|
||||
void initialize_srand(void) {
|
||||
@@ -2919,18 +2926,18 @@ int get_ctty(pid_t pid, dev_t *_devnr, char **r) {
|
||||
|
||||
/* This is an ugly hack */
|
||||
if (major(devnr) == 136) {
|
||||
asprintf(&b, "pts/%u", minor(devnr));
|
||||
goto finish;
|
||||
}
|
||||
|
||||
if (asprintf(&b, "pts/%u", minor(devnr)) < 0)
|
||||
return -ENOMEM;
|
||||
} else {
|
||||
/* Probably something like the ptys which have no
|
||||
* symlink in /dev/char. Let's return something
|
||||
* vaguely useful. */
|
||||
|
||||
b = strdup(fn + 5);
|
||||
goto finish;
|
||||
if (!b)
|
||||
return -ENOMEM;
|
||||
}
|
||||
|
||||
} else {
|
||||
if (startswith(s, "/dev/"))
|
||||
p = s + 5;
|
||||
else if (startswith(s, "../"))
|
||||
@@ -2939,10 +2946,9 @@ int get_ctty(pid_t pid, dev_t *_devnr, char **r) {
|
||||
p = s;
|
||||
|
||||
b = strdup(p);
|
||||
|
||||
finish:
|
||||
if (!b)
|
||||
return -ENOMEM;
|
||||
}
|
||||
|
||||
*r = b;
|
||||
if (_devnr)
|
||||
@@ -4115,8 +4121,7 @@ static int do_execute(char **directories, usec_t timeout, char *argv[]) {
|
||||
if (null_or_empty_path(path)) {
|
||||
log_debug("%s is empty (a mask).", path);
|
||||
continue;
|
||||
} else
|
||||
log_debug("%s will be executed.", path);
|
||||
}
|
||||
|
||||
pid = fork();
|
||||
if (pid < 0) {
|
||||
@@ -6664,7 +6669,7 @@ int getpeersec(int fd, char **ret) {
|
||||
|
||||
if (isempty(s)) {
|
||||
free(s);
|
||||
return -ENOTSUP;
|
||||
return -EOPNOTSUPP;
|
||||
}
|
||||
|
||||
*ret = s;
|
||||
@@ -7838,6 +7843,28 @@ int chattr_path(const char *p, bool b, unsigned mask) {
|
||||
return chattr_fd(fd, b, mask);
|
||||
}
|
||||
|
||||
int change_attr_fd(int fd, unsigned value, unsigned mask) {
|
||||
unsigned old_attr, new_attr;
|
||||
|
||||
assert(fd >= 0);
|
||||
|
||||
if (mask == 0)
|
||||
return 0;
|
||||
|
||||
if (ioctl(fd, FS_IOC_GETFLAGS, &old_attr) < 0)
|
||||
return -errno;
|
||||
|
||||
new_attr = (old_attr & ~mask) |(value & mask);
|
||||
|
||||
if (new_attr == old_attr)
|
||||
return 0;
|
||||
|
||||
if (ioctl(fd, FS_IOC_SETFLAGS, &new_attr) < 0)
|
||||
return -errno;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
int read_attr_fd(int fd, unsigned *ret) {
|
||||
assert(fd >= 0);
|
||||
|
||||
@@ -8118,3 +8145,44 @@ void cmsg_close_all(struct msghdr *mh) {
|
||||
if (cmsg->cmsg_level == SOL_SOCKET && cmsg->cmsg_type == SCM_RIGHTS)
|
||||
close_many((int*) CMSG_DATA(cmsg), (cmsg->cmsg_len - CMSG_LEN(0)) / sizeof(int));
|
||||
}
|
||||
|
||||
int rename_noreplace(int olddirfd, const char *oldpath, int newdirfd, const char *newpath) {
|
||||
struct stat buf;
|
||||
int ret;
|
||||
|
||||
ret = renameat2(olddirfd, oldpath, newdirfd, newpath, RENAME_NOREPLACE);
|
||||
if (ret >= 0)
|
||||
return 0;
|
||||
|
||||
/* Even though renameat2() exists since Linux 3.15, btrfs added
|
||||
* support for it later. If it is not implemented, fallback to another
|
||||
* method. */
|
||||
if (errno != EINVAL)
|
||||
return -errno;
|
||||
|
||||
/* The link()/unlink() fallback does not work on directories. But
|
||||
* renameat() without RENAME_NOREPLACE gives the same semantics on
|
||||
* directories, except when newpath is an *empty* directory. This is
|
||||
* good enough. */
|
||||
ret = fstatat(olddirfd, oldpath, &buf, AT_SYMLINK_NOFOLLOW);
|
||||
if (ret >= 0 && S_ISDIR(buf.st_mode)) {
|
||||
ret = renameat(olddirfd, oldpath, newdirfd, newpath);
|
||||
return ret >= 0 ? 0 : -errno;
|
||||
}
|
||||
|
||||
/* If it is not a directory, use the link()/unlink() fallback. */
|
||||
ret = linkat(olddirfd, oldpath, newdirfd, newpath, 0);
|
||||
if (ret < 0)
|
||||
return -errno;
|
||||
|
||||
ret = unlinkat(olddirfd, oldpath, 0);
|
||||
if (ret < 0) {
|
||||
/* backup errno before the following unlinkat() alters it */
|
||||
ret = errno;
|
||||
(void) unlinkat(newdirfd, newpath, 0);
|
||||
errno = ret;
|
||||
return -errno;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
@@ -432,6 +432,7 @@ int sigaction_many(const struct sigaction *sa, ...);
|
||||
int fopen_temporary(const char *path, FILE **_f, char **_temp_path);
|
||||
|
||||
ssize_t loop_read(int fd, void *buf, size_t nbytes, bool do_poll);
|
||||
int loop_read_exact(int fd, void *buf, size_t nbytes, bool do_poll);
|
||||
int loop_write(int fd, const void *buf, size_t nbytes, bool do_poll);
|
||||
|
||||
bool is_device_path(const char *path);
|
||||
@@ -1052,6 +1053,7 @@ int same_fd(int a, int b);
|
||||
|
||||
int chattr_fd(int fd, bool b, unsigned mask);
|
||||
int chattr_path(const char *p, bool b, unsigned mask);
|
||||
int change_attr_fd(int fd, unsigned value, unsigned mask);
|
||||
|
||||
int read_attr_fd(int fd, unsigned *ret);
|
||||
int read_attr_path(const char *p, unsigned *ret);
|
||||
@@ -1080,3 +1082,5 @@ void sigkill_wait(pid_t *pid);
|
||||
int syslog_parse_priority(const char **p, int *priority, bool with_facility);
|
||||
|
||||
void cmsg_close_all(struct msghdr *mh);
|
||||
|
||||
int rename_noreplace(int olddirfd, const char *oldpath, int newdirfd, const char *newpath);
|
||||
|
@@ -51,8 +51,8 @@ enum {
|
||||
};
|
||||
|
||||
enum {
|
||||
SD_EVENT_PASSIVE,
|
||||
SD_EVENT_PREPARED,
|
||||
SD_EVENT_INITIAL,
|
||||
SD_EVENT_ARMED,
|
||||
SD_EVENT_PENDING,
|
||||
SD_EVENT_RUNNING,
|
||||
SD_EVENT_EXITING,
|
||||
|
Reference in New Issue
Block a user