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)
|