1 /*
2  * Copyright (C) 2021 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 "nstackx_util.h"
17 #include "nstackx_error.h"
18 #include "nstackx_log.h"
19 #include "securec.h"
20 
21 #define TAG "nStackXUtil"
22 
23 static const char *g_illegalPathString[] = {
24     "/../",
25 };
26 
27 static const char *g_illegalPathHeadString[] = {
28     "../",
29 };
30 
IsFileNameLegal(const char * fileName)31 uint8_t IsFileNameLegal(const char *fileName)
32 {
33     if (fileName == NULL || strlen(fileName) == 0) {
34         LOGE(TAG, "illegal filename");
35         return NSTACKX_FALSE;
36     }
37 
38     for (uint32_t idx = 0; idx < sizeof(g_illegalPathHeadString) / sizeof(g_illegalPathHeadString[0]); idx++) {
39         if (g_illegalPathHeadString[idx] == NULL || strlen(fileName) < strlen(g_illegalPathHeadString[idx])) {
40             continue;
41         }
42         if (memcmp(fileName, g_illegalPathHeadString[idx], strlen(g_illegalPathHeadString[idx])) == 0) {
43             LOGE(TAG, "illegal filename");
44             return NSTACKX_FALSE;
45         }
46     }
47 
48     for (uint32_t idx = 0; idx < sizeof(g_illegalPathString) / sizeof(g_illegalPathString[0]); idx++) {
49         if (g_illegalPathString[idx] == NULL || strlen(fileName) < strlen(g_illegalPathString[idx])) {
50             continue;
51         }
52         if (strstr(fileName, g_illegalPathString[idx]) != NULL) {
53             LOGE(TAG, "illegal filename");
54             return NSTACKX_FALSE;
55         }
56     }
57     return NSTACKX_TRUE;
58 }
59 
GetCpuNum(void)60 int32_t GetCpuNum(void)
61 {
62     return (int)sysconf(_SC_NPROCESSORS_CONF);
63 }
64 
StartThreadBindCore(int32_t cpu)65 void StartThreadBindCore(int32_t cpu)
66 {
67     int32_t cpus;
68     cpu_set_t mask;
69     int32_t syscallres;
70     pid_t tid = gettid();
71     if (cpu < 0) {
72         return;
73     }
74     cpus = GetCpuNum();
75     if (cpus < cpu + 1) {
76         return;
77     }
78     CPU_ZERO(&mask);
79     CPU_SET(cpu, &mask);
80     syscallres = (int32_t)syscall(__NR_sched_setaffinity, tid, sizeof(mask), &mask);
81     if (syscallres < 0) {
82         LOGE(TAG, "set thread affinity failed, ret %d, error(%d)", syscallres, errno);
83         return;
84     }
85 }
86 
BindThreadToTargetMask(pid_t tid,uint32_t cpuMask)87 void BindThreadToTargetMask(pid_t tid, uint32_t cpuMask)
88 {
89     if (tid == 0) {
90         LOGE(TAG, "invalid tid");
91         return;
92     }
93 
94     int32_t cpus = GetCpuNum();
95     if (cpus < 0) {
96         return;
97     }
98 
99     if (cpuMask == 0 || cpuMask >= (1U << (uint32_t)cpus)) {
100         LOGE(TAG, "invalid cpu mask");
101         return;
102     }
103     cpu_set_t mask;
104     int32_t syscallres;
105     uint32_t cpu = CPU_IDX_0;
106     CPU_ZERO(&mask);
107     LOGI(TAG, "bind thread %d to target core :%x", tid, cpuMask);
108     while (cpuMask > 0) {
109         if ((cpuMask & 1) == 1) {
110             CPU_SET(cpu, &mask);
111         }
112         cpu++;
113         cpuMask = cpuMask >> 1;
114     }
115     syscallres = (int32_t)syscall(__NR_sched_setaffinity, tid, sizeof(mask), &mask);
116     if (syscallres < 0) {
117         LOGE(TAG, "set thread affinity failed, ret %d, error(%d)", syscallres, errno);
118         return;
119     }
120 }
121 
SetThreadName(const char * name)122 void SetThreadName(const char *name)
123 {
124     if (name == NULL || strlen(name) == 0 || strlen(name) >= MAX_THREAD_NAME_LEN) {
125         LOGE(TAG, "invalid input");
126     }
127     if (prctl(PR_SET_NAME, name) < 0) {
128         LOGE(TAG, "prctl errno %d", errno);
129     }
130 }
131 
SetMaximumPriorityForThread(void)132 void SetMaximumPriorityForThread(void)
133 {
134     if (nice(THREAD_MAXIMUM_PRIORITY) == -1) {
135         LOGE(TAG, "nice set error: %d", errno);
136     }
137 }
138 
ClockGetTime(clockid_t id,struct timespec * tp)139 void ClockGetTime(clockid_t id, struct timespec *tp)
140 {
141     if (clock_gettime(id, tp) != 0) {
142         LOGE(TAG, "clock_gettime error: %d", errno);
143     }
144 }
145 
SemInit(sem_t * sem,int pshared,unsigned int value)146 int32_t SemInit(sem_t *sem, int pshared, unsigned int value)
147 {
148     return sem_init(sem, pshared, value);
149 }
150 
SemGetValue(sem_t * sem,int * sval)151 void SemGetValue(sem_t *sem, int *sval)
152 {
153     if (sem_getvalue(sem, sval) != 0) {
154         LOGE(TAG, "sem get error: %d", errno);
155     }
156 }
157 
SemPost(sem_t * sem)158 void SemPost(sem_t *sem)
159 {
160     if (sem_post(sem) != 0) {
161         LOGE(TAG, "sem post error: %d", errno);
162     }
163 }
164 
SemWait(sem_t * sem)165 void SemWait(sem_t *sem)
166 {
167     if (sem_wait(sem) != 0) {
168         LOGE(TAG, "sem wait error: %d", errno);
169     }
170 }
171 
SemDestroy(sem_t * sem)172 void SemDestroy(sem_t *sem)
173 {
174     if (sem_destroy(sem) != 0) {
175         LOGE(TAG, "sem destroy error: %d", errno);
176     }
177 }
178 
PthreadCreate(pthread_t * tid,const pthread_attr_t * attr,void * (* entry)(void *),void * arg)179 int32_t PthreadCreate(pthread_t *tid, const pthread_attr_t *attr, void *(*entry)(void *), void *arg)
180 {
181     return pthread_create(tid, attr, entry, arg);
182 }
183 
PthreadJoin(pthread_t thread,void ** retval)184 void PthreadJoin(pthread_t thread, void **retval)
185 {
186     if (pthread_join(thread, retval) != 0) {
187         LOGE(TAG, "pthread_join failed error: %d", errno);
188     }
189 }
190 
PthreadMutexInit(pthread_mutex_t * mutex,const pthread_mutexattr_t * attr)191 int32_t PthreadMutexInit(pthread_mutex_t *mutex, const pthread_mutexattr_t *attr)
192 {
193     return pthread_mutex_init(mutex, attr);
194 }
195 
PthreadMutexDestroy(pthread_mutex_t * mutex)196 void PthreadMutexDestroy(pthread_mutex_t *mutex)
197 {
198     if (pthread_mutex_destroy(mutex) != 0) {
199         LOGE(TAG, "pthread mutex destroy error: %d", errno);
200     }
201 }
202 
PthreadMutexLock(pthread_mutex_t * mutex)203 int32_t PthreadMutexLock(pthread_mutex_t *mutex)
204 {
205     return pthread_mutex_lock(mutex);
206 }
207 
PthreadMutexUnlock(pthread_mutex_t * mutex)208 int32_t PthreadMutexUnlock(pthread_mutex_t *mutex)
209 {
210     return pthread_mutex_unlock(mutex);
211 }
212 
CloseDesc(int32_t desc)213 void CloseDesc(int32_t desc)
214 {
215     if (close(desc) != 0) {
216         LOGE(TAG, "close desc error : %d", errno);
217     }
218 }
219