1 /*
2  * Copyright (C) 2023 The Android Open Source Project
3  *
4  * Licensed under the Apache License, Version 2.0 (the "License");
5  * you may not use this file except in compliance with the License.
6  * You may obtain a copy of the License at
7  *
8  *      http://www.apache.org/licenses/LICENSE-2.0
9  *
10  * Unless required by applicable law or agreed to in writing, software
11  * distributed under the License is distributed on an "AS IS" BASIS,
12  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13  * See the License for the specific language governing permissions and
14  * limitations under the License.
15  */
16 
17 #include <setjmp.h>
18 #include <signal.h>
19 
20 #include "berberis/ndk_program_tests/scoped_sigaction.h"
21 
22 namespace {
23 
FuncWithLongJump(jmp_buf buf)24 void FuncWithLongJump(jmp_buf buf) {
25   longjmp(buf, 1);
26 }
27 
TEST(SetJmp,Jmp)28 TEST(SetJmp, Jmp) {
29   jmp_buf buf;
30   int value = setjmp(buf);
31   if (value == 0) {
32     FuncWithLongJump(buf);
33     FAIL();
34   }
35   ASSERT_EQ(value, 1);
36 }
37 
38 jmp_buf g_jmp_buf;
39 bool g_wrapper_called;
40 
LongjmpHandler(int)41 void LongjmpHandler(int) {
42   longjmp(g_jmp_buf, 1);
43 }
44 
WrapperHandler(int)45 void WrapperHandler(int) {
46   g_wrapper_called = true;
47   struct sigaction sa {};
48   sigemptyset(&sa.sa_mask);
49   sa.sa_handler = LongjmpHandler;
50   ScopedSigaction scoped_sa(SIGXCPU, &sa);
51 
52   int value = setjmp(g_jmp_buf);
53   if (value == 0) {
54     raise(SIGXCPU);
55     FAIL();
56   }
57   ASSERT_EQ(value, 1);
58 }
59 
TEST(SetJmp,JmpFromSignalHandler)60 TEST(SetJmp, JmpFromSignalHandler) {
61   g_wrapper_called = false;
62   // Before we do setjmp/longjmp we create a nested execution by invoking a wrapper handler. This
63   // way we ensure that nested executions are handled correctly.
64   struct sigaction sa {};
65   sigemptyset(&sa.sa_mask);
66   sa.sa_handler = WrapperHandler;
67   ScopedSigaction scoped_sa(SIGPWR, &sa);
68   raise(SIGPWR);
69   ASSERT_TRUE(g_wrapper_called);
70 }
71 
72 }  // namespace
73