Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit bc1ad967 authored by Rick Yiu's avatar Rick Yiu
Browse files

libprocessgroup: Support write to file feature

There may be some use cases that it needs to write string to a
file. This patch support write "Value" to "FilePath", where
both parameters could use special string "<uid>" and "<pid>" to
represent actual uid and pid.

Bug: 170507963
Test: function works
Change-Id: I543846f523518a9bcb3dd1b3437163a1b3157d95
parent 346e6792
Loading
Loading
Loading
Loading
+47 −0
Original line number Diff line number Diff line
@@ -24,6 +24,7 @@
#include <android-base/file.h>
#include <android-base/logging.h>
#include <android-base/stringprintf.h>
#include <android-base/strings.h>
#include <android-base/threads.h>

#include <cutils/android_filesystem_config.h>
@@ -38,6 +39,7 @@

using android::base::GetThreadId;
using android::base::StringPrintf;
using android::base::StringReplace;
using android::base::unique_fd;
using android::base::WriteStringToFile;

@@ -257,6 +259,39 @@ bool SetCgroupAction::ExecuteForTask(int tid) const {
    return true;
}

bool WriteFileAction::ExecuteForProcess(uid_t uid, pid_t pid) const {
    std::string filepath(filepath_), value(value_);

    filepath = StringReplace(filepath, "<uid>", std::to_string(uid), true);
    filepath = StringReplace(filepath, "<pid>", std::to_string(pid), true);
    value = StringReplace(value, "<uid>", std::to_string(uid), true);
    value = StringReplace(value, "<pid>", std::to_string(pid), true);

    if (!WriteStringToFile(value, filepath)) {
        PLOG(ERROR) << "Failed to write '" << value << "' to " << filepath;
        return false;
    }

    return true;
}

bool WriteFileAction::ExecuteForTask(int tid) const {
    std::string filepath(filepath_), value(value_);
    int uid = getuid();

    filepath = StringReplace(filepath, "<uid>", std::to_string(uid), true);
    filepath = StringReplace(filepath, "<pid>", std::to_string(tid), true);
    value = StringReplace(value, "<uid>", std::to_string(uid), true);
    value = StringReplace(value, "<pid>", std::to_string(tid), true);

    if (!WriteStringToFile(value, filepath)) {
        PLOG(ERROR) << "Failed to write '" << value << "' to " << filepath;
        return false;
    }

    return true;
}

bool ApplyProfileAction::ExecuteForProcess(uid_t uid, pid_t pid) const {
    for (const auto& profile : profiles_) {
        if (!profile->ExecuteForProcess(uid, pid)) {
@@ -459,6 +494,18 @@ bool TaskProfiles::Load(const CgroupMap& cg_map, const std::string& file_name) {
                } else {
                    LOG(WARNING) << "SetClamps: invalid parameter: " << boost_value;
                }
            } else if (action_name == "WriteFile") {
                std::string attr_filepath = params_val["FilePath"].asString();
                std::string attr_value = params_val["Value"].asString();
                if (!attr_filepath.empty() && !attr_value.empty()) {
                    profile->Add(std::make_unique<WriteFileAction>(attr_filepath, attr_value));
                } else if (attr_filepath.empty()) {
                    LOG(WARNING) << "WriteFile: invalid parameter: "
                                 << "empty filepath";
                } else if (attr_value.empty()) {
                    LOG(WARNING) << "WriteFile: invalid parameter: "
                                 << "empty value";
                }
            } else {
                LOG(WARNING) << "Unknown profile action: " << action_name;
            }
+13 −0
Original line number Diff line number Diff line
@@ -139,6 +139,19 @@ class SetCgroupAction : public ProfileAction {
    bool IsFdValid() const { return fd_ > FDS_INACCESSIBLE; }
};

// Write to file action
class WriteFileAction : public ProfileAction {
  public:
    WriteFileAction(const std::string& filepath, const std::string& value) noexcept
        : filepath_(filepath), value_(value) {}

    virtual bool ExecuteForProcess(uid_t uid, pid_t pid) const;
    virtual bool ExecuteForTask(int tid) const;

  private:
    std::string filepath_, value_;
};

class TaskProfile {
  public:
    TaskProfile() : res_cached_(false) {}