@@ -71,32 +71,28 @@ pub fn generate_and_run_uumain<F>(
7171where
7272 F : FnOnce ( std:: vec:: IntoIter < OsString > ) -> i32 + Send + ' static ,
7373{
74- // Duplicate the stdout and stderr file descriptors
75- let stdout_fd = match dup ( std:: io:: stdout ( ) ) {
76- Ok ( fd) => fd. into_raw_fd ( ) ,
77- Err ( _) => {
78- return CommandResult {
79- stdout : "" . to_string ( ) ,
80- stderr : "Failed to duplicate STDOUT_FILENO" . to_string ( ) ,
81- exit_code : -1 ,
82- } ;
83- }
84- } ;
85-
86- let stderr_fd = match dup ( std:: io:: stderr ( ) ) {
87- Ok ( fd) => fd. into_raw_fd ( ) ,
88- Err ( _) => {
89- unsafe { close ( stdout_fd) } ;
90- return CommandResult {
91- stdout : "" . to_string ( ) ,
92- stderr : "Failed to duplicate STDERR_FILENO" . to_string ( ) ,
93- exit_code : -1 ,
94- } ;
95- }
96- } ;
97-
98- let original_stdout_fd = stdout_fd;
99- let original_stderr_fd = stderr_fd;
74+ // Duplicate the stdout and stderr file descriptors to restore later
75+ let original_stdout_fd_owned = match dup ( std:: io:: stdout ( ) ) {
76+ Ok ( fd) => fd,
77+ Err ( _) => {
78+ return CommandResult {
79+ stdout : "" . to_string ( ) ,
80+ stderr : "Failed to duplicate STDOUT_FILENO" . to_string ( ) ,
81+ exit_code : -1 ,
82+ } ;
83+ }
84+ } ;
85+
86+ let original_stderr_fd_owned = match dup ( std:: io:: stderr ( ) ) {
87+ Ok ( fd) => fd,
88+ Err ( _) => {
89+ return CommandResult {
90+ stdout : "" . to_string ( ) ,
91+ stderr : "Failed to duplicate STDERR_FILENO" . to_string ( ) ,
92+ exit_code : -1 ,
93+ } ;
94+ }
95+ } ;
10096
10197 println ! ( "Running test {:?}" , & args[ 0 ..] ) ;
10298 let ( read_pipe_stdout, write_pipe_stdout) = match pipe ( ) {
@@ -148,23 +144,16 @@ where
148144 }
149145 } ;
150146
151- let original_stdin_fd = stdin_fd;
152-
153- if unsafe { dup2 ( input_file. as_raw_fd ( ) , STDIN_FILENO ) } == -1 {
154- unsafe {
155- close ( original_stdout_fd) ;
156- close ( original_stderr_fd) ;
157- close ( original_stdin_fd) ;
158- }
147+ // Redirect stdin to read from the in-memory file
148+ if dup2_stdin ( & input_file) . is_err ( ) {
159149 return CommandResult {
160150 stdout : "" . to_string ( ) ,
161151 stderr : "Failed to set up stdin redirection" . to_string ( ) ,
162152 exit_code : -1 ,
163153 } ;
164154 }
165-
166- Some ( original_stdin_fd)
167-
155+
156+ Some ( stdin_fd)
168157 } else {
169158 None
170159 } ;
@@ -190,14 +179,14 @@ where
190179 } ) ;
191180
192181 // Restore the original stdin if it was modified
193- if let Some ( fd) = original_stdin_fd_owned
194- && dup2_stdin ( & fd) . is_err ( )
195- {
196- return CommandResult {
197- stdout : "" . to_string ( ) ,
198- stderr : "Failed to restore the original STDIN" . to_string ( ) ,
199- exit_code : - 1 ,
200- } ;
182+ if let Some ( fd) = original_stdin_fd_owned {
183+ if dup2_stdin ( & fd) . is_err ( ) {
184+ return CommandResult {
185+ stdout : "" . to_string ( ) ,
186+ stderr : "Failed to restore the original STDIN " . to_string ( ) ,
187+ exit_code : - 1 ,
188+ } ;
189+ }
201190 }
202191
203192 CommandResult {
@@ -216,7 +205,7 @@ fn read_from_fd(fd: RawFd) -> String {
216205 let mut captured_output = Vec :: new ( ) ;
217206 let mut read_buffer = [ 0 ; 1024 ] ;
218207
219- // Create an OwnedFd for safe reading with RAII cleanup
208+ // Temporarily create an OwnedFd for reading (we won't drop it)
220209 let owned_fd = unsafe { OwnedFd :: from_raw_fd ( fd) } ;
221210
222211 loop {
@@ -234,7 +223,9 @@ fn read_from_fd(fd: RawFd) -> String {
234223 }
235224 }
236225
237- // owned_fd drops here and RAII automatically closes the file descriptor
226+ // Forget the owned_fd to prevent it from closing the fd (the caller owns it)
227+ std:: mem:: forget ( owned_fd) ;
228+
238229 String :: from_utf8_lossy ( & captured_output) . into_owned ( )
239230}
240231
0 commit comments