diff options
author | Yu Watanabe <watanabe.yu+github@gmail.com> | 2022-12-24 00:13:00 +0100 |
---|---|---|
committer | GitHub <noreply@github.com> | 2022-12-24 00:13:00 +0100 |
commit | 20ada514648d2c479a49689c6714c72af31ab8f6 (patch) | |
tree | 81b91da00312fef71aeb10ed9e0d339ce708474a /src | |
parent | prioq: make prioq_reshuffle() void (diff) | |
parent | lock-file: various updates (diff) | |
download | systemd-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.c | 12 | ||||
-rw-r--r-- | src/core/execute.c | 23 | ||||
-rw-r--r-- | src/core/manager.c | 14 | ||||
-rw-r--r-- | src/core/unit.c | 16 | ||||
-rw-r--r-- | src/dissect/dissect.c | 10 | ||||
-rw-r--r-- | src/home/homed-manager.c | 16 | ||||
-rw-r--r-- | src/journal/journalctl.c | 9 | ||||
-rw-r--r-- | src/mount/mount-tool.c | 17 | ||||
-rw-r--r-- | src/nspawn/nspawn-util.c | 6 | ||||
-rw-r--r-- | src/nspawn/nspawn.c | 13 | ||||
-rw-r--r-- | src/partition/makefs.c | 9 | ||||
-rw-r--r-- | src/partition/repart.c | 8 | ||||
-rw-r--r-- | src/portable/portablectl.c | 17 | ||||
-rw-r--r-- | src/shared/btrfs-util.c | 18 | ||||
-rw-r--r-- | src/shared/exec-util.c | 16 | ||||
-rw-r--r-- | src/shared/format-table.c | 29 | ||||
-rw-r--r-- | src/shared/format-table.h | 1 | ||||
-rw-r--r-- | src/shared/generator.c | 10 | ||||
-rw-r--r-- | src/shared/lockfile-util.c | 63 | ||||
-rw-r--r-- | src/shared/mount-util.c | 17 | ||||
-rw-r--r-- | src/shared/tests.c | 6 | ||||
-rw-r--r-- | src/sysv-generator/sysv-generator.c | 18 | ||||
-rw-r--r-- | src/test/test-format-table.c | 18 | ||||
-rw-r--r-- | src/tmpfiles/offline-passwd.c | 9 |
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; |