diff mbox series

[uclibc-ng-devel,3/4] add support for systems without legacy setrlimit/getrlimit syscalls

Message ID 20230914142941.25389-3-yann@sionneau.net
State Accepted
Headers show
Series [uclibc-ng-devel,1/4] fstatat64: define it as a wrapper of statx if the kernel does not support fstatat64 syscall | expand

Commit Message

Yann Sionneau Sept. 14, 2023, 2:29 p.m. UTC
From: Yann Sionneau <ysionneau@kalray.eu>

Those must have the recent prlimit64 syscall which exists since
Linux 3.2.

This patch is necessary for non-legacy architectures that wish to remove
support for legacy setrlimit/getrlimit syscalls.

The non-legacy arch are those who opt-out via non defining
__ARCH_WANT_SET_GET_RLIMIT in their arch/xxx/include/uapi/asm/unistd.h

setrlimit and getrlimit are then emulated via the new prlimit64 syscall.

Signed-off-by: Yann Sionneau <ysionneau@kalray.eu>

---
 libc/sysdeps/linux/common/getrlimit.c | 23 +++++++++++++++----
 libc/sysdeps/linux/common/setrlimit.c | 32 +++++++++++++++++++--------
 2 files changed, 42 insertions(+), 13 deletions(-)
diff mbox series

Patch

diff --git a/libc/sysdeps/linux/common/getrlimit.c b/libc/sysdeps/linux/common/getrlimit.c
index 26d3d2946..ad3f4a0e4 100644
--- a/libc/sysdeps/linux/common/getrlimit.c
+++ b/libc/sysdeps/linux/common/getrlimit.c
@@ -9,10 +9,11 @@ 
 #include <sys/syscall.h>
 #include <sys/resource.h>
 #include <bits/wordsize.h>
+#include <stddef.h> // needed for NULL to be defined
 
 /* Only wrap getrlimit if the new ugetrlimit is not present and getrlimit sucks */
 
-#if defined __NR_ugetrlimit
+#if defined(__NR_ugetrlimit)
 
 /* just call ugetrlimit() */
 # define __NR___syscall_ugetrlimit __NR_ugetrlimit
@@ -24,16 +25,25 @@  int getrlimit(__rlimit_resource_t resource, struct rlimit *rlimits)
 	return __syscall_ugetrlimit(resource, rlimits);
 }
 
-#elif !defined(__UCLIBC_HANDLE_OLDER_RLIMIT__)
+#else
+
+# if !defined(__UCLIBC_HANDLE_OLDER_RLIMIT__)
 
+#  if defined(__NR_prlimit64)
+int getrlimit(__rlimit_resource_t resource, struct rlimit *rlimits)
+{
+	return INLINE_SYSCALL (prlimit64, 4, 0, resource, NULL, rlimits);
+}
+#  else
 /* We don't need to wrap getrlimit() */
 _syscall2(int, getrlimit, __rlimit_resource_t, resource,
 	  struct rlimit *, rlim)
+#  endif
 
-#else
+# else
 
 /* we have to handle old style getrlimit() */
-# define __NR___syscall_getrlimit __NR_getrlimit
+#  define __NR___syscall_getrlimit __NR_getrlimit
 static __always_inline
 _syscall2(int, __syscall_getrlimit, int, resource, struct rlimit *, rlim)
 
@@ -41,7 +51,11 @@  int getrlimit(__rlimit_resource_t resource, struct rlimit *rlimits)
 {
 	int result;
 
+#  if defined(__NR_prlimit64)
+	result = INLINE_SYSCALL (prlimit64, 4, 0, resource, NULL, rlimits);
+#  else
 	result = __syscall_getrlimit(resource, rlimits);
+#  endif
 
 	if (result == -1)
 		return result;
@@ -54,6 +68,7 @@  int getrlimit(__rlimit_resource_t resource, struct rlimit *rlimits)
 		rlimits->rlim_max = RLIM_INFINITY;
 	return result;
 }
+# endif
 #endif
 libc_hidden_def(getrlimit)
 
diff --git a/libc/sysdeps/linux/common/setrlimit.c b/libc/sysdeps/linux/common/setrlimit.c
index 8f4973b72..8381afc61 100644
--- a/libc/sysdeps/linux/common/setrlimit.c
+++ b/libc/sysdeps/linux/common/setrlimit.c
@@ -9,36 +9,45 @@ 
 #include <sys/syscall.h>
 #include <sys/resource.h>
 #include <bits/wordsize.h>
+#include <stddef.h> // needed for NULL to be defined
 
 /* Only wrap setrlimit if the new usetrlimit is not present and setrlimit sucks */
 
 #if defined(__NR_usetrlimit)
-
 /* just call usetrlimit() */
 # define __NR___syscall_usetrlimit __NR_usetrlimit
 static __always_inline
 _syscall2(int, __syscall_usetrlimit, enum __rlimit_resource, resource,
           const struct rlimit *, rlim)
-int setrlimit(__rlimit_resource_t resource, struct rlimit *rlimits)
+int setrlimit(__rlimit_resource_t resource, const struct rlimit *rlimits)
 {
 	return __syscall_usetrlimit(resource, rlimits);
 }
 
-#elif !defined(__UCLIBC_HANDLE_OLDER_RLIMIT__)
+#else
+
+# if !defined(__UCLIBC_HANDLE_OLDER_RLIMIT__)
 
+#  if defined(__NR_prlimit64)
+int setrlimit(__rlimit_resource_t resource, const struct rlimit *rlimits)
+{
+	return INLINE_SYSCALL (prlimit64, 4, 0, resource, rlimits, NULL);
+}
+#  else
 /* We don't need to wrap setrlimit() */
 _syscall2(int, setrlimit, __rlimit_resource_t, resource,
 		const struct rlimit *, rlim)
+#  endif
 
-#else
+# else
 
-# define __need_NULL
-# include <stddef.h>
-# include <errno.h>
-# include <sys/param.h>
+#  define __need_NULL
+#  include <stddef.h>
+#  include <errno.h>
+#  include <sys/param.h>
 
 /* we have to handle old style setrlimit() */
-# define __NR___syscall_setrlimit __NR_setrlimit
+#  define __NR___syscall_setrlimit __NR_setrlimit
 static __always_inline
 _syscall2(int, __syscall_setrlimit, int, resource, const struct rlimit *, rlim)
 
@@ -57,8 +66,13 @@  int setrlimit(__rlimit_resource_t resource, const struct rlimit *rlimits)
 								  RLIM_INFINITY >> 1);
 	rlimits_small.rlim_max = MIN((unsigned long int) rlimits->rlim_max,
 								  RLIM_INFINITY >> 1);
+#  if defined(__NR_prlimit64)
+	return INLINE_SYSCALL (prlimit64, 4, 0, resource, &rlimits_small, NULL);
+#  else
 	return __syscall_setrlimit(resource, &rlimits_small);
+#  endif
 }
+# endif
 #endif
 libc_hidden_def(setrlimit)