From 8b0057aca5f80bf6eab15c898e7d373d4c003453 Mon Sep 17 00:00:00 2001 From: SulfurNitride Date: Wed, 11 Mar 2026 04:29:43 -0500 Subject: Fix cap_sys_admin apply: copy-patch-replace to avoid text file busy patchelf can't modify a running binary. Now copies the binary to a temp file, patches RPATH and applies setcap on the copy, then replaces the original with mv. Co-Authored-By: Claude Opus 4.6 --- src/src/organizercore.cpp | 9 ++++++--- src/src/settingsdialogproton.cpp | 9 ++++++--- 2 files changed, 12 insertions(+), 6 deletions(-) (limited to 'src') diff --git a/src/src/organizercore.cpp b/src/src/organizercore.cpp index c6bd678..0b60fdd 100644 --- a/src/src/organizercore.cpp +++ b/src/src/organizercore.cpp @@ -692,12 +692,15 @@ void OrganizerCore::prepareVFS() const QString binDir = fi.absolutePath(); const QString absRpath = binDir + "/lib:" + binDir + "/python/lib"; + // The binary may be running (text file busy), so copy → patch → replace. QProcess patchelf; patchelf.setProgram("pkexec"); patchelf.setArguments({"bash", "-c", - QString("patchelf --force-rpath --set-rpath '%1' '%2' && " - "setcap cap_sys_admin+ep '%2'") - .arg(absRpath, binary)}); + QString("cp '%1' '%1.tmp' && " + "patchelf --force-rpath --set-rpath '%2' '%1.tmp' && " + "setcap cap_sys_admin+ep '%1.tmp' && " + "mv -f '%1.tmp' '%1'") + .arg(binary, absRpath)}); patchelf.start(); patchelf.waitForFinished(60000); diff --git a/src/src/settingsdialogproton.cpp b/src/src/settingsdialogproton.cpp index 4bab341..207ba6d 100644 --- a/src/src/settingsdialogproton.cpp +++ b/src/src/settingsdialogproton.cpp @@ -78,12 +78,15 @@ ProtonSettingsTab::ProtonSettingsTab(Settings& s, SettingsDialog& d) const QString binDir = fi.absolutePath(); const QString absRpath = binDir + "/lib:" + binDir + "/python/lib"; + // The binary may be running (text file busy), so copy → patch → replace. QProcess proc; proc.setProgram("pkexec"); proc.setArguments({"bash", "-c", - QString("patchelf --force-rpath --set-rpath '%1' '%2' && " - "setcap cap_sys_admin+ep '%2'") - .arg(absRpath, binary)}); + QString("cp '%1' '%1.tmp' && " + "patchelf --force-rpath --set-rpath '%2' '%1.tmp' && " + "setcap cap_sys_admin+ep '%1.tmp' && " + "mv -f '%1.tmp' '%1'") + .arg(binary, absRpath)}); proc.start(); proc.waitForFinished(60000); // 60s timeout for user to auth -- cgit v1.3.1