|
37 | 37 | #include <signal.h> |
38 | 38 | #include <unistd.h> |
39 | 39 |
|
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; |
45 | 42 |
|
46 | 43 | #pragma GCC diagnostic push |
47 | 44 | #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 ) |
49 | 64 | { |
50 | | - longjmp( CATCH_JMPBUF, signal ); |
| 65 | + dup2( savedStderr, 2 ); |
| 66 | + close( savedStderr ); |
51 | 67 | } |
52 | 68 | #pragma GCC diagnostic pop |
53 | 69 |
|
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 ); \ |
81 | 81 | } while( 0 ) |
82 | 82 |
|
83 | 83 | #endif /* ifndef CATCH_ASSERT_H_ */ |
0 commit comments