1 /*
2 * Copyright (c) 2024 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 "utils_common.h"
17 #include <algorithm>
18 #include <cerrno>
19 #include <cstdint>
20 #include <cstdlib>
21 #include <dlfcn.h>
22 #include <dirent.h>
23 #include <fcntl.h>
24 #include <limits>
25 #include <linux/reboot.h>
26 #include <string>
27 #include <sys/reboot.h>
28 #include <sys/stat.h>
29 #include <sys/syscall.h>
30 #include <unistd.h>
31 #include <vector>
32 #include "log/log.h"
33
34 namespace Updater {
35 namespace Utils {
36 constexpr int USECONDS_PER_SECONDS = 1000000; // 1s = 1000000us
37 constexpr int NANOSECS_PER_USECONDS = 1000; // 1us = 1000ns
38
PathToRealPath(const std::string & path,std::string & realPath)39 bool PathToRealPath(const std::string &path, std::string &realPath)
40 {
41 if (path.empty()) {
42 LOG(ERROR) << "path is empty!";
43 return false;
44 }
45
46 if ((path.length() >= PATH_MAX)) {
47 LOG(ERROR) << "path len is error, the len is: " << path.length();
48 return false;
49 }
50
51 char tmpPath[PATH_MAX] = {0};
52 if (realpath(path.c_str(), tmpPath) == nullptr) {
53 LOG(ERROR) << "path to realpath error " << path;
54 return false;
55 }
56
57 realPath = tmpPath;
58 return true;
59 }
60
UsSleep(int usec)61 void UsSleep(int usec)
62 {
63 auto seconds = usec / USECONDS_PER_SECONDS;
64 long nanoSeconds = static_cast<long>(usec) % USECONDS_PER_SECONDS * NANOSECS_PER_USECONDS;
65 struct timespec ts = { static_cast<time_t>(seconds), nanoSeconds };
66 while (nanosleep(&ts, &ts) < 0 && errno == EINTR) {
67 }
68 }
69
IsUpdaterMode()70 bool IsUpdaterMode()
71 {
72 struct stat st {};
73 if (stat("/bin/updater", &st) == 0 && S_ISREG(st.st_mode)) {
74 LOG(INFO) << "updater mode";
75 return true;
76 }
77 LOG(INFO) << "normal mode";
78 return false;
79 }
80
LoadLibrary(const std::string & libName,const std::string & libPath)81 void* LoadLibrary(const std::string &libName, const std::string &libPath)
82 {
83 if (libName.empty()) {
84 LOG(ERROR) << "lib name is empty";
85 return nullptr;
86 }
87 if (libPath != "/system/lib64/" && libPath != "/vendor/lib64/") {
88 LOG(ERROR) << "lib path invalid";
89 return nullptr;
90 }
91 std::string libAbsPath = libPath + libName;
92 char realPath[PATH_MAX + 1] = {0};
93 if (realpath(libAbsPath.c_str(), realPath) == nullptr) {
94 LOG(ERROR) << "realpath error";
95 return nullptr;
96 }
97 void* handle = dlopen(libAbsPath.c_str(), RTLD_LAZY);
98 if (handle == nullptr) {
99 LOG(ERROR) << "dlopen fail, lib name = " << libName << "; dlerror = " << dlerror();
100 return nullptr;
101 }
102 return handle;
103 }
104
CloseLibrary(void * handle)105 void CloseLibrary(void* handle)
106 {
107 if (handle == nullptr) {
108 LOG(ERROR) << "handle is nulptr";
109 return;
110 }
111 dlclose(handle);
112 handle = nullptr;
113 }
114
GetFunction(void * handle,const std::string & funcName)115 void* GetFunction(void* handle, const std::string &funcName)
116 {
117 if (handle == nullptr) {
118 LOG(ERROR) << "handle is nullptr";
119 return nullptr;
120 }
121 if (funcName.empty()) {
122 LOG(ERROR) << "func name is empty";
123 return nullptr;
124 }
125 return dlsym(handle, funcName.c_str());
126 }
127 } // Utils
128 } // updater
129