diff options
Diffstat (limited to 'src/basic')
-rw-r--r-- | src/basic/build.c | 3 | ||||
-rw-r--r-- | src/basic/cgroup-util.c | 22 | ||||
-rw-r--r-- | src/basic/cgroup-util.h | 1 | ||||
-rw-r--r-- | src/basic/fd-util.c | 12 | ||||
-rw-r--r-- | src/basic/fd-util.h | 1 | ||||
-rw-r--r-- | src/basic/fileio.c | 2 | ||||
-rw-r--r-- | src/basic/log.c | 5 | ||||
-rw-r--r-- | src/basic/log.h | 1 | ||||
-rw-r--r-- | src/basic/macro.h | 2 | ||||
-rw-r--r-- | src/basic/missing_magic.h | 2 | ||||
-rw-r--r-- | src/basic/os-util.c | 2 | ||||
-rw-r--r-- | src/basic/process-util.c | 2 | ||||
-rw-r--r-- | src/basic/socket-util.c | 64 | ||||
-rw-r--r-- | src/basic/strv.c | 10 | ||||
-rw-r--r-- | src/basic/strv.h | 5 | ||||
-rw-r--r-- | src/basic/terminal-util.h | 2 | ||||
-rw-r--r-- | src/basic/unit-file.c | 2 | ||||
-rw-r--r-- | src/basic/xattr-util.c | 69 | ||||
-rw-r--r-- | src/basic/xattr-util.h | 2 |
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); |