Skip to content

Commit fd4ac1a

Browse files
anordalcookpate
authored andcommitted
catch_assert: Use siglongjmp instead of restoring signals manually
A more proper fix for #1339 than the previous commit: siglongjmp also restores signal state. Also take the opportunity to minimize macro state, code and namespace footprint.
1 parent 1ee487d commit fd4ac1a

1 file changed

Lines changed: 34 additions & 34 deletions

File tree

test/unit-test/catch_assert.h

Lines changed: 34 additions & 34 deletions
Original file line numberDiff line numberDiff line change
@@ -37,47 +37,47 @@
3737
#include <signal.h>
3838
#include <unistd.h>
3939

40-
#ifndef CATCH_JMPBUF
41-
#define CATCH_JMPBUF waypoint_
42-
#endif
43-
44-
static jmp_buf CATCH_JMPBUF;
40+
/* Global state apology: Sigaction offers no context. */
41+
static sigjmp_buf catch_waypoint;
4542

4643
#pragma GCC diagnostic push
4744
#pragma GCC diagnostic ignored "-Wunused-function"
48-
static void catchHandler_( int signal )
45+
static void catch_rollBack( int signal )
46+
{
47+
siglongjmp( catch_waypoint, signal );
48+
}
49+
static void catch_setSigabrtHandler( void )
50+
{
51+
struct sigaction sa = { 0 };
52+
53+
sa.sa_handler = catch_rollBack;
54+
sigaction( SIGABRT, &sa, NULL );
55+
}
56+
static int catch_saveStderr()
57+
{
58+
int savedStderr = dup( 2 );
59+
60+
close( 2 );
61+
return savedStderr;
62+
}
63+
static void catch_restoreStderr( int savedStderr )
4964
{
50-
longjmp( CATCH_JMPBUF, signal );
65+
dup2( savedStderr, 2 );
66+
close( savedStderr );
5167
}
5268
#pragma GCC diagnostic pop
5369

54-
#define catch_assert( x ) \
55-
do { \
56-
int ltry = 0, lcatch = 0; \
57-
int saveFd = dup( 2 ); \
58-
struct sigaction sa = { 0 }, saveSa; \
59-
sa.sa_handler = catchHandler_; \
60-
sigaction( SIGABRT, &sa, &saveSa ); \
61-
close( 2 ); \
62-
if( setjmp( CATCH_JMPBUF ) == 0 ) \
63-
{ \
64-
ltry++; \
65-
x; \
66-
} \
67-
else \
68-
{ \
69-
lcatch++; \
70-
sigset_t sigrid; \
71-
sigemptyset( &sigrid ); \
72-
sigaddset( &sigrid, SIGABRT ); \
73-
pthread_sigmask( \
74-
SIG_UNBLOCK, &sigrid, NULL \
75-
); \
76-
} \
77-
sigaction( SIGABRT, &saveSa, NULL ); \
78-
dup2( saveFd, 2 ); \
79-
close( saveFd ); \
80-
TEST_ASSERT_EQUAL( ltry, lcatch ); \
70+
#define catch_assert( x ) \
71+
do { \
72+
int catch_stderr = catch_saveStderr(); \
73+
int catch_signal = sigsetjmp( catch_waypoint, 1 ); \
74+
if( catch_signal == 0 ) \
75+
{ \
76+
catch_setSigabrtHandler(); \
77+
x; \
78+
} \
79+
catch_restoreStderr( catch_stderr ); \
80+
TEST_ASSERT_EQUAL( SIGABRT, catch_signal ); \
8181
} while( 0 )
8282

8383
#endif /* ifndef CATCH_ASSERT_H_ */

0 commit comments

Comments
 (0)