summaryrefslogtreecommitdiffstats
path: root/src
diff options
context:
space:
mode:
authorYu Watanabe <watanabe.yu+github@gmail.com>2022-12-24 00:13:00 +0100
committerGitHub <noreply@github.com>2022-12-24 00:13:00 +0100
commit20ada514648d2c479a49689c6714c72af31ab8f6 (patch)
tree81b91da00312fef71aeb10ed9e0d339ce708474a /src
parentprioq: make prioq_reshuffle() void (diff)
parentlock-file: various updates (diff)
downloadsystemd-20ada514648d2c479a49689c6714c72af31ab8f6.tar.xz
systemd-20ada514648d2c479a49689c6714c72af31ab8f6.zip
Merge pull request #25828 from poettering/no-more-basename
convert a number of basename() invocations to path_extract_filename()
Diffstat (limited to 'src')
-rw-r--r--src/analyze/analyze-verify-util.c12
-rw-r--r--src/core/execute.c23
-rw-r--r--src/core/manager.c14
-rw-r--r--src/core/unit.c16
-rw-r--r--src/dissect/dissect.c10
-rw-r--r--src/home/homed-manager.c16
-rw-r--r--src/journal/journalctl.c9
-rw-r--r--src/mount/mount-tool.c17
-rw-r--r--src/nspawn/nspawn-util.c6
-rw-r--r--src/nspawn/nspawn.c13
-rw-r--r--src/partition/makefs.c9
-rw-r--r--src/partition/repart.c8
-rw-r--r--src/portable/portablectl.c17
-rw-r--r--src/shared/btrfs-util.c18
-rw-r--r--src/shared/exec-util.c16
-rw-r--r--src/shared/format-table.c29
-rw-r--r--src/shared/format-table.h1
-rw-r--r--src/shared/generator.c10
-rw-r--r--src/shared/lockfile-util.c63
-rw-r--r--src/shared/mount-util.c17
-rw-r--r--src/shared/tests.c6
-rw-r--r--src/sysv-generator/sysv-generator.c18
-rw-r--r--src/test/test-format-table.c18
-rw-r--r--src/tmpfiles/offline-passwd.c9
24 files changed, 244 insertions, 131 deletions
diff --git a/src/analyze/analyze-verify-util.c b/src/analyze/analyze-verify-util.c
index a646e5807c..b9f08b6d85 100644
--- a/src/analyze/analyze-verify-util.c
+++ b/src/analyze/analyze-verify-util.c
@@ -36,12 +36,9 @@ static void log_syntax_callback(const char *unit, int level, void *userdata) {
}
int verify_prepare_filename(const char *filename, char **ret) {
- int r;
- const char *name;
- _cleanup_free_ char *abspath = NULL;
- _cleanup_free_ char *dir = NULL;
- _cleanup_free_ char *with_instance = NULL;
+ _cleanup_free_ char *abspath = NULL, *name = NULL, *dir = NULL, *with_instance = NULL;
char *c;
+ int r;
assert(filename);
assert(ret);
@@ -50,7 +47,10 @@ int verify_prepare_filename(const char *filename, char **ret) {
if (r < 0)
return r;
- name = basename(abspath);
+ r = path_extract_filename(abspath, &name);
+ if (r < 0)
+ return r;
+
if (!unit_name_is_valid(name, UNIT_NAME_ANY))
return -EINVAL;
diff --git a/src/core/execute.c b/src/core/execute.c
index 9f0c5a85bf..439f491d02 100644
--- a/src/core/execute.c
+++ b/src/core/execute.c
@@ -1376,28 +1376,29 @@ fail:
}
static void rename_process_from_path(const char *path) {
- char process_name[11];
+ _cleanup_free_ char *buf = NULL;
const char *p;
- size_t l;
- /* This resulting string must fit in 10 chars (i.e. the length
- * of "/sbin/init") to look pretty in /bin/ps */
+ assert(path);
+
+ /* This resulting string must fit in 10 chars (i.e. the length of "/sbin/init") to look pretty in
+ * /bin/ps */
- p = basename(path);
- if (isempty(p)) {
+ if (path_extract_filename(path, &buf) < 0) {
rename_process("(...)");
return;
}
- l = strlen(p);
+ size_t l = strlen(buf);
if (l > 8) {
- /* The end of the process name is usually more
- * interesting, since the first bit might just be
+ /* The end of the process name is usually more interesting, since the first bit might just be
* "systemd-" */
- p = p + l - 8;
+ p = buf + l - 8;
l = 8;
- }
+ } else
+ p = buf;
+ char process_name[11];
process_name[0] = '(';
memcpy(process_name+1, p, l);
process_name[1+l] = ')';
diff --git a/src/core/manager.c b/src/core/manager.c
index 3332d5775b..739933b97c 100644
--- a/src/core/manager.c
+++ b/src/core/manager.c
@@ -2122,10 +2122,12 @@ int manager_load_unit_prepare(
Unit **ret) {
_cleanup_(unit_freep) Unit *cleanup_unit = NULL;
+ _cleanup_free_ char *nbuf = NULL;
int r;
assert(m);
assert(ret);
+ assert(name || path);
/* This will prepare the unit for loading, but not actually load anything from disk. */
@@ -2133,11 +2135,13 @@ int manager_load_unit_prepare(
return sd_bus_error_setf(e, SD_BUS_ERROR_INVALID_ARGS, "Path %s is not absolute.", path);
if (!name) {
- /* 'name' and 'path' must not both be null. Check here 'path' using assert_se() to
- * workaround a bug in gcc that generates a -Wnonnull warning when calling basename(),
- * but this cannot be possible in any code path (See #6119). */
- assert_se(path);
- name = basename(path);
+ r = path_extract_filename(path, &nbuf);
+ if (r < 0)
+ return r;
+ if (r == O_DIRECTORY)
+ return sd_bus_error_setf(e, SD_BUS_ERROR_INVALID_ARGS, "Path '%s' refers to directory, refusing.", path);
+
+ name = nbuf;
}
UnitType t = unit_name_to_type(name);
diff --git a/src/core/unit.c b/src/core/unit.c
index e14238b3ba..59e721d3e7 100644
--- a/src/core/unit.c
+++ b/src/core/unit.c
@@ -3976,14 +3976,26 @@ UnitFileState unit_get_unit_file_state(Unit *u) {
}
int unit_get_unit_file_preset(Unit *u) {
+ int r;
+
assert(u);
- if (u->unit_file_preset < 0 && u->fragment_path)
+ if (u->unit_file_preset < 0 && u->fragment_path) {
+ _cleanup_free_ char *bn = NULL;
+
+ r = path_extract_filename(u->fragment_path, &bn);
+ if (r < 0)
+ return (u->unit_file_preset = r);
+
+ if (r == O_DIRECTORY)
+ return (u->unit_file_preset = -EISDIR);
+
u->unit_file_preset = unit_file_query_preset(
u->manager->unit_file_scope,
NULL,
- basename(u->fragment_path),
+ bn,
NULL);
+ }
return u->unit_file_preset;
}
diff --git a/src/dissect/dissect.c b/src/dissect/dissect.c
index ed923c2c86..1c62d8eafc 100644
--- a/src/dissect/dissect.c
+++ b/src/dissect/dissect.c
@@ -1110,6 +1110,7 @@ static int action_list_or_mtree_or_copy(DissectedImage *m, LoopDevice *d) {
} else if (arg_action == ACTION_COPY_TO) {
_cleanup_close_ int source_fd = -EBADF, target_fd = -EBADF, dfd = -EBADF;
_cleanup_free_ char *dn = NULL, *bn = NULL;
+ bool is_dir;
r = path_extract_directory(arg_target, &dn);
if (r < 0)
@@ -1117,6 +1118,7 @@ static int action_list_or_mtree_or_copy(DissectedImage *m, LoopDevice *d) {
r = path_extract_filename(arg_target, &bn);
if (r < 0)
return log_error_errno(r, "Failed to extract filename from target path '%s': %m", arg_target);
+ is_dir = r == O_DIRECTORY;
r = chase_symlinks(dn, mounted_dir, CHASE_PREFIX_ROOT|CHASE_WARN, NULL, &dfd);
if (r < 0)
@@ -1124,6 +1126,9 @@ static int action_list_or_mtree_or_copy(DissectedImage *m, LoopDevice *d) {
/* Are we reading from stdin? */
if (streq(arg_source, "-")) {
+ if (is_dir)
+ return log_error_errno(SYNTHETIC_ERRNO(EISDIR), "Cannot copy STDIN to a directory, refusing.");
+
target_fd = openat(dfd, bn, O_WRONLY|O_CREAT|O_CLOEXEC|O_NOCTTY|O_EXCL, 0644);
if (target_fd < 0)
return log_error_errno(errno, "Failed to open target file '%s': %m", arg_target);
@@ -1161,8 +1166,11 @@ static int action_list_or_mtree_or_copy(DissectedImage *m, LoopDevice *d) {
return 0;
}
+ if (is_dir)
+ return log_error_errno(SYNTHETIC_ERRNO(EISDIR), "Source is a regular file, but target is not, refusing.");
+
/* We area looking at a regular file */
- target_fd = openat(dfd, basename(arg_target), O_WRONLY|O_CREAT|O_CLOEXEC|O_NOCTTY|O_EXCL, 0600);
+ target_fd = openat(dfd, bn, O_WRONLY|O_CREAT|O_CLOEXEC|O_NOCTTY|O_EXCL, 0600);
if (target_fd < 0)
return log_error_errno(errno, "Failed to open target file '%s': %m", arg_target);
diff --git a/src/home/homed-manager.c b/src/home/homed-manager.c
index 2fd1d67eff..e1af7aa1ad 100644
--- a/src/home/homed-manager.c
+++ b/src/home/homed-manager.c
@@ -1022,9 +1022,9 @@ static int manager_bind_varlink(Manager *m) {
return log_error_errno(r, "Failed to attach varlink connection to event loop: %m");
assert(!m->userdb_service);
- m->userdb_service = strdup(basename(socket_path));
- if (!m->userdb_service)
- return log_oom();
+ r = path_extract_filename(socket_path, &m->userdb_service);
+ if (r < 0)
+ return log_error_errno(r, "Failed to extra filename from socket path '%s': %m", socket_path);
/* Avoid recursion */
if (setenv("SYSTEMD_BYPASS_USERDB", m->userdb_service, 1) < 0)
@@ -1505,7 +1505,11 @@ static int manager_load_public_key_one(Manager *m, const char *path) {
assert(m);
- if (streq(basename(path), "local.public")) /* we already loaded the private key, which includes the public one */
+ r = path_extract_filename(path, &fn);
+ if (r < 0)
+ return log_error_errno(r, "Failed to extract filename of path '%s': %m", path);
+
+ if (streq(fn, "local.public")) /* we already loaded the private key, which includes the public one */
return 0;
f = fopen(path, "re");
@@ -1534,10 +1538,6 @@ static int manager_load_public_key_one(Manager *m, const char *path) {
if (!pkey)
return log_error_errno(SYNTHETIC_ERRNO(EIO), "Failed to parse public key file %s.", path);
- fn = strdup(basename(path));
- if (!fn)
- return log_oom();
-
r = hashmap_put(m->public_keys, fn, pkey);
if (r < 0)
return log_error_errno(r, "Failed to add public key to set: %m");
diff --git a/src/journal/journalctl.c b/src/journal/journalctl.c
index 7805c9cd9d..dd28517924 100644
--- a/src/journal/journalctl.c
+++ b/src/journal/journalctl.c
@@ -46,6 +46,7 @@
#include "log.h"
#include "logs-show.h"
#include "memory-util.h"
+#include "missing_sched.h"
#include "mkdir.h"
#include "mount-util.h"
#include "mountpoint-util.h"
@@ -1119,11 +1120,11 @@ static int add_matches(sd_journal *j, char **args) {
if (executable_is_script(p, &interpreter) > 0) {
_cleanup_free_ char *comm = NULL;
- comm = strndup(basename(p), 15);
- if (!comm)
- return log_oom();
+ r = path_extract_filename(p, &comm);
+ if (r < 0)
+ return log_error_errno(r, "Failed to extract filename of '%s': %m", p);
- t = strjoin("_COMM=", comm);
+ t = strjoin("_COMM=", strshorten(comm, TASK_COMM_LEN-1));
if (!t)
return log_oom();
diff --git a/src/mount/mount-tool.c b/src/mount/mount-tool.c
index f7dd705c5e..ea6d528189 100644
--- a/src/mount/mount-tool.c
+++ b/src/mount/mount-tool.c
@@ -1104,12 +1104,13 @@ static const char* get_label(sd_device *d) {
static int acquire_mount_where(sd_device *d) {
const char *v;
+ int r;
if (arg_mount_where)
return 0;
if (sd_device_get_property_value(d, "SYSTEMD_MOUNT_WHERE", &v) < 0) {
- _cleanup_free_ char *escaped = NULL;
+ _cleanup_free_ char *escaped = NULL, *devname_bn = NULL;
const char *name;
name = get_label(d);
@@ -1121,7 +1122,11 @@ static int acquire_mount_where(sd_device *d) {
if (sd_device_get_devname(d, &dn) < 0)
return 0;
- name = basename(dn);
+ r = path_extract_filename(dn, &devname_bn);
+ if (r < 0)
+ return log_error_errno(r, "Failed to extract file name from '%s': %m", dn);
+
+ name = devname_bn;
}
escaped = xescape(name, "\\");
@@ -1253,12 +1258,16 @@ static int discover_loop_backing_file(void) {
return log_error_errno(errno, "Can't get loop device for %s: %m", arg_mount_what);
if (r == -ENXIO) {
- _cleanup_free_ char *escaped = NULL;
+ _cleanup_free_ char *escaped = NULL, *bn = NULL;
if (arg_mount_where)
return 0;
- escaped = xescape(basename(arg_mount_what), "\\");
+ r = path_extract_filename(arg_mount_what, &bn);
+ if (r < 0)
+ return log_error_errno(r, "Failed to extract file name from backing file path '%s': %m", arg_mount_what);
+
+ escaped = xescape(bn, "\\");
if (!escaped)
return log_oom();
if (!filename_is_valid(escaped))
diff --git a/src/nspawn/nspawn-util.c b/src/nspawn/nspawn-util.c
index 830ac39e73..6c3848916d 100644
--- a/src/nspawn/nspawn-util.c
+++ b/src/nspawn/nspawn-util.c
@@ -47,10 +47,14 @@ int systemd_installation_has_version(const char *root, const char *minimal_versi
*c = '\0'; /* truncate the glob part */
STRV_FOREACH(name, names) {
+ _cleanup_free_ char *bn = NULL;
/* This is most likely to run only once, hence let's not optimize anything. */
char *t, *t2;
- t = startswith(basename(*name), "libsystemd-shared-");
+ if (path_extract_filename(*name, &bn) < 0)
+ continue;
+
+ t = startswith(bn, "libsystemd-shared-");
if (!t)
continue;
diff --git a/src/nspawn/nspawn.c b/src/nspawn/nspawn.c
index 067efbe3f0..551f8f975c 100644
--- a/src/nspawn/nspawn.c
+++ b/src/nspawn/nspawn.c
@@ -3045,16 +3045,19 @@ static int determine_names(void) {
else if (arg_image) {
char *e;
- arg_machine = strdup(basename(arg_image));
+ r = path_extract_filename(arg_image, &arg_machine);
+ if (r < 0)
+ return log_error_errno(r, "Failed to extract file name from '%s': %m", arg_image);
/* Truncate suffix if there is one */
e = endswith(arg_machine, ".raw");
if (e)
*e = 0;
- } else
- arg_machine = strdup(basename(arg_directory));
- if (!arg_machine)
- return log_oom();
+ } else {
+ r = path_extract_filename(arg_directory, &arg_machine);
+ if (r < 0)
+ return log_error_errno(r, "Failed to extract file name from '%s': %m", arg_directory);
+ }
hostname_cleanup(arg_machine);
if (!hostname_is_valid(arg_machine, 0))
diff --git a/src/partition/makefs.c b/src/partition/makefs.c
index 3f54bbb0da..2733763eb2 100644
--- a/src/partition/makefs.c
+++ b/src/partition/makefs.c
@@ -13,12 +13,13 @@
#include "fd-util.h"
#include "main-func.h"
#include "mkfs-util.h"
+#include "path-util.h"
#include "process-util.h"
#include "signal-util.h"
#include "string-util.h"
static int run(int argc, char *argv[]) {
- _cleanup_free_ char *device = NULL, *fstype = NULL, *detected = NULL;
+ _cleanup_free_ char *device = NULL, *fstype = NULL, *detected = NULL, *label = NULL;
_cleanup_close_ int lock_fd = -EBADF;
sd_id128_t uuid;
struct stat st;
@@ -65,7 +66,11 @@ static int run(int argc, char *argv[]) {
if (r < 0)
return log_error_errno(r, "Failed to generate UUID for file system: %m");
- return make_filesystem(device, fstype, basename(device), NULL, uuid, true, NULL);
+ r = path_extract_filename(device, &label);
+ if (r < 0)
+ return log_error_errno(r, "Failed to extract file name from '%s': %m", device);
+
+ return make_filesystem(device, fstype, label, NULL, uuid, true, NULL);
}
DEFINE_MAIN_FUNCTION(run);
diff --git a/src/partition/repart.c b/src/partition/repart.c
index 71018a79cc..6802a9c874 100644
--- a/src/partition/repart.c
+++ b/src/partition/repart.c
@@ -2461,7 +2461,7 @@ static int context_dump_partitions(Context *context) {
TABLE_STRING, gpt_partition_type_uuid_to_string_harder(p->type.uuid, uuid_buffer),
TABLE_STRING, empty_to_null(label) ?: "-", TABLE_SET_COLOR, empty_to_null(label) ? NULL : ansi_grey(),
TABLE_UUID, p->new_uuid_is_set ? p->new_uuid : p->current_uuid,
- TABLE_STRING, p->definition_path ? basename(p->definition_path) : "-", TABLE_SET_COLOR, p->definition_path ? NULL : ansi_grey(),
+ TABLE_PATH_BASENAME, p->definition_path, TABLE_SET_COLOR, p->definition_path ? NULL : ansi_grey(),
TABLE_STRING, partname ?: "-", TABLE_SET_COLOR, partname ? NULL : ansi_highlight(),
TABLE_UINT64, p->offset,
TABLE_UINT64, p->current_size == UINT64_MAX ? 0 : p->current_size,
@@ -2580,10 +2580,8 @@ static int partition_hint(const Partition *p, const char *node, char **ret) {
/* Tries really hard to find a suitable description for this partition */
- if (p->definition_path) {
- buf = strdup(basename(p->definition_path));
- goto done;
- }
+ if (p->definition_path)
+ return path_extract_filename(p->definition_path, ret);
label = partition_label(p);
if (!isempty(label)) {
diff --git a/src/portable/portablectl.c b/src/portable/portablectl.c
index ff71535c13..cd9f462bb3 100644
--- a/src/portable/portablectl.c
+++ b/src/portable/portablectl.c
@@ -123,11 +123,14 @@ static int attach_extensions_to_message(sd_bus_message *m, char **extensions) {
}
static int extract_prefix(const char *path, char **ret) {
- _cleanup_free_ char *name = NULL;
- const char *bn, *underscore;
+ _cleanup_free_ char *name = NULL, *bn = NULL;
+ const char *underscore;
size_t m;
+ int r;
- bn = basename(path);
+ r = path_extract_filename(path, &bn);
+ if (r < 0)
+ return r;
underscore = strchr(bn, '_');
if (underscore)
@@ -155,7 +158,6 @@ static int extract_prefix(const char *path, char **ret) {
return -EINVAL;
*ret = TAKE_PTR(name);
-
return 0;
}
@@ -591,7 +593,8 @@ static int maybe_enable_disable(sd_bus *bus, const char *path, bool enable) {
static int maybe_start_stop_restart(sd_bus *bus, const char *path, const char *method, BusWaitForJobs *wait) {
_cleanup_(sd_bus_message_unrefp) sd_bus_message *reply = NULL;
_cleanup_(sd_bus_error_free) sd_bus_error error = SD_BUS_ERROR_NULL;
- char *name = (char *)basename(path), *job = NULL;
+ _cleanup_free_ char *name = NULL;
+ const char *job = NULL;
int r;
assert(STR_IN_SET(method, "StartUnit", "StopUnit", "RestartUnit"));
@@ -599,6 +602,10 @@ static int maybe_start_stop_restart(sd_bus *bus, const char *path, const char *m
if (!arg_now)
return 0;
+ r = path_extract_filename(path, &name);
+ if (r < 0)
+ return log_error_errno(r, "Failed to extract file name from '%s': %m", path);
+
r = bus_call_method(
bus,
bus_systemd_mgr,
diff --git a/src/shared/btrfs-util.c b/src/shared/btrfs-util.c
index 0a4bd48b88..0ef3c608bb 100644
--- a/src/shared/btrfs-util.c
+++ b/src/shared/btrfs-util.c
@@ -51,20 +51,22 @@ static int validate_subvolume_name(const char *name) {
return 0;
}
-static int extract_subvolume_name(const char *path, const char **subvolume) {
- const char *fn;
+static int extract_subvolume_name(const char *path, char **ret) {
+ _cleanup_free_ char *fn = NULL;
int r;
assert(path);
- assert(subvolume);
+ assert(ret);
- fn = basename(path);
+ r = path_extract_filename(path, &fn);
+ if (r < 0)
+ return r;
r = validate_subvolume_name(fn);
if (r < 0)
return r;
- *subvolume = fn;
+ *ret = TAKE_PTR(fn);
return 0;
}
@@ -119,8 +121,8 @@ int btrfs_subvol_make_fd(int fd, const char *subvolume) {
}
int btrfs_subvol_make(const char *path) {
+ _cleanup_free_ char *subvolume = NULL;
_cleanup_close_ int fd = -EBADF;
- const char *subvolume;
int r;
assert(path);
@@ -1180,8 +1182,8 @@ static int subvol_remove_children(int fd, const char *subvolume, uint64_t subvol
}
int btrfs_subvol_remove(const char *path, BtrfsRemoveFlags flags) {
+ _cleanup_free_ char *subvolume = NULL;
_cleanup_close_ int fd = -EBADF;
- const char *subvolume;
int r;
assert(path);
@@ -1578,8 +1580,8 @@ int btrfs_subvol_snapshot_fd_full(
copy_progress_bytes_t progress_bytes,
void *userdata) {
+ _cleanup_free_ char *subvolume = NULL;
_cleanup_close_ int new_fd = -EBADF;
- const char *subvolume;
int r;
assert(old_fd >= 0);
diff --git a/src/shared/exec-util.c b/src/shared/exec-util.c
index cd922b84d4..f5283f9df4 100644
--- a/src/shared/exec-util.c
+++ b/src/shared/exec-util.c
@@ -18,6 +18,7 @@
#include "hashmap.h"
#include "macro.h"
#include "missing_syscall.h"
+#include "path-util.h"
#include "process-util.h"
#include "rlimit-util.h"
#include "serialize.h"
@@ -131,7 +132,13 @@ static int do_execute(
return log_oom();
if (callbacks) {
- fd = open_serialization_fd(basename(*path));
+ _cleanup_free_ char *bn = NULL;
+
+ r = path_extract_filename(*path, &bn);
+ if (r < 0)
+ return log_error_errno(r, "Failed to extract filename from path '%s': %m", *path);
+
+ fd = open_serialization_fd(bn);
if (fd < 0)
return log_error_errno(fd, "Failed to open serialization file: %m");
}
@@ -199,15 +206,16 @@ int execute_directories(
ExecDirFlags flags) {
char **dirs = (char**) directories;
+ _cleanup_free_ char *name = NULL;
_cleanup_close_ int fd = -EBADF;
- char *name;
int r;
pid_t executor_pid;
assert(!strv_isempty(dirs));
- name = basename(dirs[0]);
- assert(!isempty(name));
+ r = path_extract_filename(dirs[0], &name);
+ if (r < 0)
+ return log_error_errno(r, "Failed to extract file name from '%s': %m", dirs[0]);
if (callbacks) {
assert(callback_args);
diff --git a/src/shared/format-table.c b/src/shared/format-table.c
index 1c1db2f43a..4795e1ad80 100644
--- a/src/shared/format-table.c
+++ b/src/shared/format-table.c
@@ -281,6 +281,7 @@ static size_t table_data_size(TableDataType type, const void *data) {
case TABLE_STRING:
case TABLE_PATH:
+ case TABLE_PATH_BASENAME:
case TABLE_FIELD:
case TABLE_HEADER:
return strlen(data) + 1;
@@ -513,7 +514,7 @@ int table_add_cell_stringf_full(Table *t, TableCell **ret_cell, TableDataType dt
int r;
assert(t);
- assert(IN_SET(dt, TABLE_STRING, TABLE_PATH, TABLE_FIELD, TABLE_HEADER));
+ assert(IN_SET(dt, TABLE_STRING, TABLE_PATH, TABLE_PATH_BASENAME, TABLE_FIELD, TABLE_HEADER));
va_start(ap, format);
r = vasprintf(&buffer, format, ap);
@@ -873,6 +874,7 @@ int table_add_many_internal(Table *t, TableDataType first_type, ...) {
case TABLE_STRING:
case TABLE_PATH:
+ case TABLE_PATH_BASENAME:
case TABLE_FIELD:
case TABLE_HEADER:
data = va_arg(ap, const char *);
@@ -1281,6 +1283,7 @@ static int cell_data_compare(TableData *a, size_t index_a, TableData *b, size_t
return strcmp(a->string, b->string);
case TABLE_PATH:
+ case TABLE_PATH_BASENAME:
return path_compare(a->string, b->string);
case TABLE_STRV:
@@ -1453,15 +1456,24 @@ static const char *table_data_format(Table *t, TableData *d, bool avoid_uppercas
case TABLE_STRING:
case TABLE_PATH:
+ case TABLE_PATH_BASENAME:
case TABLE_FIELD:
- case TABLE_HEADER:
+ case TABLE_HEADER: {
+ _cleanup_free_ char *bn = NULL;
+ const char *s;
+
+ if (d->type == TABLE_PATH_BASENAME)
+ s = path_extract_filename(d->string, &bn) < 0 ? d->string : bn;
+ else
+ s = d->string;
+
if (d->uppercase && !avoid_uppercasing) {
- d->formatted = new(char, strlen(d->string) + (d->type == TABLE_FIELD) + 1);
+ d->formatted = new(char, strlen(s) + (d->type == TABLE_FIELD) + 1);
if (!d->formatted)
return NULL;
char *q = d->formatted;
- for (char *p = d->string; *p; p++)
+ for (const char *p = s; *p; p++)
*(q++) = (char) toupper((unsigned char) *p);
if (d->type == TABLE_FIELD)
@@ -1470,14 +1482,20 @@ static const char *table_data_format(Table *t, TableData *d, bool avoid_uppercas
*q = 0;
return d->formatted;
} else if (d->type == TABLE_FIELD) {
- d->formatted = strjoin(d->string, ":");
+ d->formatted = strjoin(s, ":");
if (!d->formatted)
return NULL;
return d->formatted;
}
+ if (bn) {
+ d->formatted = TAKE_PTR(bn);
+ return d->formatted;
+ }
+
return d->string;
+ }
case TABLE_STRV:
if (strv_isempty(d->strv))
@@ -2544,6 +2562,7 @@ static int table_data_to_json(TableData *d, JsonVariant **ret) {
case TABLE_STRING:
case TABLE_PATH:
+ case TABLE_PATH_BASENAME:
case TABLE_FIELD:
case TABLE_HEADER:
return json_variant_new_string(ret, d->string);
diff --git a/src/shared/format-table.h b/src/shared/format-table.h
index e835692c6f..0e8aecffe6 100644
--- a/src/shared/format-table.h
+++ b/src/shared/format-table.h
@@ -17,6 +17,7 @@ typedef enum TableDataType {
TABLE_STRV,
TABLE_STRV_WRAPPED,
TABLE_PATH,
+ TABLE_PATH_BASENAME, /* like TABLE_PATH, but display only last path element (i.e. the "basename") in regular output */
TABLE_BOOLEAN,
TABLE_BOOLEAN_CHECKMARK,
TABLE_TIMESTAMP,
diff --git a/src/shared/generator.c b/src/shared/generator.c
index da3eaadbf4..6d95aa72f8 100644
--- a/src/shared/generator.c
+++ b/src/shared/generator.c
@@ -60,13 +60,19 @@ int generator_open_unit_file(
}
int generator_add_symlink(const char *dir, const char *dst, const char *dep_type, const char *src) {
+ _cleanup_free_ char *bn = NULL;
+ const char *from, *to;
+ int r;
+
/* Adds a symlink from <dst>.<dep_type>/ to <src> (if src is absolute)
* or ../<src> (otherwise). */
- const char *from, *to;
+ r = path_extract_filename(src, &bn);
+ if (r < 0)
+ return log_error_errno(r, "Failed to extract filename from '%s': %m", src);
from = path_is_absolute(src) ? src : strjoina("../", src);
- to = strjoina(dir, "/", dst, ".", dep_type, "/", basename(src));
+ to = strjoina(dir, "/", dst, ".", dep_type, "/", bn);
(void) mkdir_parents_label(to, 0755);
if (symlink(from, to) < 0)
diff --git a/src/shared/lockfile-util.c b/src/shared/lockfile-util.c
index b920f3fe9b..df099d7d05 100644
--- a/src/shared/lockfile-util.c
+++ b/src/shared/lockfile-util.c
@@ -20,15 +20,15 @@ int make_lock_file(const char *p, int operation, LockFile *ret) {
_cleanup_free_ char *t = NULL;
int r;
+ assert(p);
+ assert(ret);
+
/*
- * We use UNPOSIX locks if they are available. They have nice
- * semantics, and are mostly compatible with NFS. However,
- * they are only available on new kernels. When we detect we
- * are running on an older kernel, then we fall back to good
- * old BSD locks. They also have nice semantics, but are
- * slightly problematic on NFS, where they are upgraded to
- * POSIX locks, even though locally they are orthogonal to
- * POSIX locks.
+ * We use UNPOSIX locks if they are available. They have nice semantics, and are mostly compatible
+ * with NFS. However, they are only available on new kernels. When we detect we are running on an
+ * older kernel, then we fall back to good old BSD locks. They also have nice semantics, but are
+ * slightly problematic on NFS, where they are upgraded to POSIX locks, even though locally they are
+ * orthogonal to POSIX locks.
*/
t = strdup(p);
@@ -48,23 +48,18 @@ int make_lock_file(const char *p, int operation, LockFile *ret) {
r = fcntl(fd, (operation & LOCK_NB) ? F_OFD_SETLK : F_OFD_SETLKW, &fl);
if (r < 0) {
-
/* If the kernel is too old, use good old BSD locks */
- if (errno == EINVAL)
+ if (errno == EINVAL || ERRNO_IS_NOT_SUPPORTED(errno))
r = flock(fd, operation);
-
if (r < 0)
return errno == EAGAIN ? -EBUSY : -errno;
}
- /* If we acquired the lock, let's check if the file
- * still exists in the file system. If not, then the
- * previous exclusive owner removed it and then closed
- * it. In such a case our acquired lock is worthless,
- * hence try again. */
+ /* If we acquired the lock, let's check if the file still exists in the file system. If not,
+ * then the previous exclusive owner removed it and then closed it. In such a case our
+ * acquired lock is worthless, hence try again. */
- r = fstat(fd, &st);
- if (r < 0)
+ if (fstat(fd, &st) < 0)
return -errno;
if (st.st_nlink > 0)
break;
@@ -72,29 +67,33 @@ int make_lock_file(const char *p, int operation, LockFile *ret) {
fd = safe_close(fd);
}
- ret->path = t;
- ret->fd = fd;
- ret->operation = operation;
-
- fd = -EBADF;
- t = NULL;
+ *ret = (LockFile) {
+ .path = TAKE_PTR(t),
+ .fd = TAKE_FD(fd),
+ .operation = operation,
+ };
return r;
}
int make_lock_file_for(const char *p, int operation, LockFile *ret) {
- const char *fn;
- char *t;
+ _cleanup_free_ char *fn = NULL, *dn = NULL, *t = NULL;
+ int r;
assert(p);
assert(ret);
- fn = basename(p);
- if (!filename_is_valid(fn))
- return -EINVAL;
+ r = path_extract_filename(p, &fn);
+ if (r < 0)
+ return r;
+
+ r = path_extract_directory(p, &dn);
+ if (r < 0)
+ return r;
- t = newa(char, strlen(p) + 2 + 4 + 1);
- stpcpy(stpcpy(stpcpy(mempcpy(t, p, fn - p), ".#"), fn), ".lck");
+ t = strjoin(dn, "/.#", fn, ".lck");
+ if (!t)
+ return -ENOMEM;
return make_lock_file(t, operation, ret);
}
@@ -119,7 +118,7 @@ void release_lock_file(LockFile *f) {
};
r = fcntl(f->fd, F_OFD_SETLK, &fl);
- if (r < 0 && errno == EINVAL)
+ if (r < 0 && (errno == EINVAL || ERRNO_IS_NOT_SUPPORTED(errno)))
r = flock(f->fd, LOCK_EX|LOCK_NB);
if (r >= 0)
diff --git a/src/shared/mount-util.c b/src/shared/mount-util.c
index 603eb7b780..8aad531a4d 100644
--- a/src/shared/mount-util.c
+++ b/src/shared/mount-util.c
@@ -952,7 +952,7 @@ static int mount_in_namespace(
if (r < 0)
goto finish;
if (r == 0) {
- const char *mount_inside;
+ _cleanup_free_ char *mount_outside_fn = NULL, *mount_inside = NULL;
errno_pipe_fd[0] = safe_close(errno_pipe_fd[0]);
@@ -965,8 +965,19 @@ static int mount_in_namespace(
}
/* Fifth, move the mount to the right place inside */
- mount_inside = strjoina(incoming_path, basename(mount_outside));
- r = mount_nofollow_verbose(LOG_ERR, mount_inside, dest, NULL, MS_MOVE, NULL);
+ r = path_extract_filename(mount_outside, &mount_outside_fn);
+ if (r < 0) {
+ log_debug_errno(r, "Failed to extract filename from propagation file or directory '%s': %m", mount_outside);
+ goto child_fail;
+ }
+
+ mount_inside = path_join(incoming_path, mount_outside_fn);
+ if (!mount_inside) {
+ r = log_oom_debug();
+ goto child_fail;
+ }
+
+ r = mount_nofollow_verbose(LOG_DEBUG, mount_inside, dest, NULL, MS_MOVE, NULL);
if (r < 0)
goto child_fail;
diff --git a/src/shared/tests.c b/src/shared/tests.c
index 54e80decd1..8884c8e90e 100644
--- a/src/shared/tests.c
+++ b/src/shared/tests.c
@@ -7,12 +7,6 @@
#include <sys/mount.h>
#include <sys/wait.h>
-/* When we include libgen.h because we need dirname() we immediately
- * undefine basename() since libgen.h defines it as a macro to the POSIX
- * version which is really broken. We prefer GNU basename(). */
-#include <libgen.h>
-#undef basename
-
#include "sd-bus.h"
#include "alloc-util.h"
diff --git a/src/sysv-generator/sysv-generator.c b/src/sysv-generator/sysv-generator.c
index 9b465e8c84..7c290a8b0d 100644
--- a/src/sysv-generator/sysv-generator.c
+++ b/src/sysv-generator/sysv-generator.c
@@ -244,21 +244,22 @@ static int sysv_translate_facility(SysvStub *s, unsigned line, const char *name,
"time", SPECIAL_TIME_SYNC_TARGET,
};
- const char *filename;
- char *filename_no_sh, *e, *m;
+ _cleanup_free_ char *filename = NULL;
const char *n;
- unsigned i;
+ char *e, *m;
int r;
assert(name);
assert(s);
assert(ret);
- filename = basename(s->path);
+ r = path_extract_filename(s->path, &filename);
+ if (r < 0)
+ return log_error_errno(r, "Failed to extract file name from path '%s': %m", s->path);
n = *name == '$' ? name + 1 : name;
- for (i = 0; i < ELEMENTSOF(table); i += 2) {
+ for (size_t i = 0; i < ELEMENTSOF(table); i += 2) {
if (!streq(table[i], n))
continue;
@@ -288,12 +289,9 @@ static int sysv_translate_facility(SysvStub *s, unsigned line, const char *name,
}
/* Strip ".sh" suffix from file name for comparison */
- filename_no_sh = strdupa_safe(filename);
- e = endswith(filename_no_sh, ".sh");
- if (e) {
+ e = endswith(filename, ".sh");
+ if (e)
*e = '\0';
- filename = filename_no_sh;
- }
/* Names equaling the file name of the services are redundant */
if (streq_ptr(n, filename)) {
diff --git a/src/test/test-format-table.c b/src/test/test-format-table.c
index 14341b97b4..a1bc8b99ac 100644
--- a/src/test/test-format-table.c
+++ b/src/test/test-format-table.c
@@ -565,6 +565,24 @@ TEST(vertical) {
assert_se(json_variant_equal(a, b));
}
+TEST(path_basename) {
+ _cleanup_(table_unrefp) Table *t = NULL;
+ _cleanup_free_ char *formatted = NULL;
+
+ assert_se(t = table_new("x"));
+
+ table_set_header(t, false);
+
+ assert_se(table_add_many(t,
+ TABLE_PATH_BASENAME, "/foo/bar",
+ TABLE_PATH_BASENAME, "/quux/bar",
+ TABLE_PATH_BASENAME, "/foo/baz") >= 0);
+
+ assert_se(table_format(t, &formatted) >= 0);
+
+ assert_se(streq(formatted, "bar\nbar\nbaz\n"));
+}
+
static int intro(void) {
assert_se(setenv("SYSTEMD_COLORS", "0", 1) >= 0);
assert_se(setenv("COLUMNS", "40", 1) >= 0);
diff --git a/src/tmpfiles/offline-passwd.c b/src/tmpfiles/offline-passwd.c
index f7d3978c93..f712099b0b 100644
--- a/src/tmpfiles/offline-passwd.c
+++ b/src/tmpfiles/offline-passwd.c
@@ -9,8 +9,9 @@
DEFINE_PRIVATE_HASH_OPS_WITH_KEY_DESTRUCTOR(uid_gid_hash_ops, char, string_hash_func, string_compare_func, free);
static int open_passwd_file(const char *root, const char *fname, FILE **ret_file) {
- _cleanup_free_ char *p = NULL;
+ _cleanup_free_ char *p = NULL, *bn = NULL;
_cleanup_close_ int fd = -EBADF;
+ int r;
fd = chase_symlinks_and_open(fname, root, CHASE_PREFIX_ROOT, O_RDONLY|O_CLOEXEC, &p);
if (fd < 0)
@@ -22,7 +23,11 @@ static int open_passwd_file(const char *root, const char *fname, FILE **ret_file
TAKE_FD(fd);
- log_debug("Reading %s entries from %s...", basename(fname), p);
+ r = path_extract_filename(fname, &bn);
+ if (r < 0)
+ return r;
+
+ log_debug("Reading %s entries from %s...", bn, p);
*ret_file = f;
return 0;