diff --git a/ChangeLog.d/stdout-macro.txt b/ChangeLog.d/stdout-macro.txt new file mode 100644 index 000000000..e77b0adfd --- /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.16 in #3601. diff --git a/tests/suites/helpers.function b/tests/suites/helpers.function index cd9346e5c..8275733a8 100644 --- a/tests/suites/helpers.function +++ b/tests/suites/helpers.function @@ -391,45 +391,52 @@ void mbedtls_param_failed( const char *failure_condition, #endif #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/host_test.function b/tests/suites/host_test.function index 4be63085c..ca51e7b28 100644 --- a/tests/suites/host_test.function +++ b/tests/suites/host_test.function @@ -555,7 +555,7 @@ int execute_tests( 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 */ @@ -575,7 +575,7 @@ int execute_tests( int argc , const char ** argv ) } #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 ); @@ -667,10 +667,5 @@ int execute_tests( 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 ); }