From 0680de065af54e89ca448ae437d6e65f2f4cd68e Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?J=C3=A9r=C3=A9my=20Audiger?= Date: Mon, 5 Aug 2024 15:36:05 +0200 Subject: [PATCH 1/2] fix: set executable bit on brioche binary if not already set MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit The code changes in `self_update.rs` add logic to set the executable bit on the `brioche` binary if it's not already set. This ensures that the binary can be executed properly after a self update. Signed-off-by: Jérémy Audiger --- crates/brioche/src/self_update.rs | 16 ++++++++++++++++ 1 file changed, 16 insertions(+) diff --git a/crates/brioche/src/self_update.rs b/crates/brioche/src/self_update.rs index efb7c03..a9fd6a7 100644 --- a/crates/brioche/src/self_update.rs +++ b/crates/brioche/src/self_update.rs @@ -1,6 +1,7 @@ use std::{ collections::HashMap, io::{IsTerminal, Write as _}, + os::unix::fs::PermissionsExt, }; use anyhow::Context as _; @@ -86,6 +87,21 @@ pub async fn self_update(args: SelfUpdateArgs) -> anyhow::Result { ) })?; + // Set the executable bit if it's not already set + let mut permissions = tokio::fs::metadata(&brioche_path) + .await + .with_context(|| format!("failed to get metadata for {}", brioche_path.display()))? + .permissions(); + const EXECUTABLE_BIT: u32 = 0o111; + if permissions.mode() & EXECUTABLE_BIT != EXECUTABLE_BIT { + permissions.set_mode(permissions.mode() | EXECUTABLE_BIT); + tokio::fs::set_permissions(&brioche_path, permissions) + .await + .with_context(|| { + format!("failed to set executable bit on {}", brioche_path.display()) + })?; + } + Ok(true) } From 230124fa71f9d6b4e6cd0828b9d4dd9eef6e7821 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?J=C3=A9r=C3=A9my=20Audiger?= Date: Mon, 19 Aug 2024 07:07:50 +0200 Subject: [PATCH 2/2] refactor: apply the file permissions on the temporary file MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Signed-off-by: Jérémy Audiger --- crates/brioche/src/self_update.rs | 32 ++++++++++++++++++------------- 1 file changed, 19 insertions(+), 13 deletions(-) diff --git a/crates/brioche/src/self_update.rs b/crates/brioche/src/self_update.rs index a9fd6a7..ba32c12 100644 --- a/crates/brioche/src/self_update.rs +++ b/crates/brioche/src/self_update.rs @@ -74,34 +74,40 @@ pub async fn self_update(args: SelfUpdateArgs) -> anyhow::Result { println!("Downloaded update"); + // Write the update to a temporary file tokio::fs::write(&brioche_path_temp, new_update) .await .with_context(|| format!("failed to write update to {}", brioche_path_temp.display()))?; - tokio::fs::rename(&brioche_path_temp, &brioche_path) - .await - .with_context(|| { - format!( - "failed to rename {} to {}", - brioche_path_temp.display(), - brioche_path.display() - ) - })?; // Set the executable bit if it's not already set - let mut permissions = tokio::fs::metadata(&brioche_path) + let mut permissions = tokio::fs::metadata(&brioche_path_temp) .await - .with_context(|| format!("failed to get metadata for {}", brioche_path.display()))? + .with_context(|| format!("failed to get metadata for {}", brioche_path_temp.display()))? .permissions(); const EXECUTABLE_BIT: u32 = 0o111; if permissions.mode() & EXECUTABLE_BIT != EXECUTABLE_BIT { permissions.set_mode(permissions.mode() | EXECUTABLE_BIT); - tokio::fs::set_permissions(&brioche_path, permissions) + tokio::fs::set_permissions(&brioche_path_temp, permissions) .await .with_context(|| { - format!("failed to set executable bit on {}", brioche_path.display()) + format!( + "failed to set executable bit on {}", + brioche_path_temp.display() + ) })?; } + // Rename the temporary file to the actual file + tokio::fs::rename(&brioche_path_temp, &brioche_path) + .await + .with_context(|| { + format!( + "failed to rename {} to {}", + brioche_path_temp.display(), + brioche_path.display() + ) + })?; + Ok(true) }