OSDN Git Service

Add prlimit to LP32.
authorElliott Hughes <enh@google.com>
Thu, 29 Oct 2015 00:14:48 +0000 (17:14 -0700)
committerElliott Hughes <enh@google.com>
Thu, 29 Oct 2015 03:04:59 +0000 (20:04 -0700)
Bug: http://b/24918750
Change-Id: I0151cd66ccf79a6169610de35bb9c288c0fa4917

libc/bionic/legacy_32_bit_support.cpp
libc/include/sys/resource.h
libc/libc.arm.map
libc/libc.map.txt
libc/libc.mips.map
libc/libc.x86.map
tests/sys_resource_test.cpp

index 20d258d..f2bb37d 100644 (file)
@@ -111,3 +111,22 @@ int getrlimit64(int resource, rlimit64* limits64) {
 int setrlimit64(int resource, const rlimit64* limits64) {
   return prlimit64(0, resource, limits64, NULL);
 }
+
+// There is no prlimit system call, so we need to use prlimit64.
+int prlimit(pid_t pid, int resource, const rlimit* n32, rlimit* o32) {
+  rlimit64 n64;
+  if (n32 != nullptr) {
+    n64.rlim_cur = (n32->rlim_cur == RLIM_INFINITY) ? RLIM64_INFINITY : n32->rlim_cur;
+    n64.rlim_max = (n32->rlim_max == RLIM_INFINITY) ? RLIM64_INFINITY : n32->rlim_max;
+  }
+
+  rlimit64 o64;
+  int result = prlimit64(pid, resource,
+                         (n32 != nullptr) ? &n64 : nullptr,
+                         (o32 != nullptr) ? &o64 : nullptr);
+  if (result != -1 && o32 != nullptr) {
+    o32->rlim_cur = (o64.rlim_cur == RLIM64_INFINITY) ? RLIM_INFINITY : o64.rlim_cur;
+    o32->rlim_max = (o64.rlim_max == RLIM64_INFINITY) ? RLIM_INFINITY : o64.rlim_max;
+  }
+  return result;
+}
index 3f8dd45..8209dfb 100644 (file)
@@ -53,10 +53,7 @@ extern int setpriority(int, int, int);
 
 extern int getrusage(int, struct rusage*);
 
-#if __LP64__
-/* Implementing prlimit for 32-bit isn't worth the effort. */
 extern int prlimit(pid_t, int, const struct rlimit*, struct rlimit*);
-#endif
 extern int prlimit64(pid_t, int, const struct rlimit64*, struct rlimit64*);
 
 __END_DECLS
index fce04ee..bc68fc0 100644 (file)
@@ -1314,6 +1314,7 @@ LIBC_N {
     getgrnam_r;
     preadv;
     preadv64;
+    prlimit; # arm mips x86
     pwritev;
     pwritev64;
     scandirat;
index b0f7030..418d4cf 100644 (file)
@@ -1341,6 +1341,7 @@ LIBC_N {
     getgrnam_r;
     preadv;
     preadv64;
+    prlimit; # arm mips x86
     pwritev;
     pwritev64;
     scandirat;
index e71d5ec..0c69c19 100644 (file)
@@ -1277,6 +1277,7 @@ LIBC_N {
     getgrnam_r;
     preadv;
     preadv64;
+    prlimit; # arm mips x86
     pwritev;
     pwritev64;
     scandirat;
index 6f60524..544ee13 100644 (file)
@@ -1275,6 +1275,7 @@ LIBC_N {
     getgrnam_r;
     preadv;
     preadv64;
+    prlimit; # arm mips x86
     pwritev;
     pwritev64;
     scandirat;
index 8cefc65..0b6b6ef 100644 (file)
@@ -33,7 +33,8 @@ class SysResourceTest : public ::testing::Test {
   virtual void SetUp() {
     ASSERT_EQ(0, getrlimit(RLIMIT_CORE, &l32_));
     ASSERT_EQ(0, getrlimit64(RLIMIT_CORE, &l64_));
-    ASSERT_EQ(0, prlimit64(0, RLIMIT_CORE, NULL, &pr_l64_));
+    ASSERT_EQ(0, prlimit(0, RLIMIT_CORE, nullptr, &pr_l32_));
+    ASSERT_EQ(0, prlimit64(0, RLIMIT_CORE, nullptr, &pr_l64_));
   }
 
   void CheckResourceLimits();
@@ -41,21 +42,28 @@ class SysResourceTest : public ::testing::Test {
  protected:
   rlimit l32_;
   rlimit64 l64_;
+  rlimit pr_l32_;
   rlimit64 pr_l64_;
 };
 
 void SysResourceTest::CheckResourceLimits() {
   ASSERT_EQ(0, getrlimit(RLIMIT_CORE, &l32_));
   ASSERT_EQ(0, getrlimit64(RLIMIT_CORE, &l64_));
-  ASSERT_EQ(0, prlimit64(0, RLIMIT_CORE, NULL, &pr_l64_));
+  ASSERT_EQ(0, prlimit(0, RLIMIT_CORE, nullptr, &pr_l32_));
+  ASSERT_EQ(0, prlimit64(0, RLIMIT_CORE, nullptr, &pr_l64_));
+
+  ASSERT_EQ(l32_.rlim_cur, pr_l32_.rlim_cur);
   ASSERT_EQ(l64_.rlim_cur, pr_l64_.rlim_cur);
+
   if (l64_.rlim_cur == RLIM64_INFINITY) {
     ASSERT_EQ(RLIM_INFINITY, l32_.rlim_cur);
   } else {
     ASSERT_EQ(l64_.rlim_cur, l32_.rlim_cur);
   }
 
+  ASSERT_EQ(l32_.rlim_max, pr_l32_.rlim_max);
   ASSERT_EQ(l64_.rlim_max, pr_l64_.rlim_max);
+
   if (l64_.rlim_max == RLIM64_INFINITY) {
     ASSERT_EQ(RLIM_INFINITY, l32_.rlim_max);
   } else {
@@ -88,13 +96,16 @@ TEST_F(SysResourceTest, setrlimit64) {
   ASSERT_EQ(456U, l64_.rlim_cur);
 }
 
+TEST_F(SysResourceTest, prlimit) {
+  pr_l32_.rlim_cur = pr_l32_.rlim_max;
+  ASSERT_EQ(0, prlimit(0, RLIMIT_CORE, &pr_l32_, nullptr));
+  CheckResourceLimits();
+  ASSERT_EQ(pr_l32_.rlim_max, pr_l32_.rlim_cur);
+}
+
 TEST_F(SysResourceTest, prlimit64) {
   pr_l64_.rlim_cur = pr_l64_.rlim_max;
-  ASSERT_EQ(0, prlimit64(0, RLIMIT_CORE, &pr_l64_, NULL));
+  ASSERT_EQ(0, prlimit64(0, RLIMIT_CORE, &pr_l64_, nullptr));
   CheckResourceLimits();
   ASSERT_EQ(pr_l64_.rlim_max, pr_l64_.rlim_cur);
 }
-
-TEST_F(SysResourceTest, prlimit) {
-  // prlimit is prlimit64 on LP64 and unimplemented on 32-bit. So we only test prlimit64.
-}