Merge "Fix <sys/resource.h>."

This commit is contained in:
Elliott Hughes 2014-01-09 19:01:14 +00:00 committed by Gerrit Code Review
commit c65cbf97d9
19 changed files with 264 additions and 21 deletions

View file

@ -62,12 +62,21 @@ int tkill(pid_t tid, int sig) all
int tgkill(pid_t tgid, pid_t tid, int sig) all
int __ptrace:ptrace(int request, int pid, void* addr, void* data) all
int __set_thread_area:set_thread_area(void* user_desc) mips,x86
int __getpriority:getpriority(int, int) all
int setpriority(int, int, int) all
int setrlimit(int resource, const struct rlimit* rlp) all
int getrlimit:ugetrlimit(int resource, struct rlimit* rlp) arm,x86
int getrlimit:getrlimit(int resource, struct rlimit* rlp) aarch64,mips,x86_64
int getrusage(int who, struct rusage* r_usage) all
# <sys/resource.h>
int getrusage(int, struct rusage*) all
int __getpriority:getpriority(int, int) all
int setpriority(int, int, int) all
# On LP64, rlimit and rlimit64 are the same.
# On 32-bit systems we use prlimit64 to implement the rlimit64 functions.
int getrlimit:ugetrlimit(int, struct rlimit*) arm,x86
int getrlimit(int, struct rlimit*) mips
int getrlimit|getrlimit64(int, struct rlimit*) aarch64,x86_64
int setrlimit(int, const struct rlimit*) arm,mips,x86
int setrlimit|setrlimit64(int, const struct rlimit*) aarch64,x86_64
int prlimit64|prlimit(pid_t, int, struct rlimit64*, const struct rlimit64*) aarch64,x86_64
int prlimit64(pid_t, int, struct rlimit64*, const struct rlimit64*) arm,mips,x86
int setgroups:setgroups32(int, const gid_t*) arm,x86
int setgroups:setgroups(int, const gid_t*) aarch64,mips,x86_64
int setpgid(pid_t, pid_t) all

View file

@ -123,6 +123,7 @@ syscall_src += arch-aarch64/syscalls/personality.S
syscall_src += arch-aarch64/syscalls/pipe2.S
syscall_src += arch-aarch64/syscalls/prctl.S
syscall_src += arch-aarch64/syscalls/pread64.S
syscall_src += arch-aarch64/syscalls/prlimit64.S
syscall_src += arch-aarch64/syscalls/pwrite64.S
syscall_src += arch-aarch64/syscalls/read.S
syscall_src += arch-aarch64/syscalls/readahead.S

View file

@ -19,3 +19,6 @@ ENTRY(getrlimit)
ret
END(getrlimit)
.globl _C_LABEL(getrlimit64)
.equ _C_LABEL(getrlimit64), _C_LABEL(getrlimit)

View file

