diff --git a/ChangeLog.d/stdout-macro.txt b/ChangeLog.d/stdout-macro.txt new file mode 100644 index 000000000..1c0f9852e --- /dev/null +++ b/ChangeLog.d/stdout-macro.txt @@ -0,0 +1,4 @@ +Bugfix + * Fix bug in redirection of unit test outputs on platforms where stdout is + defined as a macro. First reported in #2311 and fix contributed in #3528. + Adopted for LTS branch 2.7 in #3600. diff --git a/tests/suites/helpers.function b/tests/suites/helpers.function index e38df8281..d122dd69b 100644 --- a/tests/suites/helpers.function +++ b/tests/suites/helpers.function @@ -172,45 +172,52 @@ void test_fail( const char *test, int line_no, const char* filename ) } #if defined(__unix__) || (defined(__APPLE__) && defined(__MACH__)) -static int redirect_output( FILE** out_stream, const char* path ) +static int redirect_output( FILE* out_stream, const char* path ) { - int stdout_fd = dup( fileno( *out_stream ) ); + int out_fd, dup_fd; + FILE* path_stream; - if( stdout_fd == -1 ) + out_fd = fileno( out_stream ); + dup_fd = dup( out_fd ); + + if( dup_fd == -1 ) { - return -1; + return( -1 ); } - fflush( *out_stream ); - fclose( *out_stream ); - *out_stream = fopen( path, "w" ); - - if( *out_stream == NULL ) + path_stream = fopen( path, "w" ); + if( path_stream == NULL ) { - close( stdout_fd ); - return -1; + close( dup_fd ); + return( -1 ); } - return stdout_fd; + fflush( out_stream ); + if( dup2( fileno( path_stream ), out_fd ) == -1 ) + { + close( dup_fd ); + fclose( path_stream ); + return( -1 ); + } + + fclose( path_stream ); + return( dup_fd ); } -static int restore_output( FILE** out_stream, int old_fd ) +static int restore_output( FILE* out_stream, int dup_fd ) { - fflush( *out_stream ); - fclose( *out_stream ); + int out_fd = fileno( out_stream ); - *out_stream = fdopen( old_fd, "w" ); - if( *out_stream == NULL ) + fflush( out_stream ); + if( dup2( dup_fd, out_fd ) == -1 ) { - return -1; + close( out_fd ); + close( dup_fd ); + return( -1 ); } - return 0; -} - -static void close_output( FILE* out_stream ) -{ - fclose( out_stream ); + close( dup_fd ); + return( 0 ); } #endif /* __unix__ || __APPLE__ __MACH__ */ diff --git a/tests/suites/main_test.function b/tests/suites/main_test.function index 9b2fa2b97..8a4137bb0 100644 --- a/tests/suites/main_test.function +++ b/tests/suites/main_test.function @@ -434,7 +434,7 @@ int main(int argc, const char *argv[]) */ if( !option_verbose ) { - stdout_fd = redirect_output( &stdout, "/dev/null" ); + stdout_fd = redirect_output( stdout, "/dev/null" ); if( stdout_fd == -1 ) { /* Redirection has failed with no stdout so exit */ @@ -446,7 +446,7 @@ int main(int argc, const char *argv[]) ret = dispatch_test( cnt, params ); #if defined(__unix__) || (defined(__APPLE__) && defined(__MACH__)) - if( !option_verbose && restore_output( &stdout, stdout_fd ) ) + if( !option_verbose && restore_output( stdout, stdout_fd ) ) { /* Redirection has failed with no stdout so exit */ exit( 1 ); @@ -541,10 +541,5 @@ int main(int argc, const char *argv[]) mbedtls_memory_buffer_alloc_free(); #endif -#if defined(__unix__) || (defined(__APPLE__) && defined(__MACH__)) - if( stdout_fd != -1 ) - close_output( stdout ); -#endif /* __unix__ || __APPLE__ __MACH__ */ - return( total_errors != 0 ); }