summaryrefslogtreecommitdiff
path: root/gnu/packages/patches/glibc-reinstate-prlimit64-fallback.patch
blob: ccc153c12a0ed3d5a4a9ff79a6e999645d347d4a (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
This patch reinstates fallback code when the 'prlimit64' system call is
missing by reverting the relevant part of this upstream commit:

  commit 695d7d138eda449678a1650a8b8b58181033353f
  Author: Joseph Myers <joseph@codesourcery.com>
  Date:   Tue May 9 14:05:09 2017 +0000

      Assume prlimit64 is available.

The fallback code is useful on systems that lack 'prlimit64', such as the
2.6.32-on-steroid kernel found on RHEL 6:

  <https://lists.gnu.org/archive/html/guix-devel/2018-03/msg00349.html>

diff --git a/sysdeps/unix/sysv/linux/getrlimit64.c b/sysdeps/unix/sysv/linux/getrlimit64.c
index 37c173286f..56af3c0646 100644
--- b/sysdeps/unix/sysv/linux/getrlimit64.c
+++ a/sysdeps/unix/sysv/linux/getrlimit64.c
@@ -35,7 +35,40 @@
 int
 __getrlimit64 (enum __rlimit_resource resource, struct rlimit64 *rlimits)
 {
-  return INLINE_SYSCALL_CALL (prlimit64, 0, resource, NULL, rlimits);
+#ifdef __NR_prlimit64
+  int res = INLINE_SYSCALL_CALL (prlimit64, 0, resource, NULL, rlimits);
+  if (res == 0 || errno != ENOSYS)
+    return res;
+#endif
+
+/* The fallback code only makes sense if the platform supports either
+   __NR_ugetrlimit and/or __NR_getrlimit.  */
+#if defined (__NR_ugetrlimit) || defined (__NR_getrlimit)
+# ifndef __NR_ugetrlimit
+#  define __NR_ugetrlimit __NR_getrlimit
+# endif
+# if __RLIM_T_MATCHES_RLIM64_T
+#  define rlimits32 (*rlimits)
+# else
+  struct rlimit rlimits32;
+# endif
+
+  if (INLINE_SYSCALL_CALL (ugetrlimit, resource, &rlimits32) < 0)
+    return -1;
+
+# if !__RLIM_T_MATCHES_RLIM64_T
+  if (rlimits32.rlim_cur == RLIM_INFINITY)
+    rlimits->rlim_cur = RLIM64_INFINITY;
+  else
+    rlimits->rlim_cur = rlimits32.rlim_cur;
+  if (rlimits32.rlim_max == RLIM_INFINITY)
+    rlimits->rlim_max = RLIM64_INFINITY;
+  else
+    rlimits->rlim_max = rlimits32.rlim_max;
+# endif /* !__RLIM_T_MATCHES_RLIM64_T */
+#endif /* defined (__NR_ugetrlimit) || defined (__NR_getrlimit)  */
+
+  return 0;
 }
 libc_hidden_def (__getrlimit64)
 
diff --git a/sysdeps/unix/sysv/linux/setrlimit.c b/sysdeps/unix/sysv/linux/setrlimit.c
index 01812ac355..8773c78236 100644
--- b/sysdeps/unix/sysv/linux/setrlimit.c
+++ a/sysdeps/unix/sysv/linux/setrlimit.c
@@ -34,6 +34,7 @@
 int
 __setrlimit (enum __rlimit_resource resource, const struct rlimit *rlim)
 {
+# ifdef __NR_prlimit64
   struct rlimit64 rlim64;
 
   if (rlim->rlim_cur == RLIM_INFINITY)
@@ -45,7 +46,11 @@
   else
     rlim64.rlim_max = rlim->rlim_max;
 
-  return INLINE_SYSCALL_CALL (prlimit64, 0, resource, &rlim64, NULL);
+  int res = INLINE_SYSCALL_CALL (prlimit64, 0, resource, &rlim64, NULL);
+  if (res == 0 || errno != ENOSYS)
+    return res;
+# endif
+  return INLINE_SYSCALL_CALL (setrlimit, resource, rlim);
 }
 
 # if SHLIB_COMPAT (libc, GLIBC_2_0, GLIBC_2_2)
diff --git a/sysdeps/unix/sysv/linux/setrlimit64.c b/sysdeps/unix/sysv/linux/setrlimit64.c
index 2dd129d99e..db1960fc18 100644
--- b/sysdeps/unix/sysv/linux/setrlimit64.c
+++ a/sysdeps/unix/sysv/linux/setrlimit64.c
@@ -36,7 +36,36 @@
 int
 __setrlimit64 (enum __rlimit_resource resource, const struct rlimit64 *rlimits)
 {
-  return INLINE_SYSCALL_CALL (prlimit64, 0, resource, rlimits, NULL);
+  int res;
+
+#ifdef __NR_prlimit64
+  res = INLINE_SYSCALL_CALL (prlimit64, 0, resource, rlimits, NULL);
+  if (res == 0 || errno != ENOSYS)
+    return res;
+#endif
+
+/* The fallback code only makes sense if the platform supports
+   __NR_setrlimit.  */
+#ifdef __NR_setrlimit
+# if !__RLIM_T_MATCHES_RLIM64_T
+  struct rlimit rlimits32;
+
+  if (rlimits->rlim_cur >= RLIM_INFINITY)
+    rlimits32.rlim_cur = RLIM_INFINITY;
+  else
+    rlimits32.rlim_cur = rlimits->rlim_cur;
+  if (rlimits->rlim_max >= RLIM_INFINITY)
+    rlimits32.rlim_max = RLIM_INFINITY;
+  else
+    rlimits32.rlim_max = rlimits->rlim_max;
+# else
+#  define rlimits32 (*rlimits)
+# endif
+
+  res = INLINE_SYSCALL_CALL (setrlimit, resource, &rlimits32);
+#endif
+
+  return res;
 }
 weak_alias (__setrlimit64, setrlimit64)