init: support setting rlimits per service

Add a new service option, `rlimit` that allows a given rlimit to be
set for a specific service instead of globally.

Use the same parsing, now allowing text such as 'cpu' or 'rtprio'
instead of relying on the enum value for the `setrlimit` builtin
command as well.

Bug: 63882119
Bug: 64894637

Test: boot bullhead, run a test app that attempts to set its rtprio to
      95, see that the priority set fails normally but passes when
      `rlimit rtprio 99 99` is used as its service option.
      See that this fails when `rlimit rtprio 50 50` is used as well.
Test: new unit tests

Change-Id: I4a13ca20e8529937d8b4bc11718ffaaf77523a52
diff --git a/init/builtins.cpp b/init/builtins.cpp
index 54ccf09..e2e3d93 100644
--- a/init/builtins.cpp
+++ b/init/builtins.cpp
@@ -63,6 +63,7 @@
 #include "parser.h"
 #include "property_service.h"
 #include "reboot.h"
+#include "rlimit_parser.h"
 #include "service.h"
 #include "signal_handler.h"
 #include "util.h"
@@ -563,20 +564,10 @@
 }
 
 static Result<Success> do_setrlimit(const std::vector<std::string>& args) {
-    int resource;
-    if (!android::base::ParseInt(args[1], &resource)) {
-        return Error() << "unable to parse resource, " << args[1];
-    }
+    auto rlimit = ParseRlimit(args);
+    if (!rlimit) return rlimit.error();
 
-    struct rlimit limit;
-    if (!android::base::ParseUint(args[2], &limit.rlim_cur)) {
-        return Error() << "unable to parse rlim_cur, " << args[2];
-    }
-    if (!android::base::ParseUint(args[3], &limit.rlim_max)) {
-        return Error() << "unable to parse rlim_max, " << args[3];
-    }
-
-    if (setrlimit(resource, &limit) == -1) {
+    if (setrlimit(rlimit->first, &rlimit->second) == -1) {
         return ErrnoError() << "setrlimit failed";
     }
     return Success();