100600bfbSopenharmony_ci/*
200600bfbSopenharmony_ci* Copyright (C) 2021 Huawei Device Co., Ltd.
300600bfbSopenharmony_ci* Licensed under the Apache License, Version 2.0 (the "License");
400600bfbSopenharmony_ci* you may not use this file except in compliance with the License.
500600bfbSopenharmony_ci* You may obtain a copy of the License at
600600bfbSopenharmony_ci*
700600bfbSopenharmony_ci* http://www.apache.org/licenses/LICENSE-2.0
800600bfbSopenharmony_ci*
900600bfbSopenharmony_ci* Unless required by applicable law or agreed to in writing, software
1000600bfbSopenharmony_ci* distributed under the License is distributed on an "AS IS" BASIS,
1100600bfbSopenharmony_ci* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
1200600bfbSopenharmony_ci* See the License for the specific language governing permissions and
1300600bfbSopenharmony_ci* limitations under the License.
1400600bfbSopenharmony_ci*/
1500600bfbSopenharmony_ci#include <unistd.h>
1600600bfbSopenharmony_ci#include <sys/stat.h>
1700600bfbSopenharmony_ci#include "hilog_wrapper.h"
1800600bfbSopenharmony_ci#include "util/file_utils.h"
1900600bfbSopenharmony_ciusing namespace std;
2000600bfbSopenharmony_cinamespace OHOS {
2100600bfbSopenharmony_cinamespace HiviewDFX {
2200600bfbSopenharmony_cistatic const std::string UNKNOWN = "unknown";
2300600bfbSopenharmony_ciFileUtils::FileUtils()
2400600bfbSopenharmony_ci{
2500600bfbSopenharmony_ci}
2600600bfbSopenharmony_ciFileUtils::~FileUtils()
2700600bfbSopenharmony_ci{
2800600bfbSopenharmony_ci}
2900600bfbSopenharmony_ci
3000600bfbSopenharmony_cibool FileUtils::CreateFolder(const string &path)
3100600bfbSopenharmony_ci{
3200600bfbSopenharmony_ci    if (!access(path.c_str(), F_OK) || path == "") {
3300600bfbSopenharmony_ci        return true;
3400600bfbSopenharmony_ci    }
3500600bfbSopenharmony_ci
3600600bfbSopenharmony_ci    size_t pos = path.rfind("/");
3700600bfbSopenharmony_ci    if (pos == string::npos) {
3800600bfbSopenharmony_ci        return false;
3900600bfbSopenharmony_ci    }
4000600bfbSopenharmony_ci
4100600bfbSopenharmony_ci    string upperPath = path.substr(0, pos);
4200600bfbSopenharmony_ci    if (CreateFolder(upperPath)) {
4300600bfbSopenharmony_ci        if (mkdir(path.c_str(), S_IRWXU | S_IRWXG | S_IRWXO)) {
4400600bfbSopenharmony_ci            if (errno != EEXIST) {
4500600bfbSopenharmony_ci                return false;
4600600bfbSopenharmony_ci            }
4700600bfbSopenharmony_ci        }
4800600bfbSopenharmony_ci        return true;
4900600bfbSopenharmony_ci    }
5000600bfbSopenharmony_ci    return false;
5100600bfbSopenharmony_ci}
5200600bfbSopenharmony_ci
5300600bfbSopenharmony_cibool FileUtils::LoadStringFromProcCb(const std::string& path, bool oneLine, bool endWithoutN, const DataHandler& func)
5400600bfbSopenharmony_ci{
5500600bfbSopenharmony_ci    char canonicalPath[PATH_MAX] = {0};
5600600bfbSopenharmony_ci    if (realpath(path.c_str(), canonicalPath) == nullptr) {
5700600bfbSopenharmony_ci        DUMPER_HILOGE(MODULE_COMMON, "realpath failed, errno=%{public}d, path=%{public}s", errno, path.c_str());
5800600bfbSopenharmony_ci        return false;
5900600bfbSopenharmony_ci    }
6000600bfbSopenharmony_ci    auto fp = std::unique_ptr<FILE, decltype(&fclose)>{fopen(canonicalPath, "re"), fclose};
6100600bfbSopenharmony_ci    if (fp == nullptr) {
6200600bfbSopenharmony_ci        DUMPER_HILOGE(MODULE_COMMON, "fopen failed, errno=%{public}d, path=%{public}s", errno, path.c_str());
6300600bfbSopenharmony_ci        return false;
6400600bfbSopenharmony_ci    }
6500600bfbSopenharmony_ci    char *lineBuf = nullptr;
6600600bfbSopenharmony_ci    ssize_t lineLen;
6700600bfbSopenharmony_ci    size_t lineAlloc = 0;
6800600bfbSopenharmony_ci    while ((lineLen = getline(&lineBuf, &lineAlloc, fp.get())) > 0) {
6900600bfbSopenharmony_ci        lineBuf[lineLen] = '\0';
7000600bfbSopenharmony_ci        if (endWithoutN && lineBuf[lineLen-1] == '\n') {
7100600bfbSopenharmony_ci            lineBuf[lineLen-1] = '\0';
7200600bfbSopenharmony_ci        }
7300600bfbSopenharmony_ci        const string content = lineBuf;
7400600bfbSopenharmony_ci        func(content);
7500600bfbSopenharmony_ci        if (oneLine) {
7600600bfbSopenharmony_ci            break;
7700600bfbSopenharmony_ci        }
7800600bfbSopenharmony_ci    }
7900600bfbSopenharmony_ci    if (lineBuf != nullptr) {
8000600bfbSopenharmony_ci        free(lineBuf);
8100600bfbSopenharmony_ci        lineBuf = nullptr;
8200600bfbSopenharmony_ci    }
8300600bfbSopenharmony_ci    return true;
8400600bfbSopenharmony_ci}
8500600bfbSopenharmony_ci
8600600bfbSopenharmony_cistring FileUtils::GetProcValue(const int32_t &pid, const string& path, const string& key)
8700600bfbSopenharmony_ci{
8800600bfbSopenharmony_ci    if (!DumpUtils::PathIsValid(path)) {
8900600bfbSopenharmony_ci        DUMPER_HILOGE(MODULE_COMMON, "path is valid");
9000600bfbSopenharmony_ci        return UNKNOWN;
9100600bfbSopenharmony_ci    }
9200600bfbSopenharmony_ci    auto fp = std::unique_ptr<FILE, decltype(&fclose)>{fopen(path.c_str(), "rd"), fclose};
9300600bfbSopenharmony_ci    if (fp == nullptr) {
9400600bfbSopenharmony_ci        DUMPER_HILOGE(MODULE_COMMON, "fopen failed");
9500600bfbSopenharmony_ci        return UNKNOWN;
9600600bfbSopenharmony_ci    }
9700600bfbSopenharmony_ci    char *lineBuf = nullptr;
9800600bfbSopenharmony_ci    ssize_t lineLen;
9900600bfbSopenharmony_ci    size_t lineAlloc = 0;
10000600bfbSopenharmony_ci    string content;
10100600bfbSopenharmony_ci    while ((lineLen = getline(&lineBuf, &lineAlloc, fp.get())) > 0) {
10200600bfbSopenharmony_ci        lineBuf[lineLen] = '\0';
10300600bfbSopenharmony_ci        if (lineBuf[lineLen - 1] == '\n') {
10400600bfbSopenharmony_ci            lineBuf[lineLen - 1] = '\0';
10500600bfbSopenharmony_ci        }
10600600bfbSopenharmony_ci        content = lineBuf;
10700600bfbSopenharmony_ci        if (content.find(key) != std::string::npos) {
10800600bfbSopenharmony_ci            break;
10900600bfbSopenharmony_ci        }
11000600bfbSopenharmony_ci        content = "";
11100600bfbSopenharmony_ci    }
11200600bfbSopenharmony_ci    if (lineBuf != nullptr) {
11300600bfbSopenharmony_ci        free(lineBuf);
11400600bfbSopenharmony_ci        lineBuf = nullptr;
11500600bfbSopenharmony_ci    }
11600600bfbSopenharmony_ci    if (!content.empty()) {
11700600bfbSopenharmony_ci        vector<string> values;
11800600bfbSopenharmony_ci        StringUtils::GetInstance().StringSplit(content, ":", values);
11900600bfbSopenharmony_ci        if (values.empty()) {
12000600bfbSopenharmony_ci            DUMPER_HILOGE(MODULE_SERVICE, "values is empty");
12100600bfbSopenharmony_ci            return UNKNOWN;
12200600bfbSopenharmony_ci        } else {
12300600bfbSopenharmony_ci            return values[1].substr(1);
12400600bfbSopenharmony_ci        }
12500600bfbSopenharmony_ci    } else {
12600600bfbSopenharmony_ci        DUMPER_HILOGE(MODULE_SERVICE, "content is empty");
12700600bfbSopenharmony_ci        return UNKNOWN;
12800600bfbSopenharmony_ci    }
12900600bfbSopenharmony_ci}
13000600bfbSopenharmony_ci} // namespace HiviewDFX
13100600bfbSopenharmony_ci} // namespace OHOS