about summary refs log tree commit diff
path: root/src
diff options
context:
space:
mode:
authorRich Felker <dalias@aerifal.cx>2020-10-27 00:45:59 -0400
committerRich Felker <dalias@aerifal.cx>2020-10-27 00:45:59 -0400
commit6ce91ef0e8eddd756def4e7e5c47c639f45fcf5f (patch)
treed1140e71b580268e477026588810723cb6e6022b /src
parent3437e478ba932edbab18a90638c20be1f0141156 (diff)
downloadmusl-6ce91ef0e8eddd756def4e7e5c47c639f45fcf5f.tar.gz
musl-6ce91ef0e8eddd756def4e7e5c47c639f45fcf5f.tar.xz
musl-6ce91ef0e8eddd756def4e7e5c47c639f45fcf5f.zip
avoid __synccall for setrlimit on kernels with prlimit syscall
resource limits have been process-wide since linux 2.6.10, and the
prlimit syscall was added in 2.6.36, so prlimit can be assumed to set
the resource limits correctly for the whole process.
Diffstat (limited to 'src')
-rw-r--r--src/misc/setrlimit.c37
1 files changed, 17 insertions, 20 deletions
diff --git a/src/misc/setrlimit.c b/src/misc/setrlimit.c
index 7a66ab29..8340aee0 100644
--- a/src/misc/setrlimit.c
+++ b/src/misc/setrlimit.c
@@ -6,25 +6,8 @@
 #define MIN(a, b) ((a)<(b) ? (a) : (b))
 #define FIX(x) do{ if ((x)>=SYSCALL_RLIM_INFINITY) (x)=RLIM_INFINITY; }while(0)
 
-static int __setrlimit(int resource, const struct rlimit *rlim)
-{
-	unsigned long k_rlim[2];
-	struct rlimit tmp;
-	if (SYSCALL_RLIM_INFINITY != RLIM_INFINITY) {
-		tmp = *rlim;
-		FIX(tmp.rlim_cur);
-		FIX(tmp.rlim_max);
-		rlim = &tmp;
-	}
-	int ret = __syscall(SYS_prlimit64, 0, resource, rlim, 0);
-	if (ret != -ENOSYS) return ret;
-	k_rlim[0] = MIN(rlim->rlim_cur, MIN(-1UL, SYSCALL_RLIM_INFINITY));
-	k_rlim[1] = MIN(rlim->rlim_max, MIN(-1UL, SYSCALL_RLIM_INFINITY));
-	return __syscall(SYS_setrlimit, resource, k_rlim);
-}
-
 struct ctx {
-	const struct rlimit *rlim;
+	unsigned long lim[2];
 	int res;
 	int err;
 };
@@ -33,12 +16,26 @@ static void do_setrlimit(void *p)
 {
 	struct ctx *c = p;
 	if (c->err>0) return;
-	c->err = -__setrlimit(c->res, c->rlim);
+	c->err = -__syscall(SYS_setrlimit, c->res, c->lim);
 }
 
 int setrlimit(int resource, const struct rlimit *rlim)
 {
-	struct ctx c = { .res = resource, .rlim = rlim, .err = -1 };
+	struct rlimit tmp;
+	if (SYSCALL_RLIM_INFINITY != RLIM_INFINITY) {
+		tmp = *rlim;
+		FIX(tmp.rlim_cur);
+		FIX(tmp.rlim_max);
+		rlim = &tmp;
+	}
+	int ret = __syscall(SYS_prlimit64, 0, resource, rlim, 0);
+	if (ret != -ENOSYS) return __syscall_ret(ret);
+
+	struct ctx c = {
+		.lim[0] = MIN(rlim->rlim_cur, MIN(-1UL, SYSCALL_RLIM_INFINITY)),
+		.lim[1] = MIN(rlim->rlim_max, MIN(-1UL, SYSCALL_RLIM_INFINITY)),
+		.res = resource, .err = -1
+	};
 	__synccall(do_setrlimit, &c);
 	if (c.err) {
 		if (c.err>0) errno = c.err;