summaryrefslogtreecommitdiff
path: root/src/basic
diff options
context:
space:
mode:
Diffstat (limited to 'src/basic')
-rw-r--r--src/basic/build.c3
-rw-r--r--src/basic/cgroup-util.c22
-rw-r--r--src/basic/cgroup-util.h1
-rw-r--r--src/basic/fd-util.c12
-rw-r--r--src/basic/fd-util.h1
-rw-r--r--src/basic/fileio.c2
-rw-r--r--src/basic/log.c5
-rw-r--r--src/basic/log.h1
-rw-r--r--src/basic/macro.h2
-rw-r--r--src/basic/missing_magic.h2
-rw-r--r--src/basic/os-util.c2
-rw-r--r--src/basic/process-util.c2
-rw-r--r--src/basic/socket-util.c64
-rw-r--r--src/basic/strv.c10
-rw-r--r--src/basic/strv.h5
-rw-r--r--src/basic/terminal-util.h2
-rw-r--r--src/basic/unit-file.c2
-rw-r--r--src/basic/xattr-util.c69
-rw-r--r--src/basic/xattr-util.h2
19 files changed, 171 insertions, 38 deletions
diff --git a/src/basic/build.c b/src/basic/build.c
index aaf7d2ceeb..c587adad7b 100644
--- a/src/basic/build.c
+++ b/src/basic/build.c
@@ -276,7 +276,8 @@ int version(void) {
if (colors_enabled())
b = systemd_features_with_color();
- printf("systemd " STRINGIFY(PROJECT_VERSION) " (" GIT_VERSION ")\n%s\n",
+ printf("%ssystemd " STRINGIFY(PROJECT_VERSION) "%s (" GIT_VERSION ")\n%s\n",
+ ansi_highlight(), ansi_normal(),
b ?: systemd_features);
return 0;
}
diff --git a/src/basic/cgroup-util.c b/src/basic/cgroup-util.c
index a8e4a1bb2d..feda596939 100644
--- a/src/basic/cgroup-util.c
+++ b/src/basic/cgroup-util.c
@@ -1198,6 +1198,28 @@ int cg_path_get_unit(const char *path, char **ret) {
return 0;
}
+int cg_path_get_unit_path(const char *path, char **ret) {
+ _cleanup_free_ char *path_copy = NULL;
+ char *unit_name;
+
+ assert(path);
+ assert(ret);
+
+ path_copy = strdup(path);
+ if (!path_copy)
+ return -ENOMEM;
+
+ unit_name = (char *)skip_slices(path_copy);
+ unit_name[strcspn(unit_name, "/")] = 0;
+
+ if (!unit_name_is_valid(cg_unescape(unit_name), UNIT_NAME_PLAIN|UNIT_NAME_INSTANCE))
+ return -ENXIO;
+
+ *ret = TAKE_PTR(path_copy);
+
+ return 0;
+}
+
int cg_pid_get_unit(pid_t pid, char **unit) {
_cleanup_free_ char *cgroup = NULL;
int r;
diff --git a/src/basic/cgroup-util.h b/src/basic/cgroup-util.h
index c9aae5abf6..b69f1683db 100644
--- a/src/basic/cgroup-util.h
+++ b/src/basic/cgroup-util.h
@@ -261,6 +261,7 @@ int cg_path_get_cgroupid(const char *path, uint64_t *ret);
int cg_path_get_session(const char *path, char **session);
int cg_path_get_owner_uid(const char *path, uid_t *uid);
int cg_path_get_unit(const char *path, char **unit);
+int cg_path_get_unit_path(const char *path, char **unit);
int cg_path_get_user_unit(const char *path, char **unit);
int cg_path_get_machine_name(const char *path, char **machine);
int cg_path_get_slice(const char *path, char **slice);
diff --git a/src/basic/fd-util.c b/src/basic/fd-util.c
index 4d6d01cd99..430db0c879 100644
--- a/src/basic/fd-util.c
+++ b/src/basic/fd-util.c
@@ -808,6 +808,18 @@ int fd_reopen_condition(
return new_fd;
}
+int fd_is_opath(int fd) {
+ int r;
+
+ assert(fd >= 0);
+
+ r = fcntl(fd, F_GETFL);
+ if (r < 0)
+ return -errno;
+
+ return FLAGS_SET(r, O_PATH);
+}
+
int read_nr_open(void) {
_cleanup_free_ char *nr_open = NULL;
int r;
diff --git a/src/basic/fd-util.h b/src/basic/fd-util.h
index 952afdd64f..f5357860f5 100644
--- a/src/basic/fd-util.h
+++ b/src/basic/fd-util.h
@@ -104,6 +104,7 @@ static inline int make_null_stdio(void) {
int fd_reopen(int fd, int flags);
int fd_reopen_condition(int fd, int flags, int mask, int *ret_new_fd);
+int fd_is_opath(int fd);
int read_nr_open(void);
int fd_get_diskseq(int fd, uint64_t *ret);
diff --git a/src/basic/fileio.c b/src/basic/fileio.c
index 51b11ab9c7..c802db749b 100644
--- a/src/basic/fileio.c
+++ b/src/basic/fileio.c
@@ -504,7 +504,7 @@ int read_virtual_file_fd(int fd, size_t max_size, char **ret_contents, size_t *r
* at least one more byte to be able to distinguish EOF from truncation. */
if (max_size != SIZE_MAX && n > max_size) {
n = size; /* Make sure we never use more than what we sized the buffer for (so that
- * we have one free byte in it for the trailing NUL we add below).*/
+ * we have one free byte in it for the trailing NUL we add below). */
truncated = true;
break;
}
diff --git a/src/basic/log.c b/src/basic/log.c
index fc5793139e..6a43731012 100644
--- a/src/basic/log.c
+++ b/src/basic/log.c
@@ -347,6 +347,11 @@ void log_set_target(LogTarget target) {
log_target = target;
}
+void log_set_target_and_open(LogTarget target) {
+ log_set_target(target);
+ log_open();
+}
+
void log_close(void) {
/* Do not call from library code. */
diff --git a/src/basic/log.h b/src/basic/log.h
index f73d4c4154..0d4956e6b5 100644
--- a/src/basic/log.h
+++ b/src/basic/log.h
@@ -51,6 +51,7 @@ static inline void clear_log_syntax_callback(dummy_t *dummy) {
const char *log_target_to_string(LogTarget target) _const_;
LogTarget log_target_from_string(const char *s) _pure_;
void log_set_target(LogTarget target);
+void log_set_target_and_open(LogTarget target);
int log_set_target_from_string(const char *e);
LogTarget log_get_target(void) _pure_;
diff --git a/src/basic/macro.h b/src/basic/macro.h
index 0d032866cf..25e42db0b6 100644
--- a/src/basic/macro.h
+++ b/src/basic/macro.h
@@ -418,7 +418,7 @@ typedef struct {
assert_cc(sizeof(dummy_t) == 0);
-/* A little helper for subtracting 1 off a pointer in a safe UB-free way. This is intended to be used for for
+/* A little helper for subtracting 1 off a pointer in a safe UB-free way. This is intended to be used for
* loops that count down from a high pointer until some base. A naive loop would implement this like this:
*
* for (p = end-1; p >= base; p--) …
diff --git a/src/basic/missing_magic.h b/src/basic/missing_magic.h
index c104fcfba3..27a33adecb 100644
--- a/src/basic/missing_magic.h
+++ b/src/basic/missing_magic.h
@@ -58,7 +58,7 @@
#define UDF_SUPER_MAGIC 0x15013346
#endif
-/* b1123ea6d3b3da25af5c8a9d843bd07ab63213f4 (4.8)*/
+/* b1123ea6d3b3da25af5c8a9d843bd07ab63213f4 (4.8) */
#ifndef BALLOON_KVM_MAGIC
#define BALLOON_KVM_MAGIC 0x13661366
#endif
diff --git a/src/basic/os-util.c b/src/basic/os-util.c
index 37a4ac1fe4..bf844e5b7f 100644
--- a/src/basic/os-util.c
+++ b/src/basic/os-util.c
@@ -171,7 +171,7 @@ int open_extension_release(const char *root, const char *extension, bool relax_e
/* We already found what we were looking for, but there's another candidate?
* We treat this as an error, as we want to enforce that there are no ambiguities
- * in case we are in the fallback path.*/
+ * in case we are in the fallback path. */
if (r == 0) {
r = -ENOTUNIQ;
break;
diff --git a/src/basic/process-util.c b/src/basic/process-util.c
index 70aa15f060..b6bf83c2cf 100644
--- a/src/basic/process-util.c
+++ b/src/basic/process-util.c
@@ -596,6 +596,8 @@ int get_process_umask(pid_t pid, mode_t *ret) {
r = get_proc_field(p, "Umask", WHITESPACE, &m);
if (r == -ENOENT)
return -ESRCH;
+ if (r < 0)
+ return r;
return parse_mode(m, ret);
}
diff --git a/src/basic/socket-util.c b/src/basic/socket-util.c
index d7946a3641..f01873e608 100644
--- a/src/basic/socket-util.c
+++ b/src/basic/socket-util.c
@@ -1425,52 +1425,60 @@ int socket_get_mtu(int fd, int af, size_t *ret) {
return 0;
}
-int connect_unix_path(int fd, int dir_fd, const char *path) {
- _cleanup_close_ int inode_fd = -EBADF;
+static int connect_unix_path_simple(int fd, const char *path) {
union sockaddr_union sa = {
.un.sun_family = AF_UNIX,
};
- size_t path_len;
- socklen_t salen;
+ size_t l;
assert(fd >= 0);
- assert(dir_fd == AT_FDCWD || dir_fd >= 0);
assert(path);
+ l = strlen(path);
+ assert(l > 0);
+ assert(l < sizeof(sa.un.sun_path));
+
+ memcpy(sa.un.sun_path, path, l + 1);
+ return RET_NERRNO(connect(fd, &sa.sa, offsetof(struct sockaddr_un, sun_path) + l + 1));
+}
+
+static int connect_unix_inode(int fd, int inode_fd) {
+ assert(fd >= 0);
+ assert(inode_fd >= 0);
+
+ return connect_unix_path_simple(fd, FORMAT_PROC_FD_PATH(inode_fd));
+}
+
+int connect_unix_path(int fd, int dir_fd, const char *path) {
+ _cleanup_close_ int inode_fd = -EBADF;
+
+ assert(fd >= 0);
+ assert(dir_fd == AT_FDCWD || dir_fd >= 0);
+
/* Connects to the specified AF_UNIX socket in the file system. Works around the 108 byte size limit
* in sockaddr_un, by going via O_PATH if needed. This hence works for any kind of path. */
- path_len = strlen(path);
+ if (!path)
+ return connect_unix_inode(fd, dir_fd); /* If no path is specified, then dir_fd refers to the socket inode to connect to. */
/* Refuse zero length path early, to make sure AF_UNIX stack won't mistake this for an abstract
* namespace path, since first char is NUL */
- if (path_len <= 0)
+ if (isempty(path))
return -EINVAL;
- if (dir_fd == AT_FDCWD && path_len < sizeof(sa.un.sun_path)) {
- memcpy(sa.un.sun_path, path, path_len + 1);
- salen = offsetof(struct sockaddr_un, sun_path) + path_len + 1;
- } else {
- const char *proc;
- size_t proc_len;
-
- /* If dir_fd is specified, then we need to go the indirect O_PATH route, because connectat()
- * does not exist. If the path is too long, we also need to take the indirect route, since we
- * can't fit this into a sockaddr_un directly. */
-
- inode_fd = openat(dir_fd, path, O_PATH|O_CLOEXEC);
- if (inode_fd < 0)
- return -errno;
+ /* Shortcut for the simple case */
+ if (dir_fd == AT_FDCWD && strlen(path) < sizeof_field(struct sockaddr_un, sun_path))
+ return connect_unix_path_simple(fd, path);
- proc = FORMAT_PROC_FD_PATH(inode_fd);
- proc_len = strlen(proc);
+ /* If dir_fd is specified, then we need to go the indirect O_PATH route, because connectat() does not
+ * exist. If the path is too long, we also need to take the indirect route, since we can't fit this
+ * into a sockaddr_un directly. */
- assert(proc_len < sizeof(sa.un.sun_path));
- memcpy(sa.un.sun_path, proc, proc_len + 1);
- salen = offsetof(struct sockaddr_un, sun_path) + proc_len + 1;
- }
+ inode_fd = openat(dir_fd, path, O_PATH|O_CLOEXEC);
+ if (inode_fd < 0)
+ return -errno;
- return RET_NERRNO(connect(fd, &sa.sa, salen));
+ return connect_unix_inode(fd, inode_fd);
}
int socket_address_parse_unix(SocketAddress *ret_address, const char *s) {
diff --git a/src/basic/strv.c b/src/basic/strv.c
index 2b7a61d442..9b4a7663a9 100644
--- a/src/basic/strv.c
+++ b/src/basic/strv.c
@@ -77,20 +77,26 @@ char** strv_free_erase(char **l) {
return mfree(l);
}
-char** strv_copy(char * const *l) {
+char** strv_copy_n(char * const *l, size_t m) {
_cleanup_strv_free_ char **result = NULL;
char **k;
- result = new(char*, strv_length(l) + 1);
+ result = new(char*, MIN(strv_length(l), m) + 1);
if (!result)
return NULL;
k = result;
STRV_FOREACH(i, l) {
+ if (m == 0)
+ break;
+
*k = strdup(*i);
if (!*k)
return NULL;
k++;
+
+ if (m != SIZE_MAX)
+ m--;
}
*k = NULL;
diff --git a/src/basic/strv.h b/src/basic/strv.h
index 1f8da85fcc..71ff3a4edf 100644
--- a/src/basic/strv.h
+++ b/src/basic/strv.h
@@ -29,7 +29,10 @@ char** strv_free_erase(char **l);
DEFINE_TRIVIAL_CLEANUP_FUNC(char**, strv_free_erase);
#define _cleanup_strv_free_erase_ _cleanup_(strv_free_erasep)
-char** strv_copy(char * const *l);
+char** strv_copy_n(char * const *l, size_t n);
+static inline char** strv_copy(char * const *l) {
+ return strv_copy_n(l, SIZE_MAX);
+}
size_t strv_length(char * const *l) _pure_;
int strv_extend_strv(char ***a, char * const *b, bool filter_duplicates);
diff --git a/src/basic/terminal-util.h b/src/basic/terminal-util.h
index 59c868a2a5..1723de34fa 100644
--- a/src/basic/terminal-util.h
+++ b/src/basic/terminal-util.h
@@ -111,7 +111,7 @@ typedef enum ColorMode {
/* Only 256 colors. */
COLOR_256,
- /* For truecolor or 24bit color support.*/
+ /* For truecolor or 24bit color support. */
COLOR_24BIT,
_COLOR_INVALID = -EINVAL,
diff --git a/src/basic/unit-file.c b/src/basic/unit-file.c
index 1334365c2f..1f79a2735e 100644
--- a/src/basic/unit-file.c
+++ b/src/basic/unit-file.c
@@ -329,7 +329,7 @@ int unit_file_resolve_symlink(
assert(path_is_absolute(simplified));
- /* Check if the symlink remain inside of of our search path.
+ /* Check if the symlink remain inside of our search path.
* If yes, it is an alias. Verify that it is valid.
*
* If no, then this is a linked unit file or mask, and we don't care about the target name
diff --git a/src/basic/xattr-util.c b/src/basic/xattr-util.c
index 5b6131b56a..b42bf68f58 100644
--- a/src/basic/xattr-util.c
+++ b/src/basic/xattr-util.c
@@ -293,3 +293,72 @@ int listxattr_at_malloc(
l = (size_t) n;
}
}
+
+int xsetxattr(int fd,
+ const char *path,
+ const char *name,
+ const char *value,
+ size_t size,
+ int flags) {
+
+ _cleanup_close_ int opened_fd = -EBADF;
+ bool by_procfs = false;
+ int r;
+
+ assert(fd >= 0 || fd == AT_FDCWD);
+ assert(name);
+ assert(value);
+ assert((flags & ~(AT_SYMLINK_FOLLOW|AT_EMPTY_PATH)) == 0);
+
+ /* So, this is a single function that does what setxattr()/lsetxattr()/fsetxattr() do, but in one go,
+ * and with additional bells and whistles. Specifically:
+ *
+ * 1. This works on O_PATH fds (which fsetxattr() does not)
+ * 2. Provides full openat()-style semantics, i.e. by-fd, by-path and combination thereof
+ * 3. As extension to openat()-style semantics implies AT_EMPTY_PATH if path is NULL.
+ */
+
+ if (!path) /* If path is NULL, imply AT_EMPTY_PATH. – But if it's "", don't — for safety reasons. */
+ flags |= AT_EMPTY_PATH;
+
+ if (size == SIZE_MAX)
+ size = strlen(value);
+
+ if (isempty(path)) {
+ if (!FLAGS_SET(flags, AT_EMPTY_PATH))
+ return -EINVAL;
+
+ if (fd == AT_FDCWD) /* Both unspecified? Then operate on current working directory */
+ path = ".";
+ else {
+ r = fd_is_opath(fd);
+ if (r < 0)
+ return r;
+
+ by_procfs = r;
+ path = NULL;
+ }
+
+ } else if (fd != AT_FDCWD) {
+
+ /* If both have been specified, then we go via O_PATH */
+ opened_fd = openat(fd, path, O_PATH|O_CLOEXEC|(FLAGS_SET(flags, AT_SYMLINK_FOLLOW) ? 0 : O_NOFOLLOW));
+ if (opened_fd < 0)
+ return -errno;
+
+ fd = opened_fd;
+ path = NULL;
+ by_procfs = true; /* fsetxattr() is not going to work, go via /proc/ link right-away */
+ }
+
+ if (path)
+ r = FLAGS_SET(flags, AT_SYMLINK_FOLLOW) ? setxattr(path, name, value, size, 0)
+ : lsetxattr(path, name, value, size, 0);
+ else
+ r = by_procfs ? setxattr(FORMAT_PROC_FD_PATH(fd), name, value, size, 0)
+ : fsetxattr(fd, name, value, size, 0);
+ if (r < 0)
+ return -errno;
+
+ return 0;
+}
diff --git a/src/basic/xattr-util.h b/src/basic/xattr-util.h
index 0eb745a7a3..649a842fe2 100644
--- a/src/basic/xattr-util.h
+++ b/src/basic/xattr-util.h
@@ -36,3 +36,5 @@ static inline int llistxattr_malloc(const char *path, char **ret) {
static inline int flistxattr_malloc(int fd, char **ret) {
return listxattr_at_malloc(fd, NULL, AT_EMPTY_PATH, ret);
}
+
+int xsetxattr(int fd, const char *path, const char *name, const char *value, size_t size, int flags);