1/*
2* Copyright (C) 2021 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#include <unistd.h>
16#include <sys/stat.h>
17#include "hilog_wrapper.h"
18#include "util/file_utils.h"
19using namespace std;
20namespace OHOS {
21namespace HiviewDFX {
22static const std::string UNKNOWN = "unknown";
23FileUtils::FileUtils()
24{
25}
26FileUtils::~FileUtils()
27{
28}
29
30bool FileUtils::CreateFolder(const string &path)
31{
32    if (!access(path.c_str(), F_OK) || path == "") {
33        return true;
34    }
35
36    size_t pos = path.rfind("/");
37    if (pos == string::npos) {
38        return false;
39    }
40
41    string upperPath = path.substr(0, pos);
42    if (CreateFolder(upperPath)) {
43        if (mkdir(path.c_str(), S_IRWXU | S_IRWXG | S_IRWXO)) {
44            if (errno != EEXIST) {
45                return false;
46            }
47        }
48        return true;
49    }
50    return false;
51}
52
53bool FileUtils::LoadStringFromProcCb(const std::string& path, bool oneLine, bool endWithoutN, const DataHandler& func)
54{
55    char canonicalPath[PATH_MAX] = {0};
56    if (realpath(path.c_str(), canonicalPath) == nullptr) {
57        DUMPER_HILOGE(MODULE_COMMON, "realpath failed, errno=%{public}d, path=%{public}s", errno, path.c_str());
58        return false;
59    }
60    auto fp = std::unique_ptr<FILE, decltype(&fclose)>{fopen(canonicalPath, "re"), fclose};
61    if (fp == nullptr) {
62        DUMPER_HILOGE(MODULE_COMMON, "fopen failed, errno=%{public}d, path=%{public}s", errno, path.c_str());
63        return false;
64    }
65    char *lineBuf = nullptr;
66    ssize_t lineLen;
67    size_t lineAlloc = 0;
68    while ((lineLen = getline(&lineBuf, &lineAlloc, fp.get())) > 0) {
69        lineBuf[lineLen] = '\0';
70        if (endWithoutN && lineBuf[lineLen-1] == '\n') {
71            lineBuf[lineLen-1] = '\0';
72        }
73        const string content = lineBuf;
74        func(content);
75        if (oneLine) {
76            break;
77        }
78    }
79    if (lineBuf != nullptr) {
80        free(lineBuf);
81        lineBuf = nullptr;
82    }
83    return true;
84}
85
86string FileUtils::GetProcValue(const int32_t &pid, const string& path, const string& key)
87{
88    if (!DumpUtils::PathIsValid(path)) {
89        DUMPER_HILOGE(MODULE_COMMON, "path is valid");
90        return UNKNOWN;
91    }
92    auto fp = std::unique_ptr<FILE, decltype(&fclose)>{fopen(path.c_str(), "rd"), fclose};
93    if (fp == nullptr) {
94        DUMPER_HILOGE(MODULE_COMMON, "fopen failed");
95        return UNKNOWN;
96    }
97    char *lineBuf = nullptr;
98    ssize_t lineLen;
99    size_t lineAlloc = 0;
100    string content;
101    while ((lineLen = getline(&lineBuf, &lineAlloc, fp.get())) > 0) {
102        lineBuf[lineLen] = '\0';
103        if (lineBuf[lineLen - 1] == '\n') {
104            lineBuf[lineLen - 1] = '\0';
105        }
106        content = lineBuf;
107        if (content.find(key) != std::string::npos) {
108            break;
109        }
110        content = "";
111    }
112    if (lineBuf != nullptr) {
113        free(lineBuf);
114        lineBuf = nullptr;
115    }
116    if (!content.empty()) {
117        vector<string> values;
118        StringUtils::GetInstance().StringSplit(content, ":", values);
119        if (values.empty()) {
120            DUMPER_HILOGE(MODULE_SERVICE, "values is empty");
121            return UNKNOWN;
122        } else {
123            return values[1].substr(1);
124        }
125    } else {
126        DUMPER_HILOGE(MODULE_SERVICE, "content is empty");
127        return UNKNOWN;
128    }
129}
130} // namespace HiviewDFX
131} // namespace OHOS