@ -0,0 +1,24 @@
/* Generated by gensyscalls.py. Do not edit. */
#include <private/bionic_asm.h>
ENTRY(prlimit64)
stp x29, x30, [sp, #-16]!
mov x29, sp
str x8, [sp, #-16]!
mov x8, __NR_prlimit64
svc #0
ldr x8, [sp], #16
ldp x29, x30, [sp], #16
cmn x0, #(MAX_ERRNO + 1)
cneg x0, x0, hi
b.hi __set_errno
ret
END(prlimit64)
.globl _C_LABEL(prlimit)
.equ _C_LABEL(prlimit), _C_LABEL(prlimit64)

View file

@ -19,3 +19,6 @@ ENTRY(setrlimit)
ret
END(setrlimit)
.globl _C_LABEL(setrlimit64)
.equ _C_LABEL(setrlimit64), _C_LABEL(setrlimit)

View file

@ -129,6 +129,7 @@ syscall_src += arch-arm/syscalls/personality.S
syscall_src += arch-arm/syscalls/pipe2.S
syscall_src += arch-arm/syscalls/prctl.S
syscall_src += arch-arm/syscalls/pread64.S
syscall_src += arch-arm/syscalls/prlimit64.S
syscall_src += arch-arm/syscalls/pwrite64.S
syscall_src += arch-arm/syscalls/read.S
syscall_src += arch-arm/syscalls/readahead.S

View file

@ -0,0 +1,14 @@
/* Generated by gensyscalls.py. Do not edit. */
#include <private/bionic_asm.h>
ENTRY(prlimit64)
mov ip, r7
ldr r7, =__NR_prlimit64
swi #0
mov r7, ip
cmn r0, #(MAX_ERRNO + 1)
bxls lr
neg r0, r0
b __set_errno
END(prlimit64)

View file

@ -129,6 +129,7 @@ syscall_src += arch-mips/syscalls/personality.S
syscall_src += arch-mips/syscalls/pipe2.S
syscall_src += arch-mips/syscalls/prctl.S
syscall_src += arch-mips/syscalls/pread64.S
syscall_src += arch-mips/syscalls/prlimit64.S
syscall_src += arch-mips/syscalls/pwrite64.S
syscall_src += arch-mips/syscalls/read.S
syscall_src += arch-mips/syscalls/readahead.S

View file

@ -0,0 +1,23 @@
/* Generated by gensyscalls.py. Do not edit. */
#include <asm/unistd.h>
.text
.globl prlimit64
.align 4
.ent prlimit64
prlimit64:
.set noreorder
.cpload $t9
li $v0, __NR_prlimit64
syscall
bnez $a3, 1f
move $a0, $v0
j $ra
nop
1:
la $t9,__set_errno
j $t9
nop
.set reorder
.end prlimit64

View file

@ -128,6 +128,7 @@ syscall_src += arch-x86/syscalls/personality.S
syscall_src += arch-x86/syscalls/pipe2.S
syscall_src += arch-x86/syscalls/prctl.S
syscall_src += arch-x86/syscalls/pread64.S
syscall_src += arch-x86/syscalls/prlimit64.S
syscall_src += arch-x86/syscalls/pwrite64.S
syscall_src += arch-x86/syscalls/read.S
syscall_src += arch-x86/syscalls/readahead.S

View file

@ -0,0 +1,34 @@
/* Generated by gensyscalls.py. Do not edit. */
#include <private/bionic_asm.h>
ENTRY(prlimit64)
pushl %ebx
pushl %ecx
pushl %edx
pushl %esi
.cfi_def_cfa_offset 16
.cfi_rel_offset ebx, 0
.cfi_rel_offset ecx, 4
.cfi_rel_offset edx, 8
.cfi_rel_offset esi, 12
mov 20(%esp), %ebx
mov 24(%esp), %ecx
mov 28(%esp), %edx
mov 32(%esp), %esi
movl $__NR_prlimit64, %eax
int $0x80
cmpl $-MAX_ERRNO, %eax
jb 1f
negl %eax
pushl %eax
call __set_errno
addl $4, %esp
orl $-1, %eax
1:
popl %esi
popl %edx
popl %ecx
popl %ebx
ret
END(prlimit64)

View file

@ -124,6 +124,7 @@ syscall_src += arch-x86_64/syscalls/personality.S
syscall_src += arch-x86_64/syscalls/pipe2.S
syscall_src += arch-x86_64/syscalls/prctl.S
syscall_src += arch-x86_64/syscalls/pread64.S
syscall_src += arch-x86_64/syscalls/prlimit64.S
syscall_src += arch-x86_64/syscalls/pwrite64.S
syscall_src += arch-x86_64/syscalls/read.S
syscall_src += arch-x86_64/syscalls/readahead.S

View file

@ -14,3 +14,6 @@ ENTRY(getrlimit)
1:
ret
END(getrlimit)
.globl _C_LABEL(getrlimit64)
.equ _C_LABEL(getrlimit64), _C_LABEL(getrlimit)

View file

@ -0,0 +1,20 @@
/* Generated by gensyscalls.py. Do not edit. */
#include <private/bionic_asm.h>
ENTRY(prlimit64)
movq %rcx, %r10
movl $__NR_prlimit64, %eax
syscall
cmpq $-MAX_ERRNO, %rax
jb 1f
negl %eax
movl %eax, %edi
call __set_errno
orq $-1, %rax
1:
ret
END(prlimit64)
.globl _C_LABEL(prlimit)
.equ _C_LABEL(prlimit), _C_LABEL(prlimit64)

View file

@ -14,3 +14,6 @@ ENTRY(setrlimit)
1:
ret
END(setrlimit)
.globl _C_LABEL(setrlimit64)
.equ _C_LABEL(setrlimit64), _C_LABEL(setrlimit)

View file

@ -28,10 +28,9 @@
#include <errno.h>
#include <stdarg.h>
#include <sys/resource.h>
#include <sys/types.h>
#include <sys/vfs.h>
#include <sys/vfs.h>
#include <unistd.h>
#include <unistd.h>
#if __LP64__
@ -86,3 +85,13 @@ ssize_t pread(int fd, void* buf, size_t byte_count, off_t offset) {
ssize_t pwrite(int fd, const void* buf, size_t byte_count, off_t offset) {
return pwrite64(fd, buf, byte_count, static_cast<off64_t>(offset));
}
// There is no getrlimit64 system call, so we need to use prlimit64.
int getrlimit64(int resource, rlimit64* limits64) {
return prlimit64(0, resource, NULL, limits64);
}
// There is no setrlimit64 system call, so we need to use prlimit64.
int setrlimit64(int resource, const rlimit64* limits64) {
return prlimit64(0, resource, limits64, NULL);
}

View file

@ -25,30 +25,35 @@
* OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
* SUCH DAMAGE.
*/
#ifndef _SYS_RESOURCE_H_
#define _SYS_RESOURCE_H_
#include <sys/cdefs.h>
#include <sys/types.h> /* MUST be included before linux/resource.h */
#include <sys/types.h>
/* TRICK AHEAD: <linux/resource.h> defines a getrusage function with
* a non-standard signature. this is surprising because the
* syscall seems to use the standard one instead.
* once again, creative macro usage saves the days
*/
#define getrusage __kernel_getrusage
#include <linux/resource.h>
#undef getrusage
typedef unsigned long rlim_t;
__BEGIN_DECLS
typedef unsigned long rlim_t;
extern int getrlimit(int, struct rlimit*);
extern int setrlimit(int, const struct rlimit*);
extern int getrlimit64(int, struct rlimit64*);
extern int setrlimit64(int, const struct rlimit64*);
extern int getpriority(int, int);
extern int setpriority(int, int, int);
extern int getrlimit(int resource, struct rlimit *rlp);
extern int setrlimit(int resource, const struct rlimit *rlp);
extern int getrusage(int who, struct rusage* r_usage);
extern int getrusage(int, struct rusage*);
#if __LP64__
/* Implementing prlimit for 32-bit isn't worth the effort. */
extern int prlimit(pid_t, int, const struct rlimit*, struct rlimit*);
#endif
extern int prlimit64(pid_t, int, const struct rlimit64*, struct rlimit64*);
__END_DECLS

View file

@ -61,6 +61,7 @@ test_src_files = \
strings_test.cpp \
stubs_test.cpp \
sys_epoll_test.cpp \
sys_resource_test.cpp \
sys_select_test.cpp \
sys_sendfile_test.cpp \
sys_stat_test.cpp \

View file

@ -0,0 +1,87 @@
/*
* Copyright (C) 2014 The Android Open Source Project
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
#include <gtest/gtest.h>
#include <sys/resource.h>
#if __GLIBC__
/* The host glibc we're currently building with doesn't have prlimit64 yet. */
static int prlimit64(pid_t, int resource, const struct rlimit64* new_limit, struct rlimit64* old_limit) {
if (new_limit != NULL) {
return setrlimit64(resource, new_limit);
} else {
return getrlimit64(resource, old_limit);
}
}
#endif
TEST(sys_resource, smoke) {
#if __LP64__ || __GLIBC__
ASSERT_EQ(sizeof(rlimit), sizeof(rlimit64));
ASSERT_EQ(8U, sizeof(rlim_t));
#else
ASSERT_NE(sizeof(rlimit), sizeof(rlimit64));
ASSERT_EQ(4U, sizeof(rlim_t));
#endif
// Read with getrlimit, getrlimit64, and prlimit64.
// (prlimit is prlimit64 on LP64 and unimplemented on 32-bit.)
rlimit l32;
rlimit64 l64;
rlimit64 pr_l64;
ASSERT_EQ(0, getrlimit(RLIMIT_CORE, &l32));
ASSERT_EQ(0, getrlimit64(RLIMIT_CORE, &l64));
ASSERT_EQ(0, prlimit64(0, RLIMIT_CORE, NULL, &pr_l64));
ASSERT_EQ(l64.rlim_cur, l32.rlim_cur);
ASSERT_EQ(l64.rlim_cur, pr_l64.rlim_cur);
ASSERT_EQ(l64.rlim_max, pr_l64.rlim_max);
if (l64.rlim_max == RLIM64_INFINITY) {
ASSERT_EQ(RLIM_INFINITY, l32.rlim_max);
} else {
ASSERT_EQ(l64.rlim_max, l32.rlim_max);
}
// Write with setrlimit and read back with everything.
l32.rlim_cur = 123;
ASSERT_EQ(0, setrlimit(RLIMIT_CORE, &l32));
ASSERT_EQ(0, getrlimit(RLIMIT_CORE, &l32));
ASSERT_EQ(0, getrlimit64(RLIMIT_CORE, &l64));
ASSERT_EQ(0, prlimit64(0, RLIMIT_CORE, NULL, &pr_l64));
ASSERT_EQ(123U, l32.rlim_cur);
ASSERT_EQ(l64.rlim_cur, l32.rlim_cur);
ASSERT_EQ(l64.rlim_cur, pr_l64.rlim_cur);
// Write with setrlimit64 and read back with everything.
l64.rlim_cur = 456;
ASSERT_EQ(0, setrlimit64(RLIMIT_CORE, &l64));
ASSERT_EQ(0, getrlimit(RLIMIT_CORE, &l32));
ASSERT_EQ(0, getrlimit64(RLIMIT_CORE, &l64));
ASSERT_EQ(0, prlimit64(0, RLIMIT_CORE, NULL, &pr_l64));
ASSERT_EQ(456U, l32.rlim_cur);
ASSERT_EQ(l64.rlim_cur, l32.rlim_cur);
ASSERT_EQ(l64.rlim_cur, pr_l64.rlim_cur);
// Write with prlimit64 and read back with everything.
l64.rlim_cur = 789;
ASSERT_EQ(0, prlimit64(0, RLIMIT_CORE, &l64, NULL));
ASSERT_EQ(0, getrlimit(RLIMIT_CORE, &l32));
ASSERT_EQ(0, getrlimit64(RLIMIT_CORE, &l64));
ASSERT_EQ(0, prlimit64(0, RLIMIT_CORE, NULL, &pr_l64));
ASSERT_EQ(789U, l32.rlim_cur);
ASSERT_EQ(l64.rlim_cur, l32.rlim_cur);
ASSERT_EQ(l64.rlim_cur, pr_l64.rlim_cur);
}