• 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 #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