1 /*
2 * Copyright (c) 2022 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 "process_group_util.h"
17 #include <sstream>
18 #include <string>
19 #include <fstream>
20 #include <fcntl.h>
21 #include <sys/stat.h>
22 #include <unistd.h>
23 #include <linux/limits.h>
24 #include "nlohmann/json.hpp"
25 #include "securec.h"
26 #include "process_group_log.h"
27
28 namespace OHOS {
29 namespace ResourceSchedule {
30 namespace CgroupSetting {
31 namespace {
32 static constexpr int FMT_STR_BUFF_LEN = 256;
33 }
34
FormatString(const char * fmt,va_list vararg)35 std::string FormatString(const char* fmt, va_list vararg)
36 {
37 std::string strResult;
38 if (fmt) {
39 char buffer[FMT_STR_BUFF_LEN] = { 0 };
40 int nWritten = vsnprintf_s(buffer, FMT_STR_BUFF_LEN, FMT_STR_BUFF_LEN - 1, fmt, vararg);
41 if (nWritten > 0) {
42 strResult.append(buffer, 0, nWritten);
43 }
44 }
45 return strResult;
46 }
47
StringPrintf(const char * fmt,...)48 std::string StringPrintf(const char* fmt, ...)
49 {
50 va_list vararg;
51 va_start(vararg, fmt);
52 std::string result = FormatString(fmt, vararg);
53 va_end(vararg);
54 return result;
55 }
56
GetRealPath(const std::string & path,std::string & realPath)57 bool GetRealPath(const std::string& path, std::string& realPath)
58 {
59 char resolvedPath[PATH_MAX] = { 0 };
60 if (path.size() > PATH_MAX || !realpath(path.c_str(), resolvedPath)) {
61 PGCGS_LOGE("%{public}s realpath for %s failed", __func__, path.c_str());
62 return false;
63 }
64 realPath = std::string(resolvedPath);
65 return true;
66 }
67
ReadFileToString(const std::string & filePath,std::string & content)68 bool ReadFileToString(const std::string& filePath, std::string& content)
69 {
70 std::string realPath;
71 if (!GetRealPath(filePath, realPath)) {
72 return false;
73 }
74 int fd = open(realPath.c_str(), O_RDONLY | O_CLOEXEC);
75 if (fd < 0) {
76 return false;
77 }
78 struct stat sb {};
79 if (fstat(fd, &sb) != -1 && sb.st_size > 0) {
80 content.resize(sb.st_size);
81 }
82
83 ssize_t remaining = sb.st_size;
84 bool readStatus = true;
85 char* p = const_cast<char*>(content.data());
86
87 while (remaining > 0) {
88 ssize_t n = read(fd, p, remaining);
89 if (n < 0) {
90 readStatus = false;
91 break;
92 }
93 p += n;
94 remaining -= n;
95 }
96 close(fd);
97 return readStatus;
98 }
99
100
ReadFileToStringForVFS(const std::string & filePath,std::string & content)101 bool ReadFileToStringForVFS(const std::string& filePath, std::string& content)
102 {
103 std::string realPath;
104 if (!GetRealPath(filePath, realPath)) {
105 return false;
106 }
107 std::ifstream fin(realPath.c_str(), std::ios::in);
108 if (!fin) {
109 return false;
110 }
111 std::stringstream ss;
112 ss << fin.rdbuf();
113 content = ss.str();
114 fin.close();
115 return true;
116 }
117
118
WriteStringToFile(int fd,const std::string & content)119 bool WriteStringToFile(int fd, const std::string& content)
120 {
121 const char *p = content.data();
122 size_t remaining = content.size();
123 while (remaining > 0) {
124 ssize_t n = write(fd, p, remaining);
125 if (n == -1) {
126 return false;
127 }
128 p += n;
129 remaining -= n;
130 }
131 return true;
132 }
133
WriteStringToFile(const std::string & content,const std::string & filePath)134 bool WriteStringToFile(const std::string& content, const std::string& filePath)
135 {
136 std::string realPath;
137 if (!GetRealPath(filePath, realPath)) {
138 return false;
139 }
140 if (access(realPath.c_str(), W_OK)) {
141 return false;
142 }
143 int fd = open(realPath.c_str(), O_WRONLY | O_CLOEXEC);
144 if (fd < 0) {
145 PGCGS_LOGE("%{public}s failed. file: %s, fd = %{public}d", __func__, realPath.c_str(), fd);
146 return false;
147 }
148 bool result = WriteStringToFile(fd, content);
149 close(fd);
150 return result;
151 }
152 } // namespace CgroupSetting
153 } // namespace ResourceSchedule
154 } // namespace OHOS
155