• 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 "inotify_mock.h"
17 
18 #include <dlfcn.h>
19 
20 namespace OHOS {
21 namespace FileManagement {
22 namespace ModuleFileIO {
23 namespace Test {
24 
25 thread_local std::shared_ptr<InotifyMock> InotifyMock::inotifyMock = nullptr;
26 thread_local bool InotifyMock::mockable = false;
27 
GetMock()28 std::shared_ptr<InotifyMock> InotifyMock::GetMock()
29 {
30     if (inotifyMock == nullptr) {
31         inotifyMock = std::make_shared<InotifyMock>();
32     }
33     return inotifyMock;
34 }
35 
EnableMock()36 void InotifyMock::EnableMock()
37 {
38     mockable = true;
39 }
40 
DisableMock()41 void InotifyMock::DisableMock()
42 {
43     inotifyMock = nullptr;
44     mockable = false;
45 }
46 
IsMockable()47 bool InotifyMock::IsMockable()
48 {
49     return mockable;
50 }
51 
52 } // namespace Test
53 } // namespace ModuleFileIO
54 } // namespace FileManagement
55 } // namespace OHOS
56 
57 #ifdef __cplusplus
58 extern "C" {
59 using namespace OHOS::FileManagement::ModuleFileIO::Test;
60 
inotify_init()61 int inotify_init()
62 {
63     if (InotifyMock::IsMockable()) {
64         return InotifyMock::GetMock()->inotify_init();
65     }
66 
67     static int (*realInotifyInit)() = []() {
68         auto func = (int (*)())dlsym(RTLD_NEXT, "inotify_init");
69         if (!func) {
70             GTEST_LOG_(ERROR) << "Failed to resolve real inotify_init: " << dlerror();
71         }
72         return func;
73     }();
74 
75     if (!realInotifyInit) {
76         return -1;
77     }
78 
79     return realInotifyInit();
80 }
81 
inotify_add_watch(int fd,const char * pathname,uint32_t mask)82 int inotify_add_watch(int fd, const char *pathname, uint32_t mask)
83 {
84     if (InotifyMock::IsMockable()) {
85         return InotifyMock::GetMock()->inotify_add_watch(fd, pathname, mask);
86     }
87 
88     static int (*realInotifyAddWatch)(int, const char *, uint32_t) = []() {
89         auto func = (int (*)(int, const char *, uint32_t))dlsym(RTLD_NEXT, "inotify_add_watch");
90         if (!func) {
91             GTEST_LOG_(ERROR) << "Failed to resolve real inotify_add_watch: " << dlerror();
92         }
93         return func;
94     }();
95 
96     if (!realInotifyAddWatch) {
97         return -1;
98     }
99 
100     return realInotifyAddWatch(fd, pathname, mask);
101 }
102 
inotify_rm_watch(int fd,int wd)103 int inotify_rm_watch(int fd, int wd)
104 {
105     if (InotifyMock::IsMockable()) {
106         return InotifyMock::GetMock()->inotify_rm_watch(fd, wd);
107     }
108 
109     static int (*realInotifyRmWatch)(int, int) = []() {
110         auto func = (int (*)(int, int))dlsym(RTLD_NEXT, "inotify_rm_watch");
111         if (!func) {
112             GTEST_LOG_(ERROR) << "Failed to resolve real inotify_rm_watch: " << dlerror();
113         }
114         return func;
115     }();
116 
117     if (!realInotifyRmWatch) {
118         return -1;
119     }
120 
121     return realInotifyRmWatch(fd, wd);
122 }
123 
124 } // extern "C"
125 #endif