forked from OSchip/llvm-project
[libc] Add implementation of POSIX setrlimit and getrlimit functions.
Reviewed By: lntue Differential Revision: https://reviews.llvm.org/D134016
This commit is contained in:
parent
c2cf93c1a9
commit
f5cbbb9988
|
@ -271,6 +271,10 @@ def UniStdAPI : PublicAPI<"unistd.h"> {
|
|||
let Types = ["off_t", "size_t", "ssize_t"];
|
||||
}
|
||||
|
||||
def SysResourceAPI : PublicAPI<"sys/resource.h"> {
|
||||
let Types = ["rlim_t", "struct rlimit_t"];
|
||||
}
|
||||
|
||||
def SysStatAPI : PublicAPI<"sys/stat.h"> {
|
||||
let Types = ["mode_t"];
|
||||
}
|
||||
|
|
|
@ -101,6 +101,10 @@ set(TARGET_LIBC_ENTRYPOINTS
|
|||
libc.src.sys.mman.mmap
|
||||
libc.src.sys.mman.munmap
|
||||
|
||||
# sys/resource.h entrypoints
|
||||
libc.src.sys.resource.getrlimit
|
||||
libc.src.sys.resource.setrlimit
|
||||
|
||||
# sys/sendfile entrypoints
|
||||
libc.src.sys.sendfile.sendfile
|
||||
|
||||
|
|
|
@ -203,6 +203,17 @@ add_gen_header(
|
|||
.llvm-libc-types.ssize_t
|
||||
)
|
||||
|
||||
add_gen_header(
|
||||
sys_resource
|
||||
DEF_FILE sys/resource.h.def
|
||||
GEN_HDR sys/resource.h
|
||||
DEPENDS
|
||||
.llvm_libc_common_h
|
||||
.llvm-libc-macros.sys_resource_macros
|
||||
.llvm-libc-types.rlim_t
|
||||
.llvm-libc-types.struct_rlimit_t
|
||||
)
|
||||
|
||||
add_gen_header(
|
||||
sys_stat
|
||||
DEF_FILE sys/stat.h.def
|
||||
|
|
|
@ -22,6 +22,14 @@ add_header(
|
|||
.linux.sys_stat_macros
|
||||
)
|
||||
|
||||
add_header(
|
||||
sys_resource_macros
|
||||
HDR
|
||||
sys-resource-macros.h
|
||||
DEPENDS
|
||||
.linux.sys_resource_macros
|
||||
)
|
||||
|
||||
add_header(
|
||||
unistd_macros
|
||||
HDR
|
||||
|
|
|
@ -10,6 +10,12 @@ add_header(
|
|||
sys-stat-macros.h
|
||||
)
|
||||
|
||||
add_header(
|
||||
sys_resource_macros
|
||||
HDR
|
||||
sys-resource-macros.h
|
||||
)
|
||||
|
||||
add_header(
|
||||
unistd_macros
|
||||
HDR
|
||||
|
|
|
@ -0,0 +1,26 @@
|
|||
//===-- Macros defined in sys/resource.h header file ----------------------===//
|
||||
//
|
||||
// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
|
||||
// See https://llvm.org/LICENSE.txt for license information.
|
||||
// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
|
||||
//
|
||||
//===----------------------------------------------------------------------===//
|
||||
|
||||
#define RLIMIT_CPU 0
|
||||
#define RLIMIT_FSIZE 1
|
||||
#define RLIMIT_DATA 2
|
||||
#define RLIMIT_STACK 3
|
||||
#define RLIMIT_CORE 4
|
||||
#define RLIMIT_RSS 5
|
||||
#define RLIMIT_NPROC 6
|
||||
#define RLIMIT_NOFILE 7
|
||||
#define RLIMIT_MEMLOCK 8
|
||||
#define RLIMIT_AS 9
|
||||
#define RLIMIT_LOCKS 10
|
||||
#define RLIMIT_SIGPENDING 11
|
||||
#define RLIMIT_MSGQUEUE 12
|
||||
#define RLIMIT_NICE 13
|
||||
#define RLIMIT_RTPRIO 14
|
||||
#define RLIMIT_RTTIME 15
|
||||
|
||||
#define RLIM_INFINITY (~0UL)
|
|
@ -0,0 +1,16 @@
|
|||
//===-- Macros defined in sys/resource.h header file ----------------------===//
|
||||
//
|
||||
// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
|
||||
// See https://llvm.org/LICENSE.txt for license information.
|
||||
// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
|
||||
//
|
||||
//===----------------------------------------------------------------------===//
|
||||
|
||||
#ifndef __LLVM_LIBC_MACROS_SYS_RESOURCE_MACROS_H
|
||||
#define __LLVM_LIBC_MACROS_SYS_RESOURCE_MACROS_H
|
||||
|
||||
#ifdef __unix__
|
||||
#include "linux/sys-resource-macros.h"
|
||||
#endif
|
||||
|
||||
#endif // __LLVM_LIBC_MACROS_SYS_RESOURCE_MACROS_H
|
|
@ -31,6 +31,8 @@ add_header(pthread_key_t HDR pthread_key_t.h)
|
|||
add_header(pthread_mutex_t HDR pthread_mutex_t.h DEPENDS .__futex_word .__mutex_type)
|
||||
add_header(pthread_t HDR pthread_t.h DEPENDS .__thread_type)
|
||||
add_header(pthread_mutexattr_t HDR pthread_mutexattr_t.h)
|
||||
add_header(rlim_t HDR rlim_t.h)
|
||||
add_header(struct_rlimit_t HDR struct_rlimit_t.h DEPENDS .rlim_t)
|
||||
add_header(ssize_t HDR ssize_t.h)
|
||||
add_header(struct_dirent HDR struct_dirent.h DEPENDS .ino_t .off_t)
|
||||
add_header(struct_sigaction HDR struct_sigaction.h)
|
||||
|
|
|
@ -0,0 +1,14 @@
|
|||
//===-- Definition of type rlim_t -----------------------------------------===//
|
||||
//
|
||||
// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
|
||||
// See https://llvm.org/LICENSE.txt for license information.
|
||||
// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
|
||||
//
|
||||
//===----------------------------------------------------------------------===//
|
||||
|
||||
#ifndef __LLVM_LIBC_TYPES_RLIM_T_H__
|
||||
#define __LLVM_LIBC_TYPES_RLIM_T_H__
|
||||
|
||||
typedef unsigned long rlim_t;
|
||||
|
||||
#endif // __LLVM_LIBC_TYPES_RLIM_T_H__
|
|
@ -0,0 +1,19 @@
|
|||
//===-- Definition of type rlimit_t ---------------------------------------===//
|
||||
//
|
||||
// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
|
||||
// See https://llvm.org/LICENSE.txt for license information.
|
||||
// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
|
||||
//
|
||||
//===----------------------------------------------------------------------===//
|
||||
|
||||
#ifndef __LLVM_LIBC_TYPES_RLIMIT_T_H__
|
||||
#define __LLVM_LIBC_TYPES_RLIMIT_T_H__
|
||||
|
||||
#include <llvm-libc-types/rlim_t.h>
|
||||
|
||||
struct rlimit_t {
|
||||
rlim_t rlim_cur;
|
||||
rlim_t rlim_max;
|
||||
};
|
||||
|
||||
#endif // __LLVM_LIBC_TYPES_RLIMIT_T_H__
|
|
@ -0,0 +1,18 @@
|
|||
//===-- POSIX header resource.h -------------------------------------------===//
|
||||
//
|
||||
// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
|
||||
// See https://llvm.org/LICENSE.txt for license information.
|
||||
// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
|
||||
//
|
||||
//===----------------------------------------------------------------------===//
|
||||
|
||||
#ifndef LLVM_LIBC_SYS_RESOURCE_H
|
||||
#define LLVM_LIBC_SYS_RESOURCE_H
|
||||
|
||||
#include <__llvm-libc-common.h>
|
||||
|
||||
#include <llvm-libc-macros/sys-resource-macros.h>
|
||||
|
||||
%%public_api()
|
||||
|
||||
#endif // LLVM_LIBC_SYS_RESOURCE_H
|
|
@ -465,6 +465,29 @@ def POSIX : StandardSpec<"POSIX"> {
|
|||
]
|
||||
>;
|
||||
|
||||
NamedType RLimTType = NamedType<"rlim_t">;
|
||||
NamedType StructRLimitTType = NamedType<"struct rlimit_t">;
|
||||
PtrType StructRLimitPtr = PtrType<StructRLimitTType>;
|
||||
ConstType ConstStructRLimitPtr = ConstType<StructRLimitTType>;
|
||||
HeaderSpec SysResource = HeaderSpec<
|
||||
"sys/resource.h",
|
||||
[], // Macros
|
||||
[RLimTType, StructRLimitTType], // Types
|
||||
[], // Enumerations
|
||||
[
|
||||
FunctionSpec<
|
||||
"getrlimit",
|
||||
RetValSpec<IntType>,
|
||||
[ArgSpec<StructRLimitPtr>]
|
||||
>,
|
||||
FunctionSpec<
|
||||
"setrlimit",
|
||||
RetValSpec<IntType>,
|
||||
[ArgSpec<ConstStructRLimitPtr>]
|
||||
>,
|
||||
]
|
||||
>;
|
||||
|
||||
HeaderSpec SysStat = HeaderSpec<
|
||||
"sys/stat.h",
|
||||
[], // Macros
|
||||
|
@ -764,6 +787,7 @@ def POSIX : StandardSpec<"POSIX"> {
|
|||
StdIO,
|
||||
StdLib,
|
||||
SysMMan,
|
||||
SysResource,
|
||||
SysStat,
|
||||
UniStd,
|
||||
String
|
||||
|
|
|
@ -1,3 +1,4 @@
|
|||
add_subdirectory(mman)
|
||||
add_subdirectory(resource)
|
||||
add_subdirectory(sendfile)
|
||||
add_subdirectory(stat)
|
||||
|
|
|
@ -0,0 +1,17 @@
|
|||
if(EXISTS ${CMAKE_CURRENT_SOURCE_DIR}/${LIBC_TARGET_OS})
|
||||
add_subdirectory(${CMAKE_CURRENT_SOURCE_DIR}/${LIBC_TARGET_OS})
|
||||
endif()
|
||||
|
||||
add_entrypoint_object(
|
||||
getrlimit
|
||||
ALIAS
|
||||
DEPENDS
|
||||
.${LIBC_TARGET_OS}.getrlimit
|
||||
)
|
||||
|
||||
add_entrypoint_object(
|
||||
setrlimit
|
||||
ALIAS
|
||||
DEPENDS
|
||||
.${LIBC_TARGET_OS}.setrlimit
|
||||
)
|
|
@ -0,0 +1,20 @@
|
|||
//===-- Implementation header for getrlimit ---------------------*- C++ -*-===//
|
||||
//
|
||||
// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
|
||||
// See https://llvm.org/LICENSE.txt for license information.
|
||||
// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
|
||||
//
|
||||
//===----------------------------------------------------------------------===//
|
||||
|
||||
#ifndef LLVM_LIBC_SRC_SYS_STAT_GETRLIMIT_H
|
||||
#define LLVM_LIBC_SRC_SYS_STAT_GETRLIMIT_H
|
||||
|
||||
#include <sys/resource.h>
|
||||
|
||||
namespace __llvm_libc {
|
||||
|
||||
int getrlimit(int resource, struct rlimit_t *lim);
|
||||
|
||||
} // namespace __llvm_libc
|
||||
|
||||
#endif // LLVM_LIBC_SRC_SYS_STAT_GETRLIMIT_H
|
|
@ -0,0 +1,25 @@
|
|||
add_entrypoint_object(
|
||||
getrlimit
|
||||
SRCS
|
||||
getrlimit.cpp
|
||||
HDRS
|
||||
../getrlimit.h
|
||||
DEPENDS
|
||||
libc.include.sys_resource
|
||||
libc.include.sys_syscall
|
||||
libc.src.__support.OSUtil.osutil
|
||||
libc.src.errno.errno
|
||||
)
|
||||
|
||||
add_entrypoint_object(
|
||||
setrlimit
|
||||
SRCS
|
||||
setrlimit.cpp
|
||||
HDRS
|
||||
../setrlimit.h
|
||||
DEPENDS
|
||||
libc.include.sys_resource
|
||||
libc.include.sys_syscall
|
||||
libc.src.__support.OSUtil.osutil
|
||||
libc.src.errno.errno
|
||||
)
|
|
@ -0,0 +1,29 @@
|
|||
//===-- Linux implementation of getrlimit ---------------------------------===//
|
||||
//
|
||||
// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
|
||||
// See https://llvm.org/LICENSE.txt for license information.
|
||||
// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
|
||||
//
|
||||
//===----------------------------------------------------------------------===//
|
||||
|
||||
#include "src/sys/resource/getrlimit.h"
|
||||
|
||||
#include "src/__support/OSUtil/syscall.h" // For internal syscall function.
|
||||
#include "src/__support/common.h"
|
||||
|
||||
#include <errno.h>
|
||||
#include <sys/resource.h> // For struct rlimit_t
|
||||
#include <sys/syscall.h> // For syscall numbers.
|
||||
|
||||
namespace __llvm_libc {
|
||||
|
||||
LLVM_LIBC_FUNCTION(int, getrlimit, (int res, struct rlimit_t *limits)) {
|
||||
long ret = __llvm_libc::syscall(SYS_prlimit64, 0, res, nullptr, limits);
|
||||
if (ret < 0) {
|
||||
errno = -ret;
|
||||
return -1;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
} // namespace __llvm_libc
|
|
@ -0,0 +1,29 @@
|
|||
//===-- Linux implementation of setrlimit ---------------------------------===//
|
||||
//
|
||||
// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
|
||||
// See https://llvm.org/LICENSE.txt for license information.
|
||||
// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
|
||||
//
|
||||
//===----------------------------------------------------------------------===//
|
||||
|
||||
#include "src/sys/resource/setrlimit.h"
|
||||
|
||||
#include "src/__support/OSUtil/syscall.h" // For internal syscall function.
|
||||
#include "src/__support/common.h"
|
||||
|
||||
#include <errno.h>
|
||||
#include <sys/resource.h> // For struct rlimit_t
|
||||
#include <sys/syscall.h> // For syscall numbers.
|
||||
|
||||
namespace __llvm_libc {
|
||||
|
||||
LLVM_LIBC_FUNCTION(int, setrlimit, (int res, const struct rlimit_t *limits)) {
|
||||
long ret = __llvm_libc::syscall(SYS_prlimit64, 0, res, limits, nullptr);
|
||||
if (ret < 0) {
|
||||
errno = -ret;
|
||||
return -1;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
} // namespace __llvm_libc
|
|
@ -0,0 +1,20 @@
|
|||
//===-- Implementation header for setrlimit ---------------------*- C++ -*-===//
|
||||
//
|
||||
// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
|
||||
// See https://llvm.org/LICENSE.txt for license information.
|
||||
// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
|
||||
//
|
||||
//===----------------------------------------------------------------------===//
|
||||
|
||||
#ifndef LLVM_LIBC_SRC_SYS_STAT_SETRLIMIT_H
|
||||
#define LLVM_LIBC_SRC_SYS_STAT_SETRLIMIT_H
|
||||
|
||||
#include <sys/resource.h>
|
||||
|
||||
namespace __llvm_libc {
|
||||
|
||||
int setrlimit(int resource, const struct rlimit_t *lim);
|
||||
|
||||
} // namespace __llvm_libc
|
||||
|
||||
#endif // LLVM_LIBC_SRC_SYS_STAT_SETRLIMIT_H
|
|
@ -1,3 +1,4 @@
|
|||
add_subdirectory(mman)
|
||||
add_subdirectory(resource)
|
||||
add_subdirectory(sendfile)
|
||||
add_subdirectory(stat)
|
||||
|
|
|
@ -0,0 +1,20 @@
|
|||
add_libc_testsuite(libc_sys_resource_unittests)
|
||||
|
||||
add_subdirectory(testdata)
|
||||
|
||||
add_libc_unittest(
|
||||
getrlimit_setrlimit_test
|
||||
SUITE
|
||||
libc_sys_resource_unittests
|
||||
SRCS
|
||||
getrlimit_setrlimit_test.cpp
|
||||
DEPENDS
|
||||
libc.include.errno
|
||||
libc.include.fcntl
|
||||
libc.include.sys_resource
|
||||
libc.src.fcntl.open
|
||||
libc.src.sys.resource.getrlimit
|
||||
libc.src.sys.resource.setrlimit
|
||||
libc.src.unistd.close
|
||||
libc.src.unistd.unlink
|
||||
)
|
|
@ -0,0 +1,77 @@
|
|||
//===-- Unittests for getrlimit and setrlimit -----------------------------===//
|
||||
//
|
||||
// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
|
||||
// See https://llvm.org/LICENSE.txt for license information.
|
||||
// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
|
||||
//
|
||||
//===----------------------------------------------------------------------===//
|
||||
|
||||
#include "src/__support/CPP/string_view.h"
|
||||
#include "src/fcntl/open.h"
|
||||
#include "src/sys/resource/getrlimit.h"
|
||||
#include "src/sys/resource/setrlimit.h"
|
||||
#include "src/unistd/close.h"
|
||||
#include "src/unistd/unlink.h"
|
||||
#include "test/ErrnoSetterMatcher.h"
|
||||
#include "utils/UnitTest/Test.h"
|
||||
|
||||
#include <errno.h>
|
||||
#include <sys/resource.h>
|
||||
|
||||
TEST(LlvmLibcResourceLimitsTest, SetNoFileLimit) {
|
||||
using __llvm_libc::testing::ErrnoSetterMatcher::Fails;
|
||||
using __llvm_libc::testing::ErrnoSetterMatcher::Succeeds;
|
||||
|
||||
// The test strategy is to first create initialize two file descriptors
|
||||
// successfully. Next, close the files and set the file descriptor limit
|
||||
// to 4. This will allow us to open one of those file but not the other.
|
||||
|
||||
constexpr const char *TEST_FILE1 = "testdata/resource_limits1.test";
|
||||
constexpr const char *TEST_FILE2 = "testdata/resource_limits2.test";
|
||||
errno = 0;
|
||||
|
||||
int fd1 = __llvm_libc::open(TEST_FILE1, O_CREAT | O_WRONLY, S_IRWXU);
|
||||
ASSERT_GT(fd1, 0);
|
||||
ASSERT_EQ(errno, 0);
|
||||
int fd2 = __llvm_libc::open(TEST_FILE2, O_CREAT | O_WRONLY, S_IRWXU);
|
||||
ASSERT_GT(fd2, 0);
|
||||
ASSERT_EQ(errno, 0);
|
||||
|
||||
ASSERT_THAT(__llvm_libc::close(fd1), Succeeds(0));
|
||||
ASSERT_THAT(__llvm_libc::close(fd2), Succeeds(0));
|
||||
|
||||
struct rlimit_t limits {
|
||||
4, 4
|
||||
};
|
||||
ASSERT_THAT(__llvm_libc::setrlimit(RLIMIT_NOFILE, &limits), Succeeds(0));
|
||||
|
||||
// One can now only open one of the files successfully.
|
||||
fd1 = __llvm_libc::open(TEST_FILE1, O_RDONLY);
|
||||
ASSERT_GT(fd1, 0);
|
||||
ASSERT_EQ(errno, 0);
|
||||
fd2 = __llvm_libc::open(TEST_FILE2, O_RDONLY);
|
||||
ASSERT_LT(fd2, 0);
|
||||
ASSERT_NE(errno, 0);
|
||||
|
||||
errno = 0;
|
||||
ASSERT_THAT(__llvm_libc::close(fd1), Succeeds(0));
|
||||
|
||||
fd2 = __llvm_libc::open(TEST_FILE2, O_RDONLY);
|
||||
ASSERT_GT(fd2, 0);
|
||||
ASSERT_EQ(errno, 0);
|
||||
fd1 = __llvm_libc::open(TEST_FILE1, O_RDONLY);
|
||||
ASSERT_LT(fd1, 0);
|
||||
ASSERT_NE(errno, 0);
|
||||
|
||||
errno = 0;
|
||||
ASSERT_THAT(__llvm_libc::close(fd2), Succeeds(0));
|
||||
|
||||
ASSERT_THAT(__llvm_libc::unlink(TEST_FILE1), Succeeds(0));
|
||||
ASSERT_THAT(__llvm_libc::unlink(TEST_FILE2), Succeeds(0));
|
||||
|
||||
struct rlimit_t current_limits;
|
||||
ASSERT_THAT(__llvm_libc::getrlimit(RLIMIT_NOFILE, ¤t_limits),
|
||||
Succeeds(0));
|
||||
ASSERT_EQ(current_limits.rlim_cur, rlim_t(4));
|
||||
ASSERT_EQ(current_limits.rlim_max, rlim_t(4));
|
||||
}
|
Loading…
Reference in New Issue