genfstab

simple implementation of genfstab
git clone git://git.ckyln.com/~cem/genfstab.git
Log | Files | Refs | README | LICENSE

commit af171b63affa4101fc84c06872e92b2d25ff5298
parent c1fbac9c3062662fded7f0ebafb2fd7f722eb6ba
Author: Cem Keylan <cem@ckyln.com>
Date:   Fri, 13 Aug 2021 09:14:52 +0300

genfstab: remove all usage of readlink(1)

Diffstat:
Mgenfstab | 49++++++++++++++++++++++++++++++++++++++-----------
1 file changed, 38 insertions(+), 11 deletions(-)

diff --git a/genfstab b/genfstab @@ -21,7 +21,7 @@ find_tag() { die "Directory '$dir' doesn't exist" for file in "$tagdir/"*; do - [ "$(readlink -f "$file")" = "$1" ] || continue + [ "$(_readlinkf "$file")" = "$1" ] || continue tag="$ident=${file##*/}" break done @@ -31,14 +31,41 @@ find_tag() { out "${tag:-$1}" } -readlink_sh() ( - # This function changes directory to the given path in order to find the - # real location of the given directory. We are doing this in a subshell - # so that we return to our previous location. Sadly, we cannot use this - # function on 'find_tag()' as this only works for resolving directory paths. - cd -P "$1" || return 1 - printf '%s\n' "$PWD" -) +_readlinkf() { + # https://github.com/ko1nksm/readlinkf + [ "${1:-}" ] || return 1 + max_symlinks=40 + CDPATH='' # to avoid changing to an unexpected directory + + target=$1 + [ -e "${target%/}" ] || target=${1%"${1##*[!/]}"} # trim trailing slashes + [ -d "${target:-/}" ] && target="$target/" + + cd -P . 2>/dev/null || return 1 + while [ "$max_symlinks" -ge 0 ] && max_symlinks=$((max_symlinks - 1)); do + if [ ! "$target" = "${target%/*}" ]; then + case $target in + /*) cd -P "${target%/*}/" 2>/dev/null || break ;; + *) cd -P "./${target%/*}" 2>/dev/null || break ;; + esac + target=${target##*/} + fi + + if [ ! -L "$target" ]; then + target="${PWD%/}${target:+/}${target}" + printf '%s\n' "${target:-/}" + return 0 + fi + + # `ls -dl` format: "%s %u %s %s %u %s %s -> %s\n", + # <file mode>, <number of links>, <owner name>, <group name>, + # <size>, <date and time>, <pathname of link>, <contents of link> + # https://pubs.opengroup.org/onlinepubs/9699919799/utilities/ls.html + link=$(ls -dl -- "$target" 2>/dev/null) || break + target=${link#*" $target -> "} + done + return 1 +} ispseudo() { # This function checks for pseudo-filesystems and returns 0 if it is. @@ -96,7 +123,7 @@ while getopts PpLUf:t: flag; do L) ident=LABEL ;; U) ident=UUID ;; f) [ -d "$OPTARG" ] || die "Not a directory '$OPTARG'" - filter=$(readlink_sh "$OPTARG") ;; + filter=$(_readlinkf "$OPTARG") ;; t) case "$OPTARG" in LABEL|UUID|PARTLABEL|PARTUUID) ident=$OPTARG ;; *) die "Unknown identifier '$OPTARG'"; esac @@ -108,7 +135,7 @@ shift $(( OPTIND - 1 )) [ "$1" ] && { [ -d "$1" ] || die "Not a directory '$1'" - root="$(readlink_sh "$1")" + root="$(_readlinkf "$1")" } # It's a good thing that /proc/mounts and fstab share the same syntax. We will