@@ -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 .
253254fn 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.
279281fn 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.
609611fn 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