From 5d248463cd5692e3637985105e18d0c41b7ffdee Mon Sep 17 00:00:00 2001 From: Samuel Holland Date: Sat, 15 Sep 2018 18:46:23 +0000 Subject: system/musl: Add a more fully-featured ldconfig --- system/musl/ldconfig | 196 +++++++++++++++++++++++++++++++++++++++++++++++---- 1 file changed, 181 insertions(+), 15 deletions(-) (limited to 'system/musl/ldconfig') diff --git a/system/musl/ldconfig b/system/musl/ldconfig index ccf7c2aa4..7699c6722 100644 --- a/system/musl/ldconfig +++ b/system/musl/ldconfig @@ -1,18 +1,184 @@ -#!/bin/sh -scan_dirs() { - scanelf -qS "$@" | while read SONAME FILE; do - TARGET="${FILE##*/}" - LINK="${FILE%/*}/$SONAME" - case "$FILE" in - /lib/*|/usr/lib/*|/usr/local/lib/*) ;; - *) [ -h "$LINK" -o ! -e "$LINK" ] && ln -sf "$TARGET" "$LINK" - esac +#!/bin/sh -eu +# Copyright 2016-2018 Samuel Holland +# SPDX-License-Identifier: 0BSD + +ME=${0##*/} +VERSION=0.2.0 + +echo() { + printf '%s\n' "$*" +} + +echo_lines() { + printf '%s\n' "$@" +} + +msg() { + printf >&2 '%s: %s\n' "$ME" "$*" +} + +musl_arch() { + $ROOT/usr/lib/libc.so |& sed -n 's/^musl libc (\(.*\))$/\1/p' +} + +musl_version() { + $ROOT/usr/lib/libc.so |& sed -n 's/^Version //p' +} + +read_ldso_conf() { + local conf="$*" d dir file glob line + + # Start with the default "trusted" directories + set -- /lib /usr/lib + for file in $conf; do + test -r "$file" || continue + $VERBOSE && msg "Reading ${file}" + while read -r line; do + line=$(tokenize ${line%%#*}) + if test "${line#include }" != "$line"; then + glob=${file%/*}/${line#include } + $VERBOSE && msg "Including ${glob}" + line=$(read_ldso_conf $glob) + fi + for dir in $line; do + # Ignore missing directories + test -d "$ROOT$dir" || continue + # Ignore duplicate directories + for d; do test "$d" = "$dir" && continue 2; done + set -- "$@" "$dir" + done + done < "$file" done - return 0 + + echo_lines "$@" +} + +tokenize() { + echo "$*" | sed 's/=libc[456]//g;y/:,/ /' | xargs } -# eat ldconfig options -while getopts "nNvXvf:C:r:" opt; do - : + +LDSO_CACHE="/etc/ld.so.cache" +LDSO_CONF="/etc/ld.so.conf" +LIBRARY_MODE=false +ONLYARG_MODE=false +PRINT_CACHE=false +PRINT_VERSION=false +ROOT= +UPDATE_CACHE=true +UPDATE_LINKS=true +VERBOSE=false + +while getopts ":c:C:Df:ilnNpr:vVX" OPTION; do + case "$OPTION" in + C) + LDSO_CACHE=$OPTARG + ;; + D) + UPDATE_CACHE=false + UPDATE_LINKS=false + ;; + f) + LDSO_CONF=$OPTARG + ;; + l) + LIBRARY_MODE=true + ;; + n) + ONLYARG_MODE=true + ;; + N) + UPDATE_CACHE=false + ;; + p) + PRINT_CACHE=true + ;; + r) + ROOT=$OPTARG + if ! test -x $ROOT/usr/lib/libc.so; then + msg "${ROOT} does not appear to be a valid root directory" + exit 1 + fi + ;; + v) + VERBOSE=true + ;; + V) + PRINT_VERSION=true + ;; + X) + UPDATE_LINKS=false + ;; + c|i) + msg "Ignored option -${OPTION}" + ;; + \?) + msg "Invalid option -${OPTARG}" + cat >&2 <<- EOF + Usage: $ME [-DnNvX] [-C cache] [-f conf] [-r root] [dir...] + $ME [-v] -l lib... + $ME [-v] [-C cache] [-r root] -p + $ME -V + EOF + exit 1 + ;; + esac done -shift $(( $OPTIND - 1 )) -[ $# -gt 0 ] && scan_dirs "$@" +shift $((OPTIND-1)) + +BANNER="ldconfig ${VERSION} for musl $(musl_version)" +LDSO_CACHE="$ROOT$LDSO_CACHE" +LDSO_CONF="$ROOT$LDSO_CONF" +LDSO_PATH="$ROOT/etc/ld-musl-$(musl_arch).path" +LDSO_PATH_TMP="$LDSO_PATH.$$" + +if $PRINT_VERSION; then + echo "$BANNER" + exit 0 +elif $PRINT_CACHE; then + test -r "$LDSO_PATH" && cat "$LDSO_PATH" + exit 0 +fi + +$VERBOSE && echo "$BANNER" + +if $LIBRARY_MODE; then + for lib; do + soname=$(scanelf -qS "$ROOT$lib") + soname=${soname%% *} + done + exit 0 +fi + +# Update musl's list of library paths +if ! test -w "${LDSO_PATH%/*}"; then + msg "You do not have permission to update ${LDSO_PATH}" + exit 0 +fi +trap 'rm -f "$LDSO_PATH_TMP"' EXIT +read_ldso_conf "$LDSO_CONF" > "$LDSO_PATH_TMP" +$VERBOSE && msg "Writing ${LDSO_PATH}" +mv "$LDSO_PATH_TMP" "$LDSO_PATH" +trap - EXIT + +# Read the updated list of library paths +$ONLYARG_MODE || set -- "$@" $(cat "$LDSO_PATH") + +if $UPDATE_LINKS; then + for dir; do + # Packages are responsible for libraries in these directories + if test "$dir" = /lib || test "$dir" = /usr/lib; then + continue + fi + $VERBOSE && msg "Scanning ${ROOT}${dir}" + scanelf -qS "$ROOT$dir" | while read soname file; do + link=${file%/*}/$soname + test -f "$link" && continue + $VERBOSE && msg "Creating link ${link}" + ln -fns "${file##*/}" "$link" + done + done +fi + +if $UPDATE_CACHE && test $# -gt 0; then + touch "$ROOT$LDSO_CACHE" +fi -- cgit v1.2.3-60-g2f50