fix: preserve executable bits when extracting Java runtimes (#873)
Co-authored-by: LynithDev <61880709+LynithDev@users.noreply.github.com>
This commit is contained in:
parent
d632c47320
commit
7ca7ac04cf
3 changed files with 60 additions and 10 deletions
|
|
@ -81,15 +81,6 @@ pub async fn install_package(
|
|||
.map_err(|err| polyio::IOError::from(std::io::Error::other(err)))?
|
||||
};
|
||||
|
||||
#[cfg(unix)]
|
||||
{
|
||||
let _ = tokio::process::Command::new("chmod")
|
||||
.arg("755")
|
||||
.arg(&executable)
|
||||
.output()
|
||||
.await;
|
||||
}
|
||||
|
||||
let _ = polyio::remove_file(&archive_path).await;
|
||||
|
||||
tracing::info!(vendor = %package.vendor, major, "installed Java runtime");
|
||||
|
|
@ -136,6 +127,52 @@ pub fn is_launcher_managed(executable: &Path) -> bool {
|
|||
managed_install_root(executable).is_ok_and(|root| root.is_some())
|
||||
}
|
||||
|
||||
#[cfg(unix)]
|
||||
pub(crate) fn restore_executable_bits(executable: &Path) {
|
||||
use std::os::unix::fs::PermissionsExt;
|
||||
|
||||
let Ok(executable) = polyio::canonicalize(executable) else {
|
||||
return;
|
||||
};
|
||||
if !is_launcher_managed(&executable) {
|
||||
return;
|
||||
}
|
||||
let Some(home) = executable.parent().and_then(Path::parent) else {
|
||||
return;
|
||||
};
|
||||
let jre = home.join("jre");
|
||||
|
||||
let entries = |dir: PathBuf| {
|
||||
std::fs::read_dir(dir)
|
||||
.into_iter()
|
||||
.flatten()
|
||||
.flatten()
|
||||
.map(|entry| entry.path())
|
||||
};
|
||||
let tools = entries(home.join("bin")).chain(entries(jre.join("bin")));
|
||||
let helpers = ["jspawnhelper", "jexec"].map(|name| home.join("lib").join(name));
|
||||
let jre_helpers = std::iter::once(jre.join("lib"))
|
||||
.chain(entries(jre.join("lib")))
|
||||
.map(|dir| dir.join("jspawnhelper"));
|
||||
|
||||
for path in tools.chain(helpers).chain(jre_helpers) {
|
||||
let Ok(metadata) = std::fs::metadata(&path) else {
|
||||
continue;
|
||||
};
|
||||
let mode = metadata.permissions().mode();
|
||||
if !metadata.is_file() || mode & 0o111 != 0 {
|
||||
continue;
|
||||
}
|
||||
|
||||
match std::fs::set_permissions(&path, std::fs::Permissions::from_mode(mode | 0o111)) {
|
||||
Ok(()) => tracing::info!(path = %path.display(), "restored missing executable bit"),
|
||||
Err(err) => {
|
||||
tracing::warn!(path = %path.display(), "could not restore executable bit: {err}");
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/// Only ever touches OneClient's own java dir a runtime the user added from
|
||||
/// their own folder is left on disk untouched
|
||||
#[tracing::instrument(level = "debug")]
|
||||
|
|
|
|||
|
|
@ -94,6 +94,9 @@ impl JavaService {
|
|||
|
||||
#[tracing::instrument(level = "debug", skip(self))]
|
||||
async fn revalidate(&self, runtime: JavaRuntime) -> JavaResult<Option<JavaRuntime>> {
|
||||
#[cfg(unix)]
|
||||
crate::install::restore_executable_bits(Path::new(&runtime.absolute_path));
|
||||
|
||||
if runtime.probe_version == PROBE_VERSION {
|
||||
if Path::new(&runtime.absolute_path).is_file() {
|
||||
return Ok(Some(runtime));
|
||||
|
|
|
|||
|
|
@ -216,6 +216,14 @@ pub async fn extract_zip_filtered(
|
|||
let entry_reader = reader.reader_without_entry(index).await?;
|
||||
|
||||
futures_lite::io::copy(entry_reader, &mut writer.compat_write()).await?;
|
||||
|
||||
#[cfg(unix)]
|
||||
if let Some(mode) = entry.unix_permissions().filter(|mode| mode & 0o777 != 0) {
|
||||
use std::os::unix::fs::PermissionsExt;
|
||||
|
||||
let mode = u32::from(mode & 0o777) | 0o600;
|
||||
tokio::fs::set_permissions(&path, std::fs::Permissions::from_mode(mode)).await?;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -353,7 +361,9 @@ pub async fn extract_tar_gz(
|
|||
let buf_reader = tokio::io::BufReader::new(file);
|
||||
let gzip_decoder = async_compression::tokio::bufread::GzipDecoder::new(buf_reader);
|
||||
|
||||
let mut tar_archive = tokio_tar::Archive::new(gzip_decoder);
|
||||
let mut tar_archive = tokio_tar::ArchiveBuilder::new(gzip_decoder)
|
||||
.set_preserve_permissions(true)
|
||||
.build();
|
||||
tar_archive.unpack(dest).await?;
|
||||
|
||||
Ok(())
|
||||
|
|
|
|||
Loading…
Add table
Reference in a new issue