• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
2  * Copyright (C) 2025 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 "c_mock.h"
17 
18 #include <dlfcn.h>
19 
20 namespace OHOS::FileManagement::ModuleFileIO::Test {
21 
22 thread_local std::shared_ptr<CMock> CMock::cMock = nullptr;
23 thread_local bool CMock::mockable = false;
24 
GetMock()25 std::shared_ptr<CMock> CMock::GetMock()
26 {
27     if (cMock == nullptr) {
28         cMock = std::make_shared<CMock>();
29     }
30     return cMock;
31 }
32 
EnableMock()33 void CMock::EnableMock()
34 {
35     mockable = true;
36 }
37 
DisableMock()38 void CMock::DisableMock()
39 {
40     cMock = nullptr;
41     mockable = false;
42 }
43 
IsMockable()44 bool CMock::IsMockable()
45 {
46     return mockable;
47 }
48 
49 } // namespace OHOS::FileManagement::ModuleFileIO::Test
50 
51 #ifdef __cplusplus
52 extern "C" {
53 using namespace OHOS::FileManagement::ModuleFileIO::Test;
54 
fseek(FILE * stream,long len,int offset)55 int fseek(FILE *stream, long len, int offset)
56 {
57     if (CMock::IsMockable()) {
58         return CMock::GetMock()->fseek(stream, len, offset);
59     }
60 
61     static int (*realFseek)(FILE *, long, int) = []() {
62         auto func = (int (*)(FILE *, long, int))dlsym(RTLD_NEXT, "fseek");
63         if (!func) {
64             GTEST_LOG_(ERROR) << "Failed to resolve real fseek: " << dlerror();
65         }
66         return func;
67     }();
68 
69     if (!realFseek) {
70         return -1;
71     }
72 
73     return realFseek(stream, len, offset);
74 }
75 
ftell(FILE * stream)76 long ftell(FILE *stream)
77 {
78     if (CMock::IsMockable()) {
79         return CMock::GetMock()->ftell(stream);
80     }
81 
82     static long (*realFtell)(FILE *) = []() {
83         auto func = (long (*)(FILE *))dlsym(RTLD_NEXT, "ftell");
84         if (!func) {
85             GTEST_LOG_(ERROR) << "Failed to resolve real ftell: " << dlerror();
86         }
87         return func;
88     }();
89 
90     if (!realFtell) {
91         return -1;
92     }
93 
94     return realFtell(stream);
95 }
96 } // extern "C"
97 #endif