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 /src | |
parent | 3437e478ba932edbab18a90638c20be1f0141156 (diff) | |
download | musl-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.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; |