summaryrefslogtreecommitdiffstats
path: root/src/basic
diff options
context:
space:
mode:
Diffstat (limited to 'src/basic')
-rw-r--r--src/basic/chase.c30
-rw-r--r--src/basic/chattr-util.c2
-rw-r--r--src/basic/env-util.c31
-rw-r--r--src/basic/env-util.h2
-rw-r--r--src/basic/filesystems-gperf.gperf1
-rw-r--r--src/basic/fs-util.c8
-rw-r--r--src/basic/fs-util.h10
-rw-r--r--src/basic/hashmap.h2
-rw-r--r--src/basic/lock-util.c14
-rw-r--r--src/basic/log.c10
-rw-r--r--src/basic/meson.build2
-rw-r--r--src/basic/missing_magic.h5
-rw-r--r--src/basic/os-util.c55
-rw-r--r--src/basic/os-util.h1
-rw-r--r--src/basic/stat-util.c26
-rw-r--r--src/basic/stat-util.h3
-rw-r--r--src/basic/terminal-util.c2
-rw-r--r--src/basic/terminal-util.h3
-rw-r--r--src/basic/virt.c1
19 files changed, 162 insertions, 46 deletions
diff --git a/src/basic/chase.c b/src/basic/chase.c
index 26bc2d6..9f5477e 100644
--- a/src/basic/chase.c
+++ b/src/basic/chase.c
@@ -374,11 +374,11 @@ int chaseat(int dir_fd, const char *path, ChaseFlags flags, char **ret_path, int
return r;
if (FLAGS_SET(flags, CHASE_MKDIR_0755) && !isempty(todo)) {
- child = xopenat(fd,
- first,
- O_DIRECTORY|O_CREAT|O_EXCL|O_NOFOLLOW|O_CLOEXEC,
- /* xopen_flags = */ 0,
- 0755);
+ child = xopenat_full(fd,
+ first,
+ O_DIRECTORY|O_CREAT|O_EXCL|O_NOFOLLOW|O_CLOEXEC,
+ /* xopen_flags = */ 0,
+ 0755);
if (child < 0)
return child;
} else if (FLAGS_SET(flags, CHASE_PARENT) && isempty(todo)) {
@@ -760,10 +760,10 @@ int chase_and_open(const char *path, const char *root, ChaseFlags chase_flags, i
if (empty_or_root(root) && !ret_path &&
(chase_flags & (CHASE_NO_AUTOFS|CHASE_SAFE|CHASE_PROHIBIT_SYMLINKS|CHASE_PARENT|CHASE_MKDIR_0755)) == 0)
/* Shortcut this call if none of the special features of this call are requested */
- return xopenat(AT_FDCWD, path,
- open_flags | (FLAGS_SET(chase_flags, CHASE_NOFOLLOW) ? O_NOFOLLOW : 0),
- /* xopen_flags = */ 0,
- mode);
+ return xopenat_full(AT_FDCWD, path,
+ open_flags | (FLAGS_SET(chase_flags, CHASE_NOFOLLOW) ? O_NOFOLLOW : 0),
+ /* xopen_flags = */ 0,
+ mode);
r = chase(path, root, CHASE_PARENT|chase_flags, &p, &path_fd);
if (r < 0)
@@ -777,7 +777,7 @@ int chase_and_open(const char *path, const char *root, ChaseFlags chase_flags, i
return r;
}
- r = xopenat(path_fd, strempty(fname), open_flags|O_NOFOLLOW, /* xopen_flags = */ 0, mode);
+ r = xopenat_full(path_fd, strempty(fname), open_flags|O_NOFOLLOW, /* xopen_flags = */ 0, mode);
if (r < 0)
return r;
@@ -964,10 +964,10 @@ int chase_and_openat(int dir_fd, const char *path, ChaseFlags chase_flags, int o
if (dir_fd == AT_FDCWD && !ret_path &&
(chase_flags & (CHASE_NO_AUTOFS|CHASE_SAFE|CHASE_PROHIBIT_SYMLINKS|CHASE_PARENT|CHASE_MKDIR_0755)) == 0)
/* Shortcut this call if none of the special features of this call are requested */
- return xopenat(dir_fd, path,
- open_flags | (FLAGS_SET(chase_flags, CHASE_NOFOLLOW) ? O_NOFOLLOW : 0),
- /* xopen_flags = */ 0,
- mode);
+ return xopenat_full(dir_fd, path,
+ open_flags | (FLAGS_SET(chase_flags, CHASE_NOFOLLOW) ? O_NOFOLLOW : 0),
+ /* xopen_flags = */ 0,
+ mode);
r = chaseat(dir_fd, path, chase_flags|CHASE_PARENT, &p, &path_fd);
if (r < 0)
@@ -979,7 +979,7 @@ int chase_and_openat(int dir_fd, const char *path, ChaseFlags chase_flags, int o
return r;
}
- r = xopenat(path_fd, strempty(fname), open_flags|O_NOFOLLOW, /* xopen_flags = */ 0, mode);
+ r = xopenat_full(path_fd, strempty(fname), open_flags|O_NOFOLLOW, /* xopen_flags = */ 0, mode);
if (r < 0)
return r;
diff --git a/src/basic/chattr-util.c b/src/basic/chattr-util.c
index fe8b9ab..d76be5c 100644
--- a/src/basic/chattr-util.c
+++ b/src/basic/chattr-util.c
@@ -29,7 +29,7 @@ int chattr_full(
assert(dir_fd >= 0 || dir_fd == AT_FDCWD);
- fd = xopenat(dir_fd, path, O_RDONLY|O_CLOEXEC|O_NOCTTY|O_NOFOLLOW, /* xopen_flags = */ 0, /* mode = */ 0);
+ fd = xopenat(dir_fd, path, O_RDONLY|O_CLOEXEC|O_NOCTTY|O_NOFOLLOW);
if (fd < 0)
return fd;
diff --git a/src/basic/env-util.c b/src/basic/env-util.c
index d3bf733..a97651d 100644
--- a/src/basic/env-util.c
+++ b/src/basic/env-util.c
@@ -983,8 +983,8 @@ int putenv_dup(const char *assignment, bool override) {
}
int setenv_systemd_exec_pid(bool update_only) {
- char str[DECIMAL_STR_MAX(pid_t)];
const char *e;
+ int r;
/* Update $SYSTEMD_EXEC_PID=pid except when '*' is set for the variable. */
@@ -995,10 +995,9 @@ int setenv_systemd_exec_pid(bool update_only) {
if (streq_ptr(e, "*"))
return 0;
- xsprintf(str, PID_FMT, getpid_cached());
-
- if (setenv("SYSTEMD_EXEC_PID", str, 1) < 0)
- return -errno;
+ r = setenvf("SYSTEMD_EXEC_PID", /* overwrite= */ 1, PID_FMT, getpid_cached());
+ if (r < 0)
+ return r;
return 1;
}
@@ -1093,3 +1092,25 @@ int set_full_environment(char **env) {
return 0;
}
+
+int setenvf(const char *name, bool overwrite, const char *valuef, ...) {
+ _cleanup_free_ char *value = NULL;
+ va_list ap;
+ int r;
+
+ assert(name);
+
+ if (!valuef)
+ return RET_NERRNO(unsetenv(name));
+
+ va_start(ap, valuef);
+ DISABLE_WARNING_FORMAT_NONLITERAL;
+ r = vasprintf(&value, valuef, ap);
+ REENABLE_WARNING;
+ va_end(ap);
+
+ if (r < 0)
+ return -ENOMEM;
+
+ return RET_NERRNO(setenv(name, value, overwrite));
+}
diff --git a/src/basic/env-util.h b/src/basic/env-util.h
index f7fb1e9..34cf1f9 100644
--- a/src/basic/env-util.h
+++ b/src/basic/env-util.h
@@ -79,3 +79,5 @@ int getenv_path_list(const char *name, char ***ret_paths);
int getenv_steal_erase(const char *name, char **ret);
int set_full_environment(char **env);
+
+int setenvf(const char *name, bool overwrite, const char *valuef, ...) _printf_(3,4);
diff --git a/src/basic/filesystems-gperf.gperf b/src/basic/filesystems-gperf.gperf
index e8c5357..1cd66b5 100644
--- a/src/basic/filesystems-gperf.gperf
+++ b/src/basic/filesystems-gperf.gperf
@@ -91,6 +91,7 @@ ocfs2, {OCFS2_SUPER_MAGIC}
openpromfs, {OPENPROM_SUPER_MAGIC}
orangefs, {ORANGEFS_DEVREQ_MAGIC}
overlay, {OVERLAYFS_SUPER_MAGIC}
+pidfs, {PID_FS_MAGIC}
pipefs, {PIPEFS_MAGIC}
ppc-cmm, {PPC_CMM_MAGIC}
proc, {PROC_SUPER_MAGIC}
diff --git a/src/basic/fs-util.c b/src/basic/fs-util.c
index 9ba9268..5bc7d2f 100644
--- a/src/basic/fs-util.c
+++ b/src/basic/fs-util.c
@@ -1054,7 +1054,7 @@ int open_mkdir_at(int dirfd, const char *path, int flags, mode_t mode) {
path = fname;
}
- fd = xopenat(dirfd, path, flags|O_CREAT|O_DIRECTORY|O_NOFOLLOW, /* xopen_flags = */ 0, mode);
+ fd = xopenat_full(dirfd, path, flags|O_CREAT|O_DIRECTORY|O_NOFOLLOW, /* xopen_flags = */ 0, mode);
if (IN_SET(fd, -ELOOP, -ENOTDIR))
return -EEXIST;
if (fd < 0)
@@ -1110,7 +1110,7 @@ int openat_report_new(int dirfd, const char *pathname, int flags, mode_t mode, b
}
}
-int xopenat(int dir_fd, const char *path, int open_flags, XOpenFlags xopen_flags, mode_t mode) {
+int xopenat_full(int dir_fd, const char *path, int open_flags, XOpenFlags xopen_flags, mode_t mode) {
_cleanup_close_ int fd = -EBADF;
bool made = false;
int r;
@@ -1191,7 +1191,7 @@ int xopenat(int dir_fd, const char *path, int open_flags, XOpenFlags xopen_flags
return TAKE_FD(fd);
}
-int xopenat_lock(
+int xopenat_lock_full(
int dir_fd,
const char *path,
int open_flags,
@@ -1214,7 +1214,7 @@ int xopenat_lock(
for (;;) {
struct stat st;
- fd = xopenat(dir_fd, path, open_flags, xopen_flags, mode);
+ fd = xopenat_full(dir_fd, path, open_flags, xopen_flags, mode);
if (fd < 0)
return fd;
diff --git a/src/basic/fs-util.h b/src/basic/fs-util.h
index 1023ab7..6a1e2e7 100644
--- a/src/basic/fs-util.h
+++ b/src/basic/fs-util.h
@@ -137,6 +137,12 @@ typedef enum XOpenFlags {
XO_SUBVOLUME = 1 << 1,
} XOpenFlags;
-int xopenat(int dir_fd, const char *path, int open_flags, XOpenFlags xopen_flags, mode_t mode);
+int xopenat_full(int dir_fd, const char *path, int open_flags, XOpenFlags xopen_flags, mode_t mode);
+static inline int xopenat(int dir_fd, const char *path, int open_flags) {
+ return xopenat_full(dir_fd, path, open_flags, 0, 0);
+}
-int xopenat_lock(int dir_fd, const char *path, int open_flags, XOpenFlags xopen_flags, mode_t mode, LockType locktype, int operation);
+int xopenat_lock_full(int dir_fd, const char *path, int open_flags, XOpenFlags xopen_flags, mode_t mode, LockType locktype, int operation);
+static inline int xopenat_lock(int dir_fd, const char *path, int open_flags, LockType locktype, int operation) {
+ return xopenat_lock_full(dir_fd, path, open_flags, 0, 0, locktype, operation);
+}
diff --git a/src/basic/hashmap.h b/src/basic/hashmap.h
index 233f1d7..d0ebdf5 100644
--- a/src/basic/hashmap.h
+++ b/src/basic/hashmap.h
@@ -39,8 +39,8 @@ typedef struct IteratedCache IteratedCache; /* Caches the iterated order of on
* by hashmap users, so the definition has to be here. Do not use its fields
* directly. */
typedef struct {
- unsigned idx; /* index of an entry to be iterated next */
const void *next_key; /* expected value of that entry's key pointer */
+ unsigned idx; /* index of an entry to be iterated next */
#if ENABLE_DEBUG_HASHMAP
unsigned put_count; /* hashmap's put_count recorded at start of iteration */
unsigned rem_count; /* hashmap's rem_count in previous iteration */
diff --git a/src/basic/lock-util.c b/src/basic/lock-util.c
index 047fd01..7bffe85 100644
--- a/src/basic/lock-util.c
+++ b/src/basic/lock-util.c
@@ -40,13 +40,13 @@ int make_lock_file_at(int dir_fd, const char *p, int operation, LockFile *ret) {
if (!t)
return -ENOMEM;
- fd = xopenat_lock(dfd,
- p,
- O_CREAT|O_RDWR|O_NOFOLLOW|O_CLOEXEC|O_NOCTTY,
- /* xopen_flags = */ 0,
- 0600,
- LOCK_UNPOSIX,
- operation);
+ fd = xopenat_lock_full(dfd,
+ p,
+ O_CREAT|O_RDWR|O_NOFOLLOW|O_CLOEXEC|O_NOCTTY,
+ /* xopen_flags = */ 0,
+ 0600,
+ LOCK_UNPOSIX,
+ operation);
if (fd < 0)
return fd == -EAGAIN ? -EBUSY : fd;
diff --git a/src/basic/log.c b/src/basic/log.c
index 1470611..7a44300 100644
--- a/src/basic/log.c
+++ b/src/basic/log.c
@@ -427,6 +427,8 @@ static int write_to_console(
const char *func,
const char *buffer) {
+ static int dumb = -1;
+
char location[256],
header_time[FORMAT_TIMESTAMP_MAX],
prefix[1 + DECIMAL_STR_MAX(int) + 2],
@@ -438,6 +440,9 @@ static int write_to_console(
if (console_fd < 0)
return 0;
+ if (dumb < 0)
+ dumb = getenv_terminal_is_dumb();
+
if (log_target == LOG_TARGET_CONSOLE_PREFIXED) {
xsprintf(prefix, "<%i>", level);
iovec[n++] = IOVEC_MAKE_STRING(prefix);
@@ -481,8 +486,9 @@ static int write_to_console(
/* When writing to a TTY we output an extra '\r' (i.e. CR) first, to generate CRNL rather than just
* NL. This is a robustness thing in case the TTY is currently in raw mode (specifically: has the
* ONLCR flag off). We want that subsequent output definitely starts at the beginning of the line
- * again, after all. If the TTY is not in raw mode the extra CR should not hurt. */
- iovec[n++] = IOVEC_MAKE_STRING(check_console_fd_is_tty() ? "\r\n" : "\n");
+ * again, after all. If the TTY is not in raw mode the extra CR should not hurt. If we're writing to
+ * a dumb terminal, only write NL as CRNL might be interpreted as a double newline. */
+ iovec[n++] = IOVEC_MAKE_STRING(check_console_fd_is_tty() && !dumb ? "\r\n" : "\n");
if (writev(console_fd, iovec, n) < 0) {
diff --git a/src/basic/meson.build b/src/basic/meson.build
index d7450d8..111253e 100644
--- a/src/basic/meson.build
+++ b/src/basic/meson.build
@@ -235,7 +235,7 @@ filesystem_includes = ['linux/magic.h',
check_filesystems = find_program('check-filesystems.sh')
r = run_command([check_filesystems, cpp, files('filesystems-gperf.gperf')] + filesystem_includes, check: false)
if r.returncode() != 0
- error('Unknown filesystems defined in kernel headers:\n\n' + r.stdout())
+ warning('Unknown filesystems defined in kernel headers:\n\n' + r.stdout())
endif
filesystems_gperf_h = custom_target(
diff --git a/src/basic/missing_magic.h b/src/basic/missing_magic.h
index 27a33ad..82d71c8 100644
--- a/src/basic/missing_magic.h
+++ b/src/basic/missing_magic.h
@@ -128,6 +128,11 @@
#define DEVMEM_MAGIC 0x454d444d
#endif
+/* cb12fd8e0dabb9a1c8aef55a6a41e2c255fcdf4b (6.8) */
+#ifndef PID_FS_MAGIC
+#define PID_FS_MAGIC 0x50494446
+#endif
+
/* Not in mainline but included in Ubuntu */
#ifndef SHIFTFS_MAGIC
#define SHIFTFS_MAGIC 0x6a656a62
diff --git a/src/basic/os-util.c b/src/basic/os-util.c
index dbd067f..985d89b 100644
--- a/src/basic/os-util.c
+++ b/src/basic/os-util.c
@@ -61,6 +61,39 @@ bool image_name_is_valid(const char *s) {
return true;
}
+int path_extract_image_name(const char *path, char **ret) {
+ _cleanup_free_ char *fn = NULL;
+ int r;
+
+ assert(path);
+ assert(ret);
+
+ /* Extract last component from path, without any "/" suffixes. */
+ r = path_extract_filename(path, &fn);
+ if (r < 0)
+ return r;
+
+ if (r != O_DIRECTORY) {
+ /* Chop off any image suffixes we recognize (unless we already know this must refer to some dir */
+ FOREACH_STRING(suffix, ".sysext.raw", ".confext.raw", ".raw") {
+ char *m = endswith(fn, suffix);
+ if (m) {
+ *m = 0;
+ break;
+ }
+ }
+ }
+
+ /* Truncate the version/counting suffixes */
+ fn[strcspn(fn, "_+")] = 0;
+
+ if (!image_name_is_valid(fn))
+ return -EINVAL;
+
+ *ret = TAKE_PTR(fn);
+ return 0;
+}
+
int path_is_extension_tree(ImageClass image_class, const char *path, const char *extension, bool relax_extension_release_check) {
int r;
@@ -230,9 +263,25 @@ int open_extension_release_at(
continue;
}
- if (!relax_extension_release_check &&
- extension_release_strict_xattr_value(fd, dir_path, de->d_name) != 0)
- continue;
+ if (!relax_extension_release_check) {
+ _cleanup_free_ char *base_image_name = NULL, *base_extension = NULL;
+
+ r = path_extract_image_name(image_name, &base_image_name);
+ if (r < 0) {
+ log_debug_errno(r, "Failed to extract image name from %s/%s, ignoring: %m", dir_path, de->d_name);
+ continue;
+ }
+
+ r = path_extract_image_name(extension, &base_extension);
+ if (r < 0) {
+ log_debug_errno(r, "Failed to extract image name from %s, ignoring: %m", extension);
+ continue;
+ }
+
+ if (!streq(base_image_name, base_extension) &&
+ extension_release_strict_xattr_value(fd, dir_path, image_name) != 0)
+ continue;
+ }
/* 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
diff --git a/src/basic/os-util.h b/src/basic/os-util.h
index 7cee3dd..f6a12a3 100644
--- a/src/basic/os-util.h
+++ b/src/basic/os-util.h
@@ -25,6 +25,7 @@ ImageClass image_class_from_string(const char *s) _pure_;
* in accordance with the OS extension specification, rather than for /usr/lib/ or /etc/os-release. */
bool image_name_is_valid(const char *s) _pure_;
+int path_extract_image_name(const char *path, char **ret);
int path_is_extension_tree(ImageClass image_class, const char *path, const char *extension, bool relax_extension_release_check);
static inline int path_is_os_tree(const char *path) {
diff --git a/src/basic/stat-util.c b/src/basic/stat-util.c
index c54374b..581370d 100644
--- a/src/basic/stat-util.c
+++ b/src/basic/stat-util.c
@@ -262,11 +262,31 @@ int path_is_network_fs(const char *path) {
return is_network_fs(&s);
}
+int stat_verify_linked(const struct stat *st) {
+ assert(st);
+
+ if (st->st_nlink <= 0)
+ return -EIDRM; /* recognizable error. */
+
+ return 0;
+}
+
+int fd_verify_linked(int fd) {
+ struct stat st;
+
+ assert(fd >= 0);
+
+ if (fstat(fd, &st) < 0)
+ return -errno;
+
+ return stat_verify_linked(&st);
+}
+
int stat_verify_regular(const struct stat *st) {
assert(st);
- /* Checks whether the specified stat() structure refers to a regular file. If not returns an appropriate error
- * code. */
+ /* Checks whether the specified stat() structure refers to a regular file. If not returns an
+ * appropriate error code. */
if (S_ISDIR(st->st_mode))
return -EISDIR;
@@ -470,7 +490,7 @@ int xstatfsat(int dir_fd, const char *path, struct statfs *ret) {
assert(dir_fd >= 0 || dir_fd == AT_FDCWD);
assert(ret);
- fd = xopenat(dir_fd, path, O_PATH|O_CLOEXEC|O_NOCTTY, /* xopen_flags = */ 0, /* mode = */ 0);
+ fd = xopenat(dir_fd, path, O_PATH|O_CLOEXEC|O_NOCTTY);
if (fd < 0)
return fd;
diff --git a/src/basic/stat-util.h b/src/basic/stat-util.h
index ae0aaf8..3501406 100644
--- a/src/basic/stat-util.h
+++ b/src/basic/stat-util.h
@@ -71,6 +71,9 @@ int path_is_network_fs(const char *path);
*/
#define F_TYPE_EQUAL(a, b) (a == (typeof(a)) b)
+int stat_verify_linked(const struct stat *st);
+int fd_verify_linked(int fd);
+
int stat_verify_regular(const struct stat *st);
int fd_verify_regular(int fd);
int verify_regular_at(int dir_fd, const char *path, bool follow);
diff --git a/src/basic/terminal-util.c b/src/basic/terminal-util.c
index 3355b74..530ef9a 100644
--- a/src/basic/terminal-util.c
+++ b/src/basic/terminal-util.c
@@ -1300,7 +1300,7 @@ static bool on_dev_null(void) {
return cached_on_dev_null;
}
-static bool getenv_terminal_is_dumb(void) {
+bool getenv_terminal_is_dumb(void) {
const char *e;
e = getenv("TERM");
diff --git a/src/basic/terminal-util.h b/src/basic/terminal-util.h
index 2a7d48b..b1d7aee 100644
--- a/src/basic/terminal-util.h
+++ b/src/basic/terminal-util.h
@@ -160,6 +160,7 @@ void columns_lines_cache_reset(int _unused_ signum);
void reset_terminal_feature_caches(void);
bool on_tty(void);
+bool getenv_terminal_is_dumb(void);
bool terminal_is_dumb(void);
ColorMode get_color_mode(void);
bool underline_enabled(void);
@@ -186,7 +187,7 @@ static inline bool colors_enabled(void) {
}
static inline const char *ansi_underline(void) {
- return underline_enabled() ? ANSI_UNDERLINE : ANSI_NORMAL;
+ return underline_enabled() ? ANSI_UNDERLINE : "";
}
#define DEFINE_ANSI_FUNC_UNDERLINE(name, NAME) \
diff --git a/src/basic/virt.c b/src/basic/virt.c
index 93ccfaa..88357a9 100644
--- a/src/basic/virt.c
+++ b/src/basic/virt.c
@@ -178,6 +178,7 @@ static Virtualization detect_vm_dmi_vendor(void) {
{ "VMW", VIRTUALIZATION_VMWARE },
{ "innotek GmbH", VIRTUALIZATION_ORACLE },
{ "VirtualBox", VIRTUALIZATION_ORACLE },
+ { "Oracle Corporation", VIRTUALIZATION_ORACLE }, /* Detect VirtualBox on some proprietary systems via the board_vendor */
{ "Xen", VIRTUALIZATION_XEN },
{ "Bochs", VIRTUALIZATION_BOCHS },
{ "Parallels", VIRTUALIZATION_PARALLELS },