diff options
| -rw-r--r-- | arch/mips/syscall_arch.h | 2 | ||||
| -rw-r--r-- | src/internal/syscall.h | 4 | ||||
| -rw-r--r-- | src/linux/prlimit.c | 17 | ||||
| -rw-r--r-- | src/misc/getrlimit.c | 8 | ||||
| -rw-r--r-- | src/misc/setrlimit.c | 12 | 
5 files changed, 40 insertions, 3 deletions
| diff --git a/arch/mips/syscall_arch.h b/arch/mips/syscall_arch.h index c52976eb..e62c3398 100644 --- a/arch/mips/syscall_arch.h +++ b/arch/mips/syscall_arch.h @@ -5,6 +5,8 @@  long (__syscall)(long, ...); +#define SYSCALL_RLIM_INFINITY (-1UL/2) +  #ifndef __clang__  #define __asm_syscall(...) do { \ diff --git a/src/internal/syscall.h b/src/internal/syscall.h index d0fe107e..1c73d0de 100644 --- a/src/internal/syscall.h +++ b/src/internal/syscall.h @@ -4,6 +4,10 @@  #include <sys/syscall.h>  #include "syscall_arch.h" +#ifndef SYSCALL_RLIM_INFINITY +#define SYSCALL_RLIM_INFINITY (~0ULL) +#endif +  #ifndef __scc  #define __scc(X) ((long) (X))  typedef long syscall_arg_t; diff --git a/src/linux/prlimit.c b/src/linux/prlimit.c index d1639cca..0fe28e10 100644 --- a/src/linux/prlimit.c +++ b/src/linux/prlimit.c @@ -3,9 +3,24 @@  #include "syscall.h"  #include "libc.h" +#define FIX(x) do{ if ((x)>=SYSCALL_RLIM_INFINITY) (x)=RLIM_INFINITY; }while(0) +  int prlimit(pid_t pid, int resource, const struct rlimit *new_limit, struct rlimit *old_limit)  { -	return syscall(SYS_prlimit64, pid, resource, new_limit, old_limit); +	struct rlimit tmp; +	int r; +	if (new_limit && SYSCALL_RLIM_INFINITY != RLIM_INFINITY) { +		tmp = *new_limit; +		FIX(tmp.rlim_cur); +		FIX(tmp.rlim_max); +		new_limit = &tmp; +	} +	r = syscall(SYS_prlimit64, pid, resource, new_limit, old_limit); +	if (!r && old_limit && SYSCALL_RLIM_INFINITY != RLIM_INFINITY) { +		FIX(old_limit->rlim_cur); +		FIX(old_limit->rlim_max); +	} +	return r;  }  #undef prlimit64 diff --git a/src/misc/getrlimit.c b/src/misc/getrlimit.c index b7bbd062..b073677f 100644 --- a/src/misc/getrlimit.c +++ b/src/misc/getrlimit.c @@ -3,16 +3,24 @@  #include "syscall.h"  #include "libc.h" +#define FIX(x) do{ if ((x)>=SYSCALL_RLIM_INFINITY) (x)=RLIM_INFINITY; }while(0) +  int getrlimit(int resource, struct rlimit *rlim)  {  	unsigned long k_rlim[2];  	int ret = syscall(SYS_prlimit64, 0, resource, 0, rlim); +	if (!ret) { +		FIX(rlim->rlim_cur); +		FIX(rlim->rlim_max); +	}  	if (!ret || errno != ENOSYS)  		return ret;  	if (syscall(SYS_getrlimit, resource, k_rlim) < 0)  		return -1;  	rlim->rlim_cur = k_rlim[0] == -1UL ? RLIM_INFINITY : k_rlim[0];  	rlim->rlim_max = k_rlim[1] == -1UL ? RLIM_INFINITY : k_rlim[1]; +	FIX(rlim->rlim_cur); +	FIX(rlim->rlim_max);  	return 0;  } diff --git a/src/misc/setrlimit.c b/src/misc/setrlimit.c index ddc13e98..8a1b8cc6 100644 --- a/src/misc/setrlimit.c +++ b/src/misc/setrlimit.c @@ -4,14 +4,22 @@  #include "libc.h"  #define MIN(a, b) ((a)<(b) ? (a) : (b)) +#define FIX(x) do{ if ((x)>=SYSCALL_RLIM_INFINITY) (x)=RLIM_INFINITY; }while(0)  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, -1UL); -	k_rlim[1] = MIN(rlim->rlim_max, -1UL); +	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);  } | 
