diff options
author | Rich Felker <dalias@aerifal.cx> | 2020-10-27 00:45:59 -0400 |
---|---|---|
committer | Rich Felker <dalias@aerifal.cx> | 2020-10-27 00:45:59 -0400 |
commit | 6ce91ef0e8eddd756def4e7e5c47c639f45fcf5f (patch) | |
tree | d1140e71b580268e477026588810723cb6e6022b | |
parent | 3437e478ba932edbab18a90638c20be1f0141156 (diff) | |
download | musl-6ce91ef0e8eddd756def4e7e5c47c639f45fcf5f.tar.gz musl-6ce91ef0e8eddd756def4e7e5c47c639f45fcf5f.tar.bz2 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.
-rw-r--r-- | src/misc/setrlimit.c | 37 |
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; |