+_relpath() {
+ local base="$(readlink -f "$1")"
+ local dest="$(readlink -f "$2")"
+ local up
+
+ [ -d "$base" ] || base="${base%/*}"
+ [ -d "$dest" ] || dest="${dest%/*}"
+
+ while true; do
+ case "$base"
+ in "$dest"/*)
+ echo "$up/${base#$dest/}"
+ break
+ ;;
+ *)
+ dest="${dest%/*}"
+ up="${up:+$up/}.."
+ ;;
+ esac
+ done
+}
+
+_runas_so() {
+ cat <<-EOT | ${CC:-gcc} -x c -fPIC -shared -o "$1" -
+ #include <unistd.h>
+ #include <stdio.h>
+ #include <stdlib.h>
+
+ int mangle_arg0(int argc, char **argv, char **env) {
+ char *arg0 = getenv("RUNAS_ARG0");
+
+ if (arg0) {
+ argv[0] = arg0;
+ unsetenv("RUNAS_ARG0");
+ }
+
+ return 0;
+ }
+
+ #ifdef __APPLE__
+ __attribute__((section("__DATA,__mod_init_func")))
+ #else
+ __attribute__((section(".init_array")))
+ #endif
+ static void *mangle_arg0_constructor = &mangle_arg0;
+ EOT
+
+ [ -x "$1" ] || {
+ echo "compiling preload library failed" >&2
+ exit 5
+ }
+}
+
+_patch_ldso() {
+ _cp "$1" "$1.patched"
+ sed -i -e 's,/\(usr\|lib\|etc\)/,/###/,g' "$1.patched"
+
+ if "$1.patched" 2>&1 | grep -q -- --library-path; then
+ _mv "$1.patched" "$1"
+ else
+ echo "binary patched ${1##*/} not executable, using original" >&2
+ rm -f "$1.patched"
+ fi
+}
+
+_patch_glibc() {
+ _cp "$1" "$1.patched"
+ sed -i -e 's,/usr/\(\(lib\|share\)/locale\),/###/\1,g' "$1.patched"
+
+ if "$1.patched" 2>&1 | grep -q -- GNU; then
+ _mv "$1.patched" "$1"
+ else
+ echo "binary patched ${1##*/} not executable, using original" >&2
+ rm -f "$1.patched"
+ fi
+}
+