1570af302Sopenharmony_ci#include <string.h> 2570af302Sopenharmony_ci#include <signal.h> 3570af302Sopenharmony_ci#include <setjmp.h> 4570af302Sopenharmony_ci#include "test.h" 5570af302Sopenharmony_ci 6570af302Sopenharmony_ci#define TEST(c, ...) ((c) ? 1 : (t_error(#c" failed: " __VA_ARGS__),0)) 7570af302Sopenharmony_ci 8570af302Sopenharmony_ciint main(void) 9570af302Sopenharmony_ci{ 10570af302Sopenharmony_ci volatile int x = 0, r; 11570af302Sopenharmony_ci jmp_buf jb; 12570af302Sopenharmony_ci sigjmp_buf sjb; 13570af302Sopenharmony_ci volatile sigset_t oldset; 14570af302Sopenharmony_ci sigset_t set, set2; 15570af302Sopenharmony_ci 16570af302Sopenharmony_ci if (!setjmp(jb)) { 17570af302Sopenharmony_ci x = 1; 18570af302Sopenharmony_ci longjmp(jb, 1); 19570af302Sopenharmony_ci } 20570af302Sopenharmony_ci TEST(x==1, "setjmp/longjmp seems to have been bypassed\n"); 21570af302Sopenharmony_ci 22570af302Sopenharmony_ci x = 0; 23570af302Sopenharmony_ci r = setjmp(jb); 24570af302Sopenharmony_ci if (!x) { 25570af302Sopenharmony_ci x = 1; 26570af302Sopenharmony_ci longjmp(jb, 0); 27570af302Sopenharmony_ci } 28570af302Sopenharmony_ci TEST(r==1, "longjmp(jb, 0) caused setjmp to return %d\n", r); 29570af302Sopenharmony_ci 30570af302Sopenharmony_ci sigemptyset(&set); 31570af302Sopenharmony_ci sigaddset(&set, SIGUSR1); 32570af302Sopenharmony_ci sigprocmask(SIG_UNBLOCK, &set, &set2); 33570af302Sopenharmony_ci oldset = set2; 34570af302Sopenharmony_ci 35570af302Sopenharmony_ci /* Improve the chances of catching failure of sigsetjmp to 36570af302Sopenharmony_ci * properly save the signal mask in the sigjmb_buf. */ 37570af302Sopenharmony_ci memset(&sjb, -1, sizeof sjb); 38570af302Sopenharmony_ci 39570af302Sopenharmony_ci if (!sigsetjmp(sjb, 1)) { 40570af302Sopenharmony_ci sigemptyset(&set); 41570af302Sopenharmony_ci sigaddset(&set, SIGUSR1); 42570af302Sopenharmony_ci sigprocmask(SIG_BLOCK, &set, 0); 43570af302Sopenharmony_ci siglongjmp(sjb, 1); 44570af302Sopenharmony_ci } 45570af302Sopenharmony_ci set = oldset; 46570af302Sopenharmony_ci sigprocmask(SIG_SETMASK, &set, &set2); 47570af302Sopenharmony_ci TEST(sigismember(&set2, SIGUSR1)==0, "siglongjmp failed to restore mask\n"); 48570af302Sopenharmony_ci 49570af302Sopenharmony_ci sigemptyset(&set); 50570af302Sopenharmony_ci sigaddset(&set, SIGUSR1); 51570af302Sopenharmony_ci sigprocmask(SIG_UNBLOCK, &set, &set2); 52570af302Sopenharmony_ci oldset = set2; 53570af302Sopenharmony_ci 54570af302Sopenharmony_ci if (!sigsetjmp(sjb, 0)) { 55570af302Sopenharmony_ci sigemptyset(&set); 56570af302Sopenharmony_ci sigaddset(&set, SIGUSR1); 57570af302Sopenharmony_ci sigprocmask(SIG_BLOCK, &set, 0); 58570af302Sopenharmony_ci siglongjmp(sjb, 1); 59570af302Sopenharmony_ci } 60570af302Sopenharmony_ci set = oldset; 61570af302Sopenharmony_ci sigprocmask(SIG_SETMASK, &set, &set2); 62570af302Sopenharmony_ci TEST(sigismember(&set2, SIGUSR1)==1, "siglongjmp incorrectly restored mask\n"); 63570af302Sopenharmony_ci 64570af302Sopenharmony_ci return t_status; 65570af302Sopenharmony_ci} 66