Skip to content

Commit 5d6dfa3

Browse files
committed
Use nix to check if running as root
Other way to use libc directly
1 parent 7678f84 commit 5d6dfa3

File tree

2 files changed

+26
-15
lines changed

2 files changed

+26
-15
lines changed

crates/cli/Cargo.toml

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -19,7 +19,9 @@ dialoguer = "0.11"
1919
libloading = "0.8"
2020
cargo_metadata = "0.20"
2121
semver = "1.0"
22-
elevate = "0.6.1"
22+
23+
[target.'cfg(unix)'.dependencies]
24+
nix = { version = "0.30", features=["user"]}
2325

2426
[lints.rust]
2527
missing_docs = "warn"

crates/cli/src/lib.rs

Lines changed: 23 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -198,9 +198,10 @@ impl Install {
198198
self.no_default_features,
199199
)?;
200200

201+
#[cfg(unix)]
201202
if !self.bypass_root_check {
202203
anyhow::ensure!(
203-
elevate::check() == elevate::RunningAs::User,
204+
! is_root(),
204205
"Running as root is not recommended. Use --bypass-root-check to override."
205206
);
206207
}
@@ -246,10 +247,10 @@ impl Install {
246247
}
247248
}
248249

249-
// Update extension information in the ini file, if fails, try with sudo again.
250+
// Update extension line in the ini file.
250251
//
251-
// Write to a temp file then move it to given path. Use `sudo` on unix to move
252-
// file if needed.
252+
// Write to a temp file then copy it to a given path. If this fails, then try `sudo mv`
253+
// on unix.
253254
fn update_ini_file(php_ini: &PathBuf, ext_name: &str, disable: bool) -> anyhow::Result<()> {
254255
let current_ini_content = std::fs::read_to_string(php_ini)?;
255256
let mut ext_line = format!("extension={ext_name}");
@@ -267,6 +268,7 @@ fn update_ini_file(php_ini: &PathBuf, ext_name: &str, disable: bool) -> anyhow::
267268
}
268269

269270
new_lines.push(&ext_line);
271+
270272
write_to_file(new_lines.join("\n"), php_ini)?;
271273
Ok(())
272274
}
@@ -275,17 +277,20 @@ fn update_ini_file(php_ini: &PathBuf, ext_name: &str, disable: bool) -> anyhow::
275277
//
276278
// Checking if we have write permission for ext_dir may fail due to ACL, group
277279
// list and and other nuances. See
278-
// https://doc.rust-lang.org/std/fs/struct.Permissions.html#method.readonly
280+
// https://doc.rust-lang.org/std/fs/struct.Permissions.html#method.readonly.
279281
fn copy_extension(ext_path: &Utf8PathBuf, ext_dir: &PathBuf) -> anyhow::Result<()> {
280282
if let Err(_e) = std::fs::copy(ext_path, ext_dir) {
281283
#[cfg(unix)]
282284
{
283-
let _ = std::process::Command::new("sudo")
285+
let s = std::process::Command::new("sudo")
284286
.arg("cp")
285287
.arg(ext_path)
286288
.arg(ext_dir)
287289
.status()?;
290+
anyhow::ensure!(s.success(), "Failed to copy extension");
288291
}
292+
#[cfg(not(unix))]
293+
anyhow::bail!("Failed to copy extension: {_e}");
289294
}
290295
Ok(())
291296
}
@@ -599,28 +604,26 @@ fn build_ext(
599604
bail!("Failed to retrieve extension path from artifact")
600605
}
601606

602-
// Write given string to a given filepath.
607+
// Write content to a given filepath.
603608
//
604-
// - Write to a temp file first.
605-
// - Copy the temp file to the given filepath.
606-
// - If it fails, move tempfile using `sudo mv`.
607-
//
608-
// TODO: Try with sudo when error is permission related.
609+
// We may not have write permission but we may have sudo privilege on unix. So we write to
610+
// a temp file and then try moving it to given filepath, and retry with sudo on unix.
609611
fn write_to_file(content: String, filepath: &PathBuf) -> anyhow::Result<()> {
610612
// write to a temp file
611613
let tempf = std::env::temp_dir().join("__tmp_cargo_php");
612614
std::fs::write(&tempf, content)?;
613615

614-
// Now move. `rename` will overwrite existing file.
616+
// Now try moving, `rename` will overwrite existing file.
615617
if std::fs::rename(&tempf, filepath).is_err() {
616618
#[cfg(unix)]
617619
{
618620
// if not successful, try with sudo on unix.
619-
let _ = std::process::Command::new("sudo")
621+
let s = std::process::Command::new("sudo")
620622
.arg("mv")
621623
.arg(&tempf)
622624
.arg(filepath)
623625
.status()?;
626+
anyhow::ensure!(s.success(), "Falied to write to {filepath:?}");
624627
}
625628

626629
#[cfg(not(unix))]
@@ -629,3 +632,9 @@ fn write_to_file(content: String, filepath: &PathBuf) -> anyhow::Result<()> {
629632

630633
Ok(())
631634
}
635+
636+
#[cfg(unix)]
637+
fn is_root() -> bool
638+
{
639+
nix::unistd::Uid::effective().is_root()
640+
}

0 commit comments

Comments
 (0)