1 /*
2 * Copyright (c) 2023 Huawei Device Co., Ltd.
3 * Licensed under the Apache License, Version 2.0 (the "License");
4 * you may not use this file except in compliance with the License.
5 * You may obtain a copy of the License at
6 *
7 * http://www.apache.org/licenses/LICENSE-2.0
8 *
9 * Unless required by applicable law or agreed to in writing, software
10 * distributed under the License is distributed on an "AS IS" BASIS,
11 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12 * See the License for the specific language governing permissions and
13 * limitations under the License.
14 */
15
16 #include <signal.h>
17 #include <errno.h>
18 #include <sigchain.h>
19 #include <stddef.h>
20 #include <hilog_adapter.h>
21 #include <string.h>
22 #include "syscall.h"
23 #ifdef OHOS_ENABLE_PARAMETER
24 #include "sys_param.h"
25 #endif
26
27 extern void intercept_pthread_sigmask(int how, sigset_t *restrict set);
28 static const char *param_name = "musl.sigchain.procmask";
29
30 /**
31 * @brief Get whether sigchain mask is enabled
32 * @retval True if the sigchain mask is enable, or false.
33 */
get_sigchain_mask_enable()34 bool get_sigchain_mask_enable()
35 {
36 #ifdef OHOS_ENABLE_PARAMETER
37 static CachedHandle sigchain_procmask_handle = NULL;
38 if (sigchain_procmask_handle == NULL) {
39 sigchain_procmask_handle = CachedParameterCreate(param_name, "false");
40 }
41 char *param_value = CachedParameterGet(sigchain_procmask_handle);
42 if (param_value != NULL) {
43 if (strcmp(param_value, "true") == 0) {
44 return true;
45 }
46 }
47 #endif
48 return false;
49 }
50
pthread_sigmask(int how,const sigset_t * restrict set,sigset_t * restrict old)51 int pthread_sigmask(int how, const sigset_t *restrict set, sigset_t *restrict old)
52 {
53 int ret;
54 if (set && (unsigned)how - SIG_BLOCK > 2U) return EINVAL;
55 /* sigchain intercepts pthread_sigmask */
56 if (set && get_sigchain_mask_enable()) {
57 sigset_t tmpset = *set;
58 intercept_pthread_sigmask(how, &tmpset);
59 const sigset_t *new_set_ptr = &tmpset;
60 ret = -__syscall(SYS_rt_sigprocmask, how, new_set_ptr, old, _NSIG/8);
61 } else {
62 ret = -__syscall(SYS_rt_sigprocmask, how, set, old, _NSIG/8);
63 }
64
65 if (!ret && old) {
66 if (sizeof old->__bits[0] == 8) {
67 old->__bits[0] &= ~0x380000000ULL;
68 } else {
69 old->__bits[0] &= ~0x80000000UL;
70 old->__bits[1] &= ~0x3UL;
71 }
72 }
73 return ret;
74 }
75