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