From c08fb0d7bba4015078406b28d3906ccc5fda9d5a Mon Sep 17 00:00:00 2001 From: Ulrich Drepper Date: Wed, 11 Aug 2010 11:18:52 -0700 Subject: [PATCH] Add support for prlimit and prlimit64 on Linux. --- ChangeLog | 16 ++++ NEWS | 2 + sysdeps/unix/sysv/linux/Makefile | 2 +- sysdeps/unix/sysv/linux/Versions | 3 + sysdeps/unix/sysv/linux/bits/resource.h | 30 ++++++- sysdeps/unix/sysv/linux/i386/syscalls.list | 2 + .../sysv/linux/powerpc/powerpc32/syscalls.list | 2 + sysdeps/unix/sysv/linux/prlimit.c | 92 ++++++++++++++++++++++ sysdeps/unix/sysv/linux/s390/s390-32/syscalls.list | 2 + sysdeps/unix/sysv/linux/sh/syscalls.list | 2 + .../unix/sysv/linux/sparc/sparc32/syscalls.list | 2 + sysdeps/unix/sysv/linux/wordsize-64/syscalls.list | 1 + 12 files changed, 154 insertions(+), 2 deletions(-) create mode 100644 sysdeps/unix/sysv/linux/prlimit.c diff --git a/ChangeLog b/ChangeLog index 96655d8..30b59e6 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,5 +1,21 @@ 2010-08-11 Ulrich Drepper + * sysdeps/unix/sysv/linux/Makefile [subdir=misc] (sysdep_routines): + Add prlimit. + * sysdeps/unix/sysv/linux/Versions [libc]: Export prlimit and + prlimit64 for GLIBC_2.13. + * sysdeps/unix/sysv/linux/bits/resource.h: Declare prlimit and + prlimit64. + * sysdeps/unix/sysv/linux/i386/syscalls.list: Add entry for prlimit64 + syscall. + * sysdeps/unix/sysv/linux/powerpc/powerpc32/syscalls.list: Likewise. + * sysdeps/unix/sysv/linux/s390/s390-32/syscalls.list: Likewise. + * sysdeps/unix/sysv/linux/sh/syscalls.list: Likewise. + * sysdeps/unix/sysv/linux/sparc/sparc32/syscalls.lis: Likewise. + * sysdeps/unix/sysv/linux/wordsize-64/syscalls.list: Likewise. Also + add prlimit alias. + * sysdeps/unix/sysv/linux/prlimit.c: New file. + [BZ #11903] * sysdeps/generic/netinet/ip.h (IPTOS_CLASS): Fix definition. Patch by Evgeni Bikov . diff --git a/NEWS b/NEWS index e51fba9..0e461c2 100644 --- a/NEWS +++ b/NEWS @@ -11,6 +11,8 @@ Version 2.13 11640, 11701, 11840, 11856, 11883, 11903 +* New Linux interfaces: prlimit, prlimit64 + * POWER7 optimizations: memset, memcmp, strncmp * New optimized string functions for x86-64: strnlen, strcasecmp diff --git a/sysdeps/unix/sysv/linux/Makefile b/sysdeps/unix/sysv/linux/Makefile index 9c53b2d..5ab6a4f 100644 --- a/sysdeps/unix/sysv/linux/Makefile +++ b/sysdeps/unix/sysv/linux/Makefile @@ -18,7 +18,7 @@ endif ifeq ($(subdir),misc) sysdep_routines += sysctl clone llseek umount umount2 readahead \ setfsuid setfsgid makedev epoll_pwait signalfd \ - eventfd eventfd_read eventfd_write + eventfd eventfd_read eventfd_write prlimit CFLAGS-gethostid.c = -fexceptions diff --git a/sysdeps/unix/sysv/linux/Versions b/sysdeps/unix/sysv/linux/Versions index f09ef6d..c662765 100644 --- a/sysdeps/unix/sysv/linux/Versions +++ b/sysdeps/unix/sysv/linux/Versions @@ -149,6 +149,9 @@ libc { recvmmsg; } + GLIBC_2.13 { + prlimit; prlimit64; + } GLIBC_PRIVATE { # functions used in other libraries __syscall_rt_sigqueueinfo; diff --git a/sysdeps/unix/sysv/linux/bits/resource.h b/sysdeps/unix/sysv/linux/bits/resource.h index cb3acf1..ca2c9f0 100644 --- a/sysdeps/unix/sysv/linux/bits/resource.h +++ b/sysdeps/unix/sysv/linux/bits/resource.h @@ -1,5 +1,5 @@ /* Bit values & structures for resource limits. Linux version. - Copyright (C) 1994, 1996, 1997, 1998, 1999, 2000, 2004, 2005, 2008, 2009 + Copyright (C) 1994, 1996-2000, 2004, 2005, 2008, 2009, 2010 Free Software Foundation, Inc. This file is part of the GNU C Library. @@ -232,3 +232,31 @@ enum __priority_which PRIO_USER = 2 /* WHO is a user ID. */ #define PRIO_USER PRIO_USER }; + + +__BEGIN_DECLS + +#ifdef __USE_GNU +/* Modify and return resource limits of a process atomically. */ +# ifndef __USE_FILE_OFFSET64 +extern int prlimit (__pid_t __pid, enum __rlimit_resource __resource, + __const struct rlimit *__new_limit, + struct rlimit *__old_limit) __THROW; +# else +# ifdef __REDIRECT_NTH +extern int __REDIRECT_NTH (prlimit, (__pid_t __pid, + enum __rlimit_resource __resource, + __const struct rlimit *__new_limit, + struct rlimit *__old_limit), prlimit64); +# else +# define prlimit prlimit64 +# endif +# endif +# ifdef __USE_LARGEFILE64 +extern int prlimit64 (__pid_t __pid, enum __rlimit_resource __resource, + __const struct rlimit64 *__new_limit, + struct rlimit64 *__old_limit) __THROW; +# endif +#endif + +__END_DECLS diff --git a/sysdeps/unix/sysv/linux/i386/syscalls.list b/sysdeps/unix/sysv/linux/i386/syscalls.list index 3ff3a73..597e598 100644 --- a/sysdeps/unix/sysv/linux/i386/syscalls.list +++ b/sysdeps/unix/sysv/linux/i386/syscalls.list @@ -6,3 +6,5 @@ vm86 - vm86 i:ip __vm86 vm86@@GLIBC_2.3.4 oldgetrlimit EXTRA getrlimit i:ip __old_getrlimit getrlimit@GLIBC_2.0 oldsetrlimit EXTRA setrlimit i:ip __old_setrlimit setrlimit@GLIBC_2.0 waitpid - waitpid Ci:ipi __waitpid waitpid __libc_waitpid + +prlimit64 EXTRA prlimit64 i:iipp prlimit64 diff --git a/sysdeps/unix/sysv/linux/powerpc/powerpc32/syscalls.list b/sysdeps/unix/sysv/linux/powerpc/powerpc32/syscalls.list index 1233be6..3012285 100644 --- a/sysdeps/unix/sysv/linux/powerpc/powerpc32/syscalls.list +++ b/sysdeps/unix/sysv/linux/powerpc/powerpc32/syscalls.list @@ -6,3 +6,5 @@ oldsetrlimit EXTRA setrlimit i:ip __old_setrlimit setrlimit@GLIBC_2.0 # Due to 64bit alignment there is a dummy second parameter readahead - readahead i:iiiii __readahead readahead + +prlimit64 EXTRA prlimit64 i:iipp prlimit64 diff --git a/sysdeps/unix/sysv/linux/prlimit.c b/sysdeps/unix/sysv/linux/prlimit.c new file mode 100644 index 0000000..6d61e9a --- /dev/null +++ b/sysdeps/unix/sysv/linux/prlimit.c @@ -0,0 +1,92 @@ +/* Copyright (C) 2010 Free Software Foundation, Inc. + This file is part of the GNU C Library. + + The GNU C Library is free software; you can redistribute it and/or + modify it under the terms of the GNU Lesser General Public + License as published by the Free Software Foundation; either + version 2.1 of the License, or (at your option) any later version. + + The GNU C Library is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + Lesser General Public License for more details. + + You should have received a copy of the GNU Lesser General Public + License along with the GNU C Library; if not, write to the Free + Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA + 02111-1307 USA. */ + +#include +#include +#include + + +#ifdef __NR_prlimit64 +int +prlimit (__pid_t pid, enum __rlimit_resource resource, + __const struct rlimit *new_limit, struct rlimit *old_limit) +{ + struct rlimit64 new_rlimit64_mem; + struct rlimit64 *new_rlimit64 = NULL; + struct rlimit64 old_rlimit64_mem; + struct rlimit64 *old_rlimit64 = (old_rlimiit != NULL + ? &old_rlimit64_mem : NULL); + + if (new_rlimit != NULL) + { + if (new_rlimit->rlim_cur == RLIM_INFINITY) + new_rlimit64_mem.rlim_cur = RLIM64_INFINITY; + else + new_rlimit64_mem.rlim_cur = new_rlimit->rlim_cur; + if (new_rlimit->rlim_max == RLIM_INFINITY) + new_rlimit64_mem.rlim_max = = RLIM64_INFINITY; + else + new_rlimit64_mem.rlim_max = new_rlimit->rlim_max; + new_rlimit64 = &new_rlimit64_mem; + } + + int res = INLINE_SYSCALL (prlimit64, 4, pid, resource, new_rlimit64, + old_rlimit64); + + if (res == 0 && old_limit != NULL) + { + /* The prlimit64 syscall is ill-designed for 32-bit machines. + We have to provide a 32-bit variant since otherwise the LFS + system would not work. But what shall we do if the syscall + succeeds but the old values do not fit into a rlimit + structure? We cannot return an error because the operation + itself worked. Best is perhaps to return RLIM_INFINITY. */ + old_rlimit->rlim_cur = old_rlimit64_mem.rlim_cur; + if (old_rlimit->rlim_cur != old_rlimit64_mem.rlim_cur) + { + if (new_limit == NULL) + { + __set_errno (EOVERFLOW); + return -1; + } + old_rlimit->rlim_cur = RLIM_INFINITY; + } + old_rlimit->rlim_max = old_rlimit64_mem.rlim_max; + if (old_rlimit->rlim_max != old_rlimit64_mem.rlim_max) + { + if (new_limit == NULL) + { + __set_errno (EOVERFLOW); + return -1; + } + old_rlimit->rlim_max = RLIM_INFINITY; + } + } + + return res; +} +#else +int +prlimit (__pid_t pid, enum __rlimit_resource resource, + __const struct rlimit *new_limit, struct rlimit *old_limit) +{ + __set_errno (ENOSYS); + return -1; +} +stub_warning (prlimit) +#endif diff --git a/sysdeps/unix/sysv/linux/s390/s390-32/syscalls.list b/sysdeps/unix/sysv/linux/s390/s390-32/syscalls.list index 0e76857..d3a05d2 100644 --- a/sysdeps/unix/sysv/linux/s390/s390-32/syscalls.list +++ b/sysdeps/unix/sysv/linux/s390/s390-32/syscalls.list @@ -3,3 +3,5 @@ oldgetrlimit EXTRA getrlimit i:ip __old_getrlimit getrlimit@GLIBC_2.0 oldsetrlimit EXTRA setrlimit i:ip __old_setrlimit setrlimit@GLIBC_2.0 vfork - vfork 0 __vfork vfork + +prlimit64 EXTRA prlimit64 i:iipp prlimit64 diff --git a/sysdeps/unix/sysv/linux/sh/syscalls.list b/sysdeps/unix/sysv/linux/sh/syscalls.list index a666593..be9ffed 100644 --- a/sysdeps/unix/sysv/linux/sh/syscalls.list +++ b/sysdeps/unix/sysv/linux/sh/syscalls.list @@ -1,3 +1,5 @@ # File name Caller Syscall name # args Strong name Weak names waitpid - waitpid Ci:ipi __waitpid waitpid __libc_waitpid + +prlimit64 EXTRA prlimit64 i:iipp prlimit64 diff --git a/sysdeps/unix/sysv/linux/sparc/sparc32/syscalls.list b/sysdeps/unix/sysv/linux/sparc/sparc32/syscalls.list index 2bfe376..8b1d682 100644 --- a/sysdeps/unix/sysv/linux/sparc/sparc32/syscalls.list +++ b/sysdeps/unix/sysv/linux/sparc/sparc32/syscalls.list @@ -4,3 +4,5 @@ setrlimit - setrlimit 2 __setrlimit setrlimit getrlimit - getrlimit 2 __getrlimit getrlimit getresuid - getresuid32 3 getresuid getresgid - getresgid32 3 getresgid + +prlimit64 EXTRA prlimit64 i:iipp prlimit64 diff --git a/sysdeps/unix/sysv/linux/wordsize-64/syscalls.list b/sysdeps/unix/sysv/linux/wordsize-64/syscalls.list index 6091550..b2e2163 100644 --- a/sysdeps/unix/sysv/linux/wordsize-64/syscalls.list +++ b/sysdeps/unix/sysv/linux/wordsize-64/syscalls.list @@ -17,3 +17,4 @@ sendfile - sendfile i:iipi sendfile sendfile64 sync_file_range - sync_file_range i:iiii sync_file_range creat - creat Ci:si __libc_creat creat creat64 open - open Ci:siv __libc_open __open open __open64 open64 +prlimit EXTRA prlimit64 i:iipp prlimit prlimit64 -- 2.7.4