/* * Copyright (C) 2017 The Android Open Source Project * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ #include "rlimit_parser.h" #include #include using android::base::EqualsIgnoreCase; using android::base::ParseInt; using android::base::ParseUint; using android::base::StartsWith; namespace android { namespace init { // Builtins and service definitions both have their arguments start at 1 and finish at 3. Result> ParseRlimit(const std::vector& args) { static const std::vector> text_to_resources = { {"cpu", RLIMIT_CPU}, {"fsize", RLIMIT_FSIZE}, {"data", RLIMIT_DATA}, {"stack", RLIMIT_STACK}, {"core", RLIMIT_CORE}, {"rss", RLIMIT_RSS}, {"nproc", RLIMIT_NPROC}, {"nofile", RLIMIT_NOFILE}, {"memlock", RLIMIT_MEMLOCK}, {"as", RLIMIT_AS}, {"locks", RLIMIT_LOCKS}, {"sigpending", RLIMIT_SIGPENDING}, {"msgqueue", RLIMIT_MSGQUEUE}, {"nice", RLIMIT_NICE}, {"rtprio", RLIMIT_RTPRIO}, {"rttime", RLIMIT_RTTIME}, }; int resource; if (ParseInt(args[1], &resource)) { if (resource >= RLIM_NLIMITS) { return Error() << "Resource '" << args[1] << "' over the maximum resource value '" << RLIM_NLIMITS << "'"; } else if (resource < 0) { return Error() << "Resource '" << args[1] << "' below the minimum resource value '0'"; } } else { std::string resource_string; if (StartsWith(args[1], "RLIM_")) { resource_string = args[1].substr(5); } else if (StartsWith(args[1], "RLIMIT_")) { resource_string = args[1].substr(7); } else { resource_string = args[1]; } auto it = std::find_if(text_to_resources.begin(), text_to_resources.end(), [&resource_string](const auto& entry) { return EqualsIgnoreCase(resource_string, entry.first); }); if (it == text_to_resources.end()) { return Error() << "Could not parse resource '" << args[1] << "'"; } resource = it->second; } rlimit limit; if (args[2] == "-1" || args[2] == "unlimited") { limit.rlim_cur = RLIM_INFINITY; } else if (!ParseUint(args[2], &limit.rlim_cur)) { return Error() << "Could not parse soft limit '" << args[2] << "'"; } if (args[3] == "-1" || args[3] == "unlimited") { limit.rlim_max = RLIM_INFINITY; } else if (!ParseUint(args[3], &limit.rlim_max)) { return Error() << "Could not parse hard limit '" << args[3] << "'"; } return std::pair{resource, limit}; } } // namespace init } // namespace android