diff options
Diffstat (limited to 'sys-fs/btrfs-progs/files/btrfs-progs-6.8-musl-1.2.5.patch')
-rw-r--r-- | sys-fs/btrfs-progs/files/btrfs-progs-6.8-musl-1.2.5.patch | 209 |
1 files changed, 209 insertions, 0 deletions
diff --git a/sys-fs/btrfs-progs/files/btrfs-progs-6.8-musl-1.2.5.patch b/sys-fs/btrfs-progs/files/btrfs-progs-6.8-musl-1.2.5.patch new file mode 100644 index 000000000000..19737515b616 --- /dev/null +++ b/sys-fs/btrfs-progs/files/btrfs-progs-6.8-musl-1.2.5.patch @@ -0,0 +1,209 @@ +From 45ca77f9e4cfe5fd5814d553502ef99877c9e972 Mon Sep 17 00:00:00 2001 +From: David Sterba <dsterba@suse.com> +Date: Thu, 18 Apr 2024 18:57:08 +0200 +Subject: [PATCH] btrfs-progs: add basename wrappers for unified semantics + +What basename(3) does with the argument depends on _GNU_SOURCE and +inclusion of libgen.h. This is problematic on Musl (1.2.5) as reported. + +We want the GNU semantics that does not modify the argument. Common way +to make it portable is to add own helper. This is now implemented in +path_basename() that does not use the libc provided basename but preserves +the semantics. The path_dirname() is just for parity, otherwise same as +dirname(). + +Sources: +- https://bugs.gentoo.org/926288 +- https://git.musl-libc.org/cgit/musl/commit/?id=725e17ed6dff4d0cd22487bb64470881e86a92e7 + +Issue: #778 +Signed-off-by: David Sterba <dsterba@suse.com> +--- + cmds/subvolume.c | 26 +++++++++++++------------- + common/device-utils.c | 4 ++-- + common/path-utils.c | 28 ++++++++++++++++++++++++++++ + common/path-utils.h | 2 ++ + 4 files changed, 45 insertions(+), 15 deletions(-) + +diff --git a/cmds/subvolume.c b/cmds/subvolume.c +index 5d53efe6f..869d7077d 100644 +--- a/cmds/subvolume.c ++++ b/cmds/subvolume.c +@@ -24,7 +24,6 @@ + #include <string.h> + #include <unistd.h> + #include <errno.h> +-#include <libgen.h> + #include <getopt.h> + #include <dirent.h> + #include <stdbool.h> +@@ -149,7 +148,7 @@ static int create_one_subvolume(const char *dst, struct btrfs_qgroup_inherit *in + int fddst = -1; + char *dupname = NULL; + char *dupdir = NULL; +- char *newname; ++ const char *newname; + char *dstdir; + + ret = path_is_dir(dst); +@@ -170,7 +169,7 @@ static int create_one_subvolume(const char *dst, struct btrfs_qgroup_inherit *in + ret = -ENOMEM; + goto out; + } +- newname = basename(dupname); ++ newname = path_basename(dupname); + + dupdir = strdup(dst); + if (!dupdir) { +@@ -178,7 +177,7 @@ static int create_one_subvolume(const char *dst, struct btrfs_qgroup_inherit *in + ret = -ENOMEM; + goto out; + } +- dstdir = dirname(dupdir); ++ dstdir = path_dirname(dupdir); + + if (!test_issubvolname(newname)) { + error("invalid subvolume name: %s", newname); +@@ -364,7 +363,8 @@ static int cmd_subvolume_delete(const struct cmd_struct *cmd, int argc, char **a + int res, ret = 0; + int cnt; + int fd = -1; +- char *dname, *vname, *cpath; ++ char *dname, *cpath; ++ const char *vname; + char *dupdname = NULL; + char *dupvname = NULL; + char *path = NULL; +@@ -482,9 +482,9 @@ static int cmd_subvolume_delete(const struct cmd_struct *cmd, int argc, char **a + goto out; + } + dupdname = strdup(cpath); +- dname = dirname(dupdname); ++ dname = path_dirname(dupdname); + dupvname = strdup(cpath); +- vname = basename(dupvname); ++ vname = path_basename(dupvname); + free(cpath); + + /* When subvolid is passed, <path> will point to the mount point */ +@@ -670,7 +670,7 @@ static int cmd_subvolume_snapshot(const struct cmd_struct *cmd, int argc, char * + bool readonly = false; + char *dupname = NULL; + char *dupdir = NULL; +- char *newname; ++ const char *newname; + char *dstdir; + enum btrfs_util_error err; + struct btrfs_ioctl_vol_args_v2 args; +@@ -727,13 +727,13 @@ static int cmd_subvolume_snapshot(const struct cmd_struct *cmd, int argc, char * + + if (res > 0) { + dupname = strdup(subvol); +- newname = basename(dupname); ++ newname = path_basename(dupname); + dstdir = dst; + } else { + dupname = strdup(dst); +- newname = basename(dupname); ++ newname = path_basename(dupname); + dupdir = strdup(dst); +- dstdir = dirname(dupdir); ++ dstdir = path_dirname(dupdir); + } + + if (!test_issubvolname(newname)) { +@@ -1557,7 +1557,7 @@ static int cmd_subvolume_show(const struct cmd_struct *cmd, int argc, char **arg + struct btrfs_util_subvolume_iterator *iter; + struct btrfs_util_subvolume_info subvol; + char *subvol_path = NULL; +- char *subvol_name = NULL; ++ const char *subvol_name = NULL; + enum btrfs_util_error err; + struct btrfs_qgroup_stats stats; + unsigned int unit_mode; +@@ -1669,7 +1669,7 @@ static int cmd_subvolume_show(const struct cmd_struct *cmd, int argc, char **arg + subvol_path = strdup("/"); + subvol_name = "<FS_TREE>"; + } else { +- subvol_name = basename(subvol_path); ++ subvol_name = path_basename(subvol_path); + } + + if (bconf.output_format == CMD_FORMAT_JSON) { +diff --git a/common/device-utils.c b/common/device-utils.c +index 36108ec4e..d086e9ea2 100644 +--- a/common/device-utils.c ++++ b/common/device-utils.c +@@ -343,14 +343,14 @@ static u64 device_get_partition_size_sysfs(const char *dev) + char path[PATH_MAX] = {}; + char sysfs[PATH_MAX] = {}; + char sizebuf[128] = {}; +- char *name = NULL; ++ const char *name = NULL; + int sysfd; + unsigned long long size = 0; + + name = realpath(dev, path); + if (!name) + return 0; +- name = basename(path); ++ name = path_basename(path); + + ret = path_cat3_out(sysfs, "/sys/class/block", name, "size"); + if (ret < 0) +diff --git a/common/path-utils.c b/common/path-utils.c +index 181737c4d..929e5c8fa 100644 +--- a/common/path-utils.c ++++ b/common/path-utils.c +@@ -28,6 +28,11 @@ + #include <string.h> + #include <errno.h> + #include <ctype.h> ++/* ++ * For dirname() and basename(), but never use basename directly, there's ++ * path_basename() with unified GNU behaviour regardless of the includes and ++ * conditional defines. See basename(3) for more. ++ */ + #include <libgen.h> + #include <limits.h> + #include "common/path-utils.h" +@@ -482,3 +487,26 @@ int test_issubvolname(const char *name) + strcmp(name, ".") && strcmp(name, ".."); + } + ++/* ++ * Unified GNU semantics basename helper, never changing the argument. Always ++ * use this instead of basename(). ++ */ ++const char *path_basename(const char *path) ++{ ++ const char *tmp = strrchr(path, '/'); ++ ++ /* Special case when the whole path is just "/". */ ++ if (path[0] == '/' && path[1] == 0) ++ return path; ++ ++ return tmp ? tmp + 1 : path; ++} ++ ++/* ++ * Return dirname component of path, may change the argument. ++ * Own helper for parity with path_basename(). ++ */ ++char *path_dirname(char *path) ++{ ++ return dirname(path); ++} +diff --git a/common/path-utils.h b/common/path-utils.h +index 08ae0ff10..697fa6b48 100644 +--- a/common/path-utils.h ++++ b/common/path-utils.h +@@ -39,6 +39,8 @@ int path_is_dir(const char *path); + int is_same_loop_file(const char *a, const char *b); + int path_is_reg_or_block_device(const char *filename); + int path_is_in_dir(const char *parent, const char *path); ++const char *path_basename(const char *path); ++char *path_dirname(char *path); + + int test_issubvolname(const char *name); + |