1
1
use std:: collections:: HashMap ;
2
2
use std:: ffi:: OsStr ;
3
+ #[ cfg( unix) ]
4
+ use std:: os:: unix:: process:: CommandExt ;
3
5
use std:: path:: PathBuf ;
4
6
5
7
use crate :: config:: ConfigInfo ;
6
- use crate :: utils:: {
7
- get_toolchain, run_command_with_output_and_env_no_err, rustc_toolchain_version_info,
8
- rustc_version_info,
9
- } ;
8
+ use crate :: utils:: { get_toolchain, rustc_toolchain_version_info, rustc_version_info} ;
10
9
11
10
fn args ( command : & str ) -> Result < Option < Vec < String > > , String > {
12
11
// We skip the binary and the "cargo"/"rustc" option.
@@ -97,6 +96,26 @@ impl RustcTools {
97
96
}
98
97
}
99
98
99
+ fn exec ( input : & [ & dyn AsRef < OsStr > ] , env : & HashMap < String , String > ) -> Result < ( ) , String > {
100
+ #[ cfg( unix) ]
101
+ {
102
+ // We use `exec` to call the `execvp` syscall instead of creating a new process where the
103
+ // command will be executed because very few signals can actually kill a current process,
104
+ // so if segmentation fault (SIGSEGV signal) happens and we raise to the current process,
105
+ // it will simply do nothing and we won't have the nice error message for the shell.
106
+ let error = crate :: utils:: get_command_inner ( input, None , Some ( env) ) . exec ( ) ;
107
+ eprintln ! ( "execvp syscall failed: {error:?}" ) ;
108
+ std:: process:: exit ( 1 ) ;
109
+ }
110
+ #[ cfg( not( unix) ) ]
111
+ {
112
+ if crate :: utils:: run_command_with_output_and_env_no_err ( input, None , Some ( env) ) . is_err ( ) {
113
+ std:: process:: exit ( 1 ) ;
114
+ }
115
+ Ok ( ( ) )
116
+ }
117
+ }
118
+
100
119
pub fn run_cargo ( ) -> Result < ( ) , String > {
101
120
let Some ( mut tools) = RustcTools :: new ( "cargo" ) ? else { return Ok ( ( ) ) } ;
102
121
let rustflags = tools. env . get ( "RUSTFLAGS" ) . cloned ( ) . unwrap_or_default ( ) ;
@@ -105,11 +124,7 @@ pub fn run_cargo() -> Result<(), String> {
105
124
for arg in & tools. args {
106
125
command. push ( arg) ;
107
126
}
108
- if run_command_with_output_and_env_no_err ( & command, None , Some ( & tools. env ) ) . is_err ( ) {
109
- std:: process:: exit ( 1 ) ;
110
- }
111
-
112
- Ok ( ( ) )
127
+ exec ( & command, & tools. env )
113
128
}
114
129
115
130
pub fn run_rustc ( ) -> Result < ( ) , String > {
@@ -118,8 +133,5 @@ pub fn run_rustc() -> Result<(), String> {
118
133
for arg in & tools. args {
119
134
command. push ( arg) ;
120
135
}
121
- if run_command_with_output_and_env_no_err ( & command, None , Some ( & tools. env ) ) . is_err ( ) {
122
- std:: process:: exit ( 1 ) ;
123
- }
124
- Ok ( ( ) )
136
+ exec ( & command, & tools. env )
125
137
}
0 commit comments