• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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