From 9116dff92e5b362011431f073fe6aa98327be254 Mon Sep 17 00:00:00 2001 From: Eric Andersen Date: Sun, 31 Mar 2002 01:56:09 +0000 Subject: Add support for getrlimit64 and setrlimit64. Fix some problems with the getrlimit and setrlimit syscalls. -Erik --- libc/sysdeps/linux/common/Makefile | 3 +- libc/sysdeps/linux/common/getrlimit64.c | 57 +++++++++++++++++++++++++++++++++ libc/sysdeps/linux/common/setrlimit64.c | 56 ++++++++++++++++++++++++++++++++ libc/sysdeps/linux/common/statfs64.c | 50 +++++++++++++++++------------ libc/sysdeps/linux/common/syscalls.c | 56 ++++++++++++++++++++++++++++++-- 5 files changed, 199 insertions(+), 23 deletions(-) create mode 100644 libc/sysdeps/linux/common/getrlimit64.c create mode 100644 libc/sysdeps/linux/common/setrlimit64.c (limited to 'libc') diff --git a/libc/sysdeps/linux/common/Makefile b/libc/sysdeps/linux/common/Makefile index ba35ed22a..eb5d31323 100644 --- a/libc/sysdeps/linux/common/Makefile +++ b/libc/sysdeps/linux/common/Makefile @@ -32,7 +32,8 @@ endif CSRC= waitpid.c kernel_version.c statfix.c getdnnm.c gethstnm.c \ mkfifo.c setegid.c wait.c getpagesize.c seteuid.c \ wait3.c setpgrp.c getdtablesize.c create_module.c ptrace.c \ - cmsg_nxthdr.c open64.c statfix64.c statfs64.c longjmp.c + cmsg_nxthdr.c open64.c statfix64.c statfs64.c longjmp.c \ + getrlimit64.c setrlimit64.c ifneq ($(strip $(EXCLUDE_BRK)),true) CSRC+=sbrk.c endif diff --git a/libc/sysdeps/linux/common/getrlimit64.c b/libc/sysdeps/linux/common/getrlimit64.c new file mode 100644 index 000000000..daf496ee8 --- /dev/null +++ b/libc/sysdeps/linux/common/getrlimit64.c @@ -0,0 +1,57 @@ +/* Copyright (C) 1991, 1995, 1996, 1997, 1998 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 + +#if defined _FILE_OFFSET_BITS && _FILE_OFFSET_BITS != 64 +#undef _FILE_OFFSET_BITS +#define _FILE_OFFSET_BITS 64 +#endif +#ifndef __USE_FILE_OFFSET64 +# define __USE_FILE_OFFSET64 1 +#endif +#ifndef __USE_LARGEFILE64 +# define __USE_LARGEFILE64 1 +#endif + +#include +#include + +#if defined __UCLIBC_HAVE_LFS__ + +/* Put the soft and hard limits for RESOURCE in *RLIMITS. + Returns 0 if successful, -1 if not (and sets errno). */ +int getrlimit64 (__rlimit_resource_t resource, struct rlimit64 *rlimits) +{ + struct rlimit rlimits32; + + if (getrlimit (resource, &rlimits32) < 0) + return -1; + + if (rlimits32.rlim_cur == RLIM_INFINITY) + rlimits->rlim_cur = RLIM64_INFINITY; + else + rlimits->rlim_cur = rlimits32.rlim_cur; + if (rlimits32.rlim_max == RLIM_INFINITY) + rlimits->rlim_max = RLIM64_INFINITY; + else + rlimits->rlim_max = rlimits32.rlim_max; + + return 0; +} +#endif diff --git a/libc/sysdeps/linux/common/setrlimit64.c b/libc/sysdeps/linux/common/setrlimit64.c new file mode 100644 index 000000000..87d1157a8 --- /dev/null +++ b/libc/sysdeps/linux/common/setrlimit64.c @@ -0,0 +1,56 @@ +/* Copyright (C) 1991,1995,1996,1997,1998,2000 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 + +#if defined _FILE_OFFSET_BITS && _FILE_OFFSET_BITS != 64 +#undef _FILE_OFFSET_BITS +#define _FILE_OFFSET_BITS 64 +#endif +#ifndef __USE_FILE_OFFSET64 +# define __USE_FILE_OFFSET64 1 +#endif +#ifndef __USE_LARGEFILE64 +# define __USE_LARGEFILE64 1 +#endif + +#include +#include + +#if defined __UCLIBC_HAVE_LFS__ + +/* Set the soft and hard limits for RESOURCE to *RLIMITS. + Only the super-user can increase hard limits. + Return 0 if successful, -1 if not (and sets errno). */ +int setrlimit64 (__rlimit_resource_t resource, const struct rlimit64 *rlimits) +{ + struct rlimit rlimits32; + + if (rlimits->rlim_cur >= RLIM_INFINITY) + rlimits32.rlim_cur = RLIM_INFINITY; + else + rlimits32.rlim_cur = rlimits->rlim_cur; + if (rlimits->rlim_max >= RLIM_INFINITY) + rlimits32.rlim_max = RLIM_INFINITY; + else + rlimits32.rlim_max = rlimits->rlim_max; + + return setrlimit (resource, &rlimits32); +} +#endif diff --git a/libc/sysdeps/linux/common/statfs64.c b/libc/sysdeps/linux/common/statfs64.c index 2a0a930c4..7d5060914 100644 --- a/libc/sysdeps/linux/common/statfs64.c +++ b/libc/sysdeps/linux/common/statfs64.c @@ -19,34 +19,44 @@ #include -#ifdef __UCLIBC_HAVE_LFS__ -#define __USE_LARGEFILE64 +#if defined _FILE_OFFSET_BITS && _FILE_OFFSET_BITS != 64 +#undef _FILE_OFFSET_BITS +#define _FILE_OFFSET_BITS 64 +#endif +#ifndef __USE_FILE_OFFSET64 +# define __USE_FILE_OFFSET64 1 +#endif +#ifndef __USE_LARGEFILE64 +# define __USE_LARGEFILE64 1 +#endif -#include #include #include #include + +#if defined __UCLIBC_HAVE_LFS__ + /* Return information about the filesystem on which FILE resides. */ int statfs64 (const char *file, struct statfs64 *buf) { - struct statfs buf32; - - if (statfs (file, &buf32) < 0) - return -1; - - buf->f_type = buf32.f_type; - buf->f_bsize = buf32.f_bsize; - buf->f_blocks = buf32.f_blocks; - buf->f_bfree = buf32.f_bfree; - buf->f_bavail = buf32.f_bavail; - buf->f_files = buf32.f_files; - buf->f_ffree = buf32.f_ffree; - buf->f_fsid = buf32.f_fsid; - buf->f_namelen = buf32.f_namelen; - memcpy (buf->f_spare, buf32.f_spare, sizeof (buf32.f_spare)); - - return 0; + struct statfs buf32; + + if (statfs (file, &buf32) < 0) + return -1; + + buf->f_type = buf32.f_type; + buf->f_bsize = buf32.f_bsize; + buf->f_blocks = buf32.f_blocks; + buf->f_bfree = buf32.f_bfree; + buf->f_bavail = buf32.f_bavail; + buf->f_files = buf32.f_files; + buf->f_ffree = buf32.f_ffree; + buf->f_fsid = buf32.f_fsid; + buf->f_namelen = buf32.f_namelen; + memcpy (buf->f_spare, buf32.f_spare, sizeof (buf32.f_spare)); + + return 0; } #endif diff --git a/libc/sysdeps/linux/common/syscalls.c b/libc/sysdeps/linux/common/syscalls.c index 9c3453e8b..974cf5f70 100644 --- a/libc/sysdeps/linux/common/syscalls.c +++ b/libc/sysdeps/linux/common/syscalls.c @@ -566,18 +566,59 @@ _syscall2(int, sethostname, const char *, name, size_t, len); #endif //#define __NR_setrlimit 75 +#ifndef __NR_ugetrlimit +/* Only wrap setrlimit if the new ugetrlimit is not present */ +#ifdef L___setrlimit +#define __NR___setrlimit __NR_setrlimit +#include +#include +_syscall2(int, __setrlimit, int, resource, const struct rlimit *, rlim); +int setrlimit (enum __rlimit_resource resource, const struct rlimit *rlimits) +{ + struct rlimit rlimits_small; + /* We might have to correct the limits values. Since the old values + * were signed the new values might be too large. */ + rlimits_small.rlim_cur = MIN ((unsigned long int) rlimits->rlim_cur, + RLIM_INFINITY >> 1); + rlimits_small.rlim_max = MIN ((unsigned long int) rlimits->rlim_max, + RLIM_INFINITY >> 1); + return(__setrlimit(resource, &rlimits_small)); +} +#endif +#else /* We don't need to wrap setrlimit */ #ifdef L_setrlimit #include #include _syscall2(int, setrlimit, int, resource, const struct rlimit *, rlim); #endif +#endif /* __NR_setrlimit */ //#define __NR_getrlimit 76 -#ifdef L_getrlimit +#ifdef L___getrlimit +/* Only include the old getrlimit if the new one (ugetrlimit) is not around */ +#ifndef __NR_ugetrlimit +#define __NR___getrlimit __NR_getrlimit #include #include -_syscall2(int, getrlimit, int, resource, struct rlimit *, rlim); +_syscall2(int, __getrlimit, int, resource, struct rlimit *, rlim); +int getrlimit (enum __rlimit_resource resource, struct rlimit *rlim) +{ + int result; + result = __getrlimit(resource, rlim); + + if (result == -1) + return result; + + /* We might have to correct the limits values. Since the old values + * were signed the infinity value is too small. */ + if (rlimits->rlim_cur == RLIM_INFINITY >> 1) + rlimits->rlim_cur = RLIM_INFINITY; + if (rlimits->rlim_max == RLIM_INFINITY >> 1) + rlimits->rlim_max = RLIM_INFINITY; + return result; +} #endif +#endif /* __NR_getrlimit */ //#define __NR_getrusage 77 #ifdef L_getrusage @@ -1404,6 +1445,17 @@ _syscall4(ssize_t,sendfile, int, out_fd, int, in_fd, __off_t *, offset, size_t, //See sysdeps/linux/vfork.[cS] for architecture specific implementation... //#define __NR_ugetrlimit 191 /* SuS compliant getrlimit */ +#ifdef L___ugetrlimit +#define __NR___ugetrlimit __NR_ugetrlimit +#include +#include +_syscall2(int, __ugetrlimit, enum __rlimit_resource, resource, struct rlimit *, rlim); +int getrlimit (__rlimit_resource_t resource, struct rlimit *rlimits) +{ + return(__ugetrlimit(resource, rlimits)); +} +#endif + //#define __NR_mmap2 192 -- cgit v1.2.3