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 #include "c_mock_common.h"
16
17 #include <dlfcn.h>
18 #include <fuse_lowlevel.h>
19 #include <sys/stat.h>
20 #include <sys/types.h>
21 #include <unistd.h>
22 #include "securec.h"
23
24 #ifdef __cplusplus
25 extern "C" {
26 #endif
27
28 #ifdef _ARM64_
29 static const std::string LIB_PATH = "/system/lib64/";
30 #else
31 static const std::string LIB_PATH = "/system/lib/";
32 #endif
33 static const std::string LIBFUSE_LIB_PATH = LIB_PATH + "libfuse.z.so";
34
35 typedef int (*AddArgsT)(struct fuse_args *args, const char *arg);
36 typedef void (*FreeArgsT)(struct fuse_args *args);
37 typedef struct fuse_session *(*NewSessionT)(struct fuse_args *args,
38 const struct fuse_lowlevel_ops *op, size_t op_size, void *userdata);
39 typedef int (*MountSessionT)(struct fuse_session *se, const char *mountpoint);
40 typedef void (*DestorySessionT)(struct fuse_session *se);
41 typedef int (*LoopSessionT)(struct fuse_session *se);
42 typedef int (*FuseReplyErrT)(fuse_req_t req, int err);
43 typedef int (*FuseReplyEntryT)(fuse_req_t req, const struct fuse_entry_param *e);
44 typedef int (*FuseReplyAttrT)(fuse_req_t req, const struct stat *attr, double attr_timeout);
45 typedef int (*FuseReplyOpenT)(fuse_req_t req, const struct fuse_file_info *f);
46 typedef int (*FuseReplyBufT)(fuse_req_t req, const char *buf, size_t size);
47 typedef int (*FuseReplyWriteT)(fuse_req_t req, size_t count);
48 typedef size_t (*FuseAddDirentryT)(fuse_req_t req, char *buf, size_t bufsize,
49 const char *name, const struct stat *stbuf, off_t off);
50
51 static void *g_libfuseHandle = nullptr;
GetLibfuseLibFunc(const char * funcName)52 static void *GetLibfuseLibFunc(const char *funcName)
53 {
54 if (g_libfuseHandle == nullptr) {
55 g_libfuseHandle = dlopen(LIBFUSE_LIB_PATH.c_str(), RTLD_LAZY);
56 if (g_libfuseHandle == nullptr) {
57 return nullptr;
58 }
59 }
60
61 void *func = dlsym(g_libfuseHandle, funcName);
62 return func;
63 }
64
fuse_opt_add_arg(struct fuse_args * args,const char * arg)65 int fuse_opt_add_arg(struct fuse_args *args, const char *arg)
66 {
67 if (IsFuncNeedMock(__func__)) {
68 CommonMockFuncT rawFunc = GetMockFunc(__func__);
69 if (rawFunc != nullptr) {
70 return (*reinterpret_cast<AddArgsT>(rawFunc))(args, arg);
71 }
72 return -1;
73 }
74
75 AddArgsT func = reinterpret_cast<AddArgsT>(GetLibfuseLibFunc(__func__));
76 if (func == nullptr) {
77 return -1;
78 }
79 return (*func)(args, arg);
80 }
81
fuse_opt_free_args(struct fuse_args * args)82 void fuse_opt_free_args(struct fuse_args *args)
83 {
84 if (IsFuncNeedMock(__func__)) {
85 CommonMockFuncT rawFunc = GetMockFunc(__func__);
86 if (rawFunc != nullptr) {
87 (*reinterpret_cast<FreeArgsT>(rawFunc))(args);
88 }
89 return;
90 }
91
92 FreeArgsT func = reinterpret_cast<FreeArgsT>(GetLibfuseLibFunc(__func__));
93 if (func == nullptr) {
94 return;
95 }
96 (*func)(args);
97 }
98
fuse_session_new(struct fuse_args * args,const struct fuse_lowlevel_ops * op,size_t op_size,void * userdata)99 struct fuse_session *fuse_session_new(struct fuse_args *args, const struct fuse_lowlevel_ops *op,
100 size_t op_size, void *userdata)
101 {
102 if (IsFuncNeedMock(__func__)) {
103 CommonMockFuncT rawFunc = GetMockFunc(__func__);
104 if (rawFunc != nullptr) {
105 return (*reinterpret_cast<NewSessionT>(rawFunc))(args, op, op_size, userdata);
106 }
107 return nullptr;
108 }
109 NewSessionT func = reinterpret_cast<NewSessionT>(GetLibfuseLibFunc(__func__));
110 if (func == nullptr) {
111 return nullptr;
112 }
113 return (*func)(args, op, op_size, userdata);
114 }
115
fuse_session_mount(struct fuse_session * se,const char * mountpoint)116 int fuse_session_mount(struct fuse_session *se, const char *mountpoint)
117 {
118 if (IsFuncNeedMock(__func__)) {
119 CommonMockFuncT rawFunc = GetMockFunc(__func__);
120 if (rawFunc != nullptr) {
121 return (*reinterpret_cast<MountSessionT>(rawFunc))(se, mountpoint);
122 }
123 return -1;
124 }
125
126 MountSessionT func = reinterpret_cast<MountSessionT>(GetLibfuseLibFunc(__func__));
127 if (func == nullptr) {
128 return -1;
129 }
130 return (*func)(se, mountpoint);
131 }
132
fuse_session_destroy(struct fuse_session * se)133 void fuse_session_destroy(struct fuse_session *se)
134 {
135 if (IsFuncNeedMock(__func__)) {
136 CommonMockFuncT rawFunc = GetMockFunc(__func__);
137 if (rawFunc != nullptr) {
138 (*reinterpret_cast<DestorySessionT>(rawFunc))(se);
139 }
140 return;
141 }
142
143 DestorySessionT func = reinterpret_cast<DestorySessionT>(GetLibfuseLibFunc(__func__));
144 if (func == nullptr) {
145 return;
146 }
147 (*func)(se);
148 }
149
fuse_session_loop(struct fuse_session * se)150 int fuse_session_loop(struct fuse_session *se)
151 {
152 if (IsFuncNeedMock(__func__)) {
153 CommonMockFuncT rawFunc = GetMockFunc(__func__);
154 if (rawFunc != nullptr) {
155 return (*reinterpret_cast<LoopSessionT>(rawFunc))(se);
156 }
157 return -1;
158 }
159
160 LoopSessionT func = reinterpret_cast<LoopSessionT>(GetLibfuseLibFunc(__func__));
161 if (func == nullptr) {
162 return -1;
163 }
164 return (*func)(se);
165 }
166
fuse_reply_err(fuse_req_t req,int err)167 int fuse_reply_err(fuse_req_t req, int err)
168 {
169 if (IsFuncNeedMock(__func__)) {
170 CommonMockFuncT rawFunc = GetMockFunc(__func__);
171 if (rawFunc != nullptr) {
172 return (*reinterpret_cast<FuseReplyErrT>(rawFunc))(req, err);
173 }
174 return -1;
175 }
176
177 FuseReplyErrT func = reinterpret_cast<FuseReplyErrT>(GetLibfuseLibFunc(__func__));
178 if (func == nullptr) {
179 return -1;
180 }
181 return (*func)(req, err);
182 }
183
fuse_reply_entry(fuse_req_t req,const struct fuse_entry_param * e)184 int fuse_reply_entry(fuse_req_t req, const struct fuse_entry_param *e)
185 {
186 if (IsFuncNeedMock(__func__)) {
187 CommonMockFuncT rawFunc = GetMockFunc(__func__);
188 if (rawFunc != nullptr) {
189 return (*reinterpret_cast<FuseReplyEntryT>(rawFunc))(req, e);
190 }
191 return -1;
192 }
193
194 FuseReplyEntryT func = reinterpret_cast<FuseReplyEntryT>(GetLibfuseLibFunc(__func__));
195 if (func == nullptr) {
196 return -1;
197 }
198 return (*func)(req, e);
199 }
200
fuse_reply_attr(fuse_req_t req,const struct stat * attr,double attr_timeout)201 int fuse_reply_attr(fuse_req_t req, const struct stat *attr, double attr_timeout)
202 {
203 if (IsFuncNeedMock(__func__)) {
204 CommonMockFuncT rawFunc = GetMockFunc(__func__);
205 if (rawFunc != nullptr) {
206 return (*reinterpret_cast<FuseReplyAttrT>(rawFunc))(req, attr, attr_timeout);
207 }
208 return -1;
209 }
210
211 FuseReplyAttrT func = reinterpret_cast<FuseReplyAttrT>(GetLibfuseLibFunc(__func__));
212 if (func == nullptr) {
213 return -1;
214 }
215 return (*func)(req, attr, attr_timeout);
216 }
217
fuse_reply_open(fuse_req_t req,const struct fuse_file_info * f)218 int fuse_reply_open(fuse_req_t req, const struct fuse_file_info *f)
219 {
220 if (IsFuncNeedMock(__func__)) {
221 CommonMockFuncT rawFunc = GetMockFunc(__func__);
222 if (rawFunc != nullptr) {
223 return (*reinterpret_cast<FuseReplyOpenT>(rawFunc))(req, f);
224 }
225 return -1;
226 }
227
228 FuseReplyOpenT func = reinterpret_cast<FuseReplyOpenT>(GetLibfuseLibFunc(__func__));
229 if (func == nullptr) {
230 return -1;
231 }
232 return (*func)(req, f);
233 }
234
fuse_reply_buf(fuse_req_t req,const char * buf,size_t size)235 int fuse_reply_buf(fuse_req_t req, const char *buf, size_t size)
236 {
237 if (IsFuncNeedMock(__func__)) {
238 CommonMockFuncT rawFunc = GetMockFunc(__func__);
239 if (rawFunc != nullptr) {
240 return (*reinterpret_cast<FuseReplyBufT>(rawFunc))(req, buf, size);
241 }
242 return -1;
243 }
244
245 FuseReplyBufT func = reinterpret_cast<FuseReplyBufT>(GetLibfuseLibFunc(__func__));
246 if (func == nullptr) {
247 return -1;
248 }
249 return (*func)(req, buf, size);
250 }
251
fuse_reply_write(fuse_req_t req,size_t count)252 int fuse_reply_write(fuse_req_t req, size_t count)
253 {
254 if (IsFuncNeedMock(__func__)) {
255 CommonMockFuncT rawFunc = GetMockFunc(__func__);
256 if (rawFunc != nullptr) {
257 return (*reinterpret_cast<FuseReplyWriteT>(rawFunc))(req, count);
258 }
259 return -1;
260 }
261
262 FuseReplyWriteT func = reinterpret_cast<FuseReplyWriteT>(GetLibfuseLibFunc(__func__));
263 if (func == nullptr) {
264 return -1;
265 }
266 return (*func)(req, count);
267 }
268
fuse_add_direntry(fuse_req_t req,char * buf,size_t bufsize,const char * name,const struct stat * stbuf,off_t off)269 size_t fuse_add_direntry(fuse_req_t req, char *buf, size_t bufsize,
270 const char *name, const struct stat *stbuf, off_t off)
271 {
272 if (IsFuncNeedMock(__func__)) {
273 CommonMockFuncT rawFunc = GetMockFunc(__func__);
274 if (rawFunc != nullptr) {
275 return (*reinterpret_cast<FuseAddDirentryT>(rawFunc))(req, buf, bufsize, name, stbuf, off);
276 }
277 return 0;
278 }
279
280 FuseAddDirentryT func = reinterpret_cast<FuseAddDirentryT>(GetLibfuseLibFunc(__func__));
281 if (func == nullptr) {
282 return 0;
283 }
284 return (*func)(req, buf, bufsize, name, stbuf, off);
285 }
286
287 #ifdef __cplusplus
288 }
289 #endif
290