@@ -77,25 +77,27 @@ pub fn exec(
77
77
input : Option < & [ u8 ] > ,
78
78
retrieve_output : Output ,
79
79
) -> Result < CmdOutput , CmdError > {
80
- if input. is_some ( ) {
81
- cmd. stdin ( Stdio :: piped ( ) ) ;
82
- }
83
-
84
80
cmd. stdout ( Stdio :: piped ( ) ) . stderr ( Stdio :: piped ( ) ) ;
85
81
86
- let mut child = cmd. spawn ( ) . map_err ( CmdError :: BinaryNotFound ) ?;
82
+ // Create a temp dir for the input and/or output of the tool
83
+ let temp_dir = tempfile:: tempdir ( ) . map_err ( CmdError :: Io ) ?;
84
+
85
+ // Output
86
+ let output_path = temp_dir. path ( ) . join ( "output" ) ;
87
+ if retrieve_output == Output :: Retrieve {
88
+ cmd. arg ( "-o" ) . arg ( & output_path) ;
89
+ }
87
90
91
+ // Input
88
92
if let Some ( input) = input {
89
- use std:: io:: Write ;
90
-
91
- child
92
- . stdin
93
- . take ( )
94
- . unwrap ( )
95
- . write_all ( input)
96
- . map_err ( CmdError :: Io ) ?;
93
+ let input_path = temp_dir. path ( ) . join ( "input" ) ;
94
+ std:: fs:: write ( & input_path, input) . map_err ( CmdError :: Io ) ?;
95
+
96
+ cmd. arg ( & input_path) ;
97
97
}
98
98
99
+ let child = cmd. spawn ( ) . map_err ( CmdError :: BinaryNotFound ) ?;
100
+
99
101
let output = child. wait_with_output ( ) . map_err ( CmdError :: Io ) ?;
100
102
101
103
let code = match output. status . code ( ) {
@@ -163,35 +165,24 @@ pub fn exec(
163
165
Split { haystack, needle }
164
166
}
165
167
166
- let retrieve_output = retrieve_output == Output :: Retrieve ;
168
+ let binary = match retrieve_output {
169
+ Output :: Retrieve => std:: fs:: read ( & output_path) . map_err ( CmdError :: Io ) ?,
170
+ Output :: Ignore => Vec :: new ( ) ,
171
+ } ;
167
172
168
173
// Since we are retrieving the results via stdout, but it can also contain
169
174
// diagnostic messages, we need to be careful
170
175
let mut messages = Vec :: new ( ) ;
171
- let mut binary = Vec :: with_capacity ( if retrieve_output { 1024 } else { 0 } ) ;
172
176
173
- let mut maybe_msg = true ;
174
177
for line in split ( & output. stdout , b'\n' ) {
175
- if maybe_msg {
176
- if let Ok ( s) = std:: str:: from_utf8 ( line) {
177
- if let Some ( msg) = crate :: error:: Message :: parse ( s) {
178
- messages. push ( msg) ;
179
- continue ;
180
- }
181
- }
182
- }
183
-
184
- if retrieve_output {
185
- // Handle case where there is a '\n' in the stream, but it's not the
186
- // end of an output message
187
- if !maybe_msg || messages. is_empty ( ) && !binary. is_empty ( ) {
188
- binary. push ( b'\n' ) ;
178
+ if let Ok ( s) = std:: str:: from_utf8 ( line) {
179
+ if let Some ( msg) = crate :: error:: Message :: parse ( s) {
180
+ messages. push ( msg) ;
181
+ continue ;
189
182
}
190
-
191
- binary. extend_from_slice ( line) ;
192
183
}
193
184
194
- maybe_msg = false ;
185
+ break ;
195
186
}
196
187
197
188
Ok ( CmdOutput { binary, messages } )
0 commit comments