mirror of
https://github.com/tinyhumansai/openhuman.git
synced 2026-07-27 21:08:00 +00:00
fix(appimage): cd "$APPDIR" in AppRun before exec to fix sharun preload CWD resolution (#2829)
Co-authored-by: Taimoor <astikkosapparel009@gmail.com> Co-authored-by: sanil-23 <sanil@vezures.xyz>
This commit is contained in:
co-authored by
Taimoor
sanil-23
parent
38238d63d5
commit
97e4854ccb
@@ -363,6 +363,80 @@ validate_sharun_lib_path() {
|
||||
fi
|
||||
}
|
||||
|
||||
# patch_apprun_sharun_cwd — inject `cd "$APPDIR"` into AppRun before the final
|
||||
# exec call so sharun resolves preload/library paths relative to the AppDir
|
||||
# rather than the caller's CWD.
|
||||
#
|
||||
# Problem (issue #2822): sharun reads its `.preload` entry and library search
|
||||
# paths relative to the process CWD. When a user launches the AppImage from
|
||||
# any directory other than the AppDir itself (e.g. double-click from ~/Downloads)
|
||||
# CWD != AppDir, so ld.so can't find `anylinux.so` (preload) or `libcef.so`
|
||||
# (LD_LIBRARY_PATH entry). SHARUN_DIR is set correctly — the AppDir IS known —
|
||||
# but sharun doesn't use it to anchor the preload/library arguments it hands to
|
||||
# ld.so.
|
||||
#
|
||||
# Fix: prepend `cd "$APPDIR"` to the exec line in AppRun so the working
|
||||
# directory is always the AppDir by the time sharun/the binary runs. This
|
||||
# mirrors the verified manual workaround from the bug report.
|
||||
#
|
||||
# Returns 0 (true) if the AppRun was modified, 1 if no change was needed.
|
||||
patch_apprun_sharun_cwd() {
|
||||
local appdir="$1"
|
||||
if ! uses_sharun_launcher "$appdir"; then
|
||||
return 1
|
||||
fi
|
||||
|
||||
local apprun="$appdir/AppRun"
|
||||
if [ ! -f "$apprun" ]; then
|
||||
# Some sharun bundles use the sharun binary directly as the AppDir entry
|
||||
# point without a separate shell AppRun. Nothing to patch in that case.
|
||||
return 1
|
||||
fi
|
||||
|
||||
# Check if the file is a shell script (not an ELF binary).
|
||||
local first_bytes
|
||||
first_bytes="$(LC_ALL=C head -c 2 "$apprun" 2>/dev/null || true)"
|
||||
if [ "$first_bytes" = $'\x7fE' ]; then
|
||||
# AppRun is an ELF binary — cannot patch with sed.
|
||||
return 1
|
||||
fi
|
||||
|
||||
# Idempotency guard: skip if we already patched this AppRun.
|
||||
# Match only the exact patched line — a loose substring (e.g. 'cd.*"$APPDIR"')
|
||||
# would false-positive on comments like '# cd "$APPDIR"' or unrelated lines
|
||||
# and leave the real `exec "$@"` unpatched.
|
||||
local patched_line_re='^[[:space:]]*cd[[:space:]]+"\$APPDIR"[[:space:]]*&&[[:space:]]*exec[[:space:]]+"\$@"[[:space:]]*$'
|
||||
if grep -Eq "$patched_line_re" "$apprun" 2>/dev/null; then
|
||||
return 1
|
||||
fi
|
||||
|
||||
# Locate the exec line. AppRun scripts generated by lib4bin / sharun
|
||||
# typically have a line of the form (possibly with leading whitespace):
|
||||
# exec "$@"
|
||||
# Patch it to:
|
||||
# cd "$APPDIR" && exec "$@"
|
||||
#
|
||||
# The sed pattern is anchored to end-of-line ($) so trailing content (extra
|
||||
# args, comments, redirections) doesn't get silently absorbed into the cd &&
|
||||
# exec sequence.
|
||||
#
|
||||
# Use a temp file + mv to avoid truncating AppRun mid-write on failure.
|
||||
local tmp_apprun
|
||||
tmp_apprun="$(mktemp)"
|
||||
if sed 's|^\([[:space:]]*\)exec "\$@"[[:space:]]*$|\1cd "$APPDIR" \&\& exec "$@"|' \
|
||||
"$apprun" > "$tmp_apprun" \
|
||||
&& grep -Eq "$patched_line_re" "$tmp_apprun"; then
|
||||
chmod --reference="$apprun" "$tmp_apprun"
|
||||
mv "$tmp_apprun" "$apprun"
|
||||
echo "[strip-libs] patched AppRun: added 'cd \"\$APPDIR\"' before exec to fix sharun CWD preload resolution (issue #2822)"
|
||||
return 0
|
||||
else
|
||||
rm -f "$tmp_apprun"
|
||||
echo "[strip-libs] WARNING: could not locate 'exec \"\$@\"' in AppRun — sharun CWD fix not applied; AppImage may fail to launch from non-AppDir CWDs" >&2
|
||||
return 1
|
||||
fi
|
||||
}
|
||||
|
||||
strip_one_appimage() {
|
||||
local img="$1"
|
||||
local original
|
||||
@@ -386,6 +460,7 @@ strip_one_appimage() {
|
||||
local removed=0
|
||||
local added_loader=0
|
||||
local rewrote_libpath=0
|
||||
local patched_apprun=0
|
||||
local lib_roots=()
|
||||
for candidate in \
|
||||
"$appdir/usr/lib" \
|
||||
@@ -420,14 +495,17 @@ strip_one_appimage() {
|
||||
if rewrite_sharun_lib_path "$appdir"; then
|
||||
rewrote_libpath=1
|
||||
fi
|
||||
if patch_apprun_sharun_cwd "$appdir"; then
|
||||
patched_apprun=1
|
||||
fi
|
||||
validate_sharun_lib_path "$appdir"
|
||||
|
||||
if [ "$removed" -eq 0 ] && [ "$added_loader" -eq 0 ] && [ "$rewrote_libpath" -eq 0 ]; then
|
||||
if [ "$removed" -eq 0 ] && [ "$added_loader" -eq 0 ] && [ "$rewrote_libpath" -eq 0 ] && [ "$patched_apprun" -eq 0 ]; then
|
||||
echo "[strip-libs] No graphics libs or missing sharun interpreter found in $original; leaving unchanged."
|
||||
rm -rf "$workdir"
|
||||
return
|
||||
fi
|
||||
echo "[strip-libs] Removed $removed file(s), added $added_loader loader file(s); repacking AppImage."
|
||||
echo "[strip-libs] Removed $removed file(s), added $added_loader loader file(s), patched AppRun=$patched_apprun; repacking AppImage."
|
||||
|
||||
local rebuilt="$workdir/$name"
|
||||
local appimage_arch
|
||||
|
||||
Reference in New Issue
Block a user