diff --git a/libc/config/linux/aarch64/entrypoints.txt b/libc/config/linux/aarch64/entrypoints.txt index 567025e62f43d..05bc74fa6932f 100644 --- a/libc/config/linux/aarch64/entrypoints.txt +++ b/libc/config/linux/aarch64/entrypoints.txt @@ -299,8 +299,10 @@ set(TARGET_LIBC_ENTRYPOINTS libc.src.sys.random.getrandom # sys/resource.h entrypoints + libc.src.sys.resource.getpriority libc.src.sys.resource.getrlimit libc.src.sys.resource.getrusage + libc.src.sys.resource.setpriority libc.src.sys.resource.setrlimit # sys/sendfile.h entrypoints diff --git a/libc/config/linux/riscv/entrypoints.txt b/libc/config/linux/riscv/entrypoints.txt index 40fef13470322..cf28d6d9645e8 100644 --- a/libc/config/linux/riscv/entrypoints.txt +++ b/libc/config/linux/riscv/entrypoints.txt @@ -330,8 +330,10 @@ set(TARGET_LIBC_ENTRYPOINTS libc.src.sys.random.getrandom # sys/resource.h entrypoints + libc.src.sys.resource.getpriority libc.src.sys.resource.getrlimit libc.src.sys.resource.getrusage + libc.src.sys.resource.setpriority libc.src.sys.resource.setrlimit # sys/sendfile.h entrypoints diff --git a/libc/config/linux/x86_64/entrypoints.txt b/libc/config/linux/x86_64/entrypoints.txt index 6a37d8b2b48d6..2e1dc645696ee 100644 --- a/libc/config/linux/x86_64/entrypoints.txt +++ b/libc/config/linux/x86_64/entrypoints.txt @@ -330,8 +330,10 @@ set(TARGET_LIBC_ENTRYPOINTS libc.src.sys.random.getrandom # sys/resource.h entrypoints + libc.src.sys.resource.getpriority libc.src.sys.resource.getrlimit libc.src.sys.resource.getrusage + libc.src.sys.resource.setpriority libc.src.sys.resource.setrlimit # sys/sem.h entrypoints diff --git a/libc/hdr/types/CMakeLists.txt b/libc/hdr/types/CMakeLists.txt index 14f5004922606..0d12917200226 100644 --- a/libc/hdr/types/CMakeLists.txt +++ b/libc/hdr/types/CMakeLists.txt @@ -1349,3 +1349,11 @@ add_proxy_header_library( FULL_BUILD_DEPENDS libc.include.llvm-libc-types.tcflag_t ) + +add_proxy_header_library( + id_t + HDRS + id_t.h + FULL_BUILD_DEPENDS + libc.include.llvm-libc-types.id_t +) diff --git a/libc/hdr/types/id_t.h b/libc/hdr/types/id_t.h new file mode 100644 index 0000000000000..b478af776b7cb --- /dev/null +++ b/libc/hdr/types/id_t.h @@ -0,0 +1,27 @@ +//===----------------------------------------------------------------------===// +// +// 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 +// +//===----------------------------------------------------------------------===// +/// +/// \file +/// Proxy for id_t. +/// +//===----------------------------------------------------------------------===// + +#ifndef LLVM_LIBC_HDR_TYPES_ID_T_H +#define LLVM_LIBC_HDR_TYPES_ID_T_H + +#ifdef LIBC_FULL_BUILD + +#include "include/llvm-libc-types/id_t.h" + +#else // Overlay mode + +#include + +#endif // LIBC_FULL_BUILD + +#endif // LLVM_LIBC_HDR_TYPES_ID_T_H diff --git a/libc/include/llvm-libc-macros/linux/sys-resource-macros.h b/libc/include/llvm-libc-macros/linux/sys-resource-macros.h index 9f1e04a339c73..4c3ebf3991086 100644 --- a/libc/include/llvm-libc-macros/linux/sys-resource-macros.h +++ b/libc/include/llvm-libc-macros/linux/sys-resource-macros.h @@ -34,4 +34,8 @@ #define RUSAGE_CHILDREN (-1) #define RUSAGE_THREAD 1 +#define PRIO_PROCESS 0 +#define PRIO_PGRP 1 +#define PRIO_USER 2 + #endif // LLVM_LIBC_MACROS_LINUX_SYS_RESOURCE_MACROS_H diff --git a/libc/include/sys/resource.yaml b/libc/include/sys/resource.yaml index a26dfb5f77beb..c4733dead7575 100644 --- a/libc/include/sys/resource.yaml +++ b/libc/include/sys/resource.yaml @@ -12,6 +12,12 @@ macros: macro_header: sys-resource-macros.h standards: - gnu + - macro_name: PRIO_PROCESS + macro_header: sys-resource-macros.h + - macro_name: PRIO_PGRP + macro_header: sys-resource-macros.h + - macro_name: PRIO_USER + macro_header: sys-resource-macros.h types: - type_name: struct_rlimit - type_name: rlim_t @@ -19,6 +25,13 @@ types: enums: [] objects: [] functions: + - name: getpriority + standards: + - posix + return_type: int + arguments: + - type: int + - type: id_t - name: getrlimit standards: - posix @@ -33,6 +46,14 @@ functions: arguments: - type: int - type: struct rusage * + - name: setpriority + standards: + - posix + return_type: int + arguments: + - type: int + - type: id_t + - type: int - name: setrlimit standards: - posix diff --git a/libc/src/__support/OSUtil/linux/syscall_wrappers/CMakeLists.txt b/libc/src/__support/OSUtil/linux/syscall_wrappers/CMakeLists.txt index 7d09f46696308..24371d2220921 100644 --- a/libc/src/__support/OSUtil/linux/syscall_wrappers/CMakeLists.txt +++ b/libc/src/__support/OSUtil/linux/syscall_wrappers/CMakeLists.txt @@ -1066,3 +1066,29 @@ add_header_library( libc.src.__support.macros.config libc.include.sys_syscall ) + +add_header_library( + getpriority + HDRS + getpriority.h + DEPENDS + libc.hdr.types.id_t + libc.src.__support.OSUtil.osutil + libc.src.__support.common + libc.src.__support.error_or + libc.src.__support.macros.config + libc.include.sys_syscall +) + +add_header_library( + setpriority + HDRS + setpriority.h + DEPENDS + libc.hdr.types.id_t + libc.src.__support.OSUtil.osutil + libc.src.__support.common + libc.src.__support.error_or + libc.src.__support.macros.config + libc.include.sys_syscall +) diff --git a/libc/src/__support/OSUtil/linux/syscall_wrappers/getpriority.h b/libc/src/__support/OSUtil/linux/syscall_wrappers/getpriority.h new file mode 100644 index 0000000000000..d4939568528cf --- /dev/null +++ b/libc/src/__support/OSUtil/linux/syscall_wrappers/getpriority.h @@ -0,0 +1,34 @@ +//===----------------------------------------------------------------------===// +// +// 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 +// +//===----------------------------------------------------------------------===// +/// +/// \file +/// Syscall wrapper for getpriority +/// +//===----------------------------------------------------------------------===// + +#ifndef LLVM_LIBC_SRC___SUPPORT_OSUTIL_LINUX_SYSCALL_WRAPPERS_GETPRIORITY_H +#define LLVM_LIBC_SRC___SUPPORT_OSUTIL_LINUX_SYSCALL_WRAPPERS_GETPRIORITY_H + +#include "hdr/types/pid_t.h" +#include "src/__support/OSUtil/linux/syscall.h" // For syscall_checked +#include "src/__support/common.h" +#include "src/__support/error_or.h" +#include "src/__support/macros/config.h" +#include // For syscall numbers + +namespace LIBC_NAMESPACE_DECL { +namespace linux_syscalls { + +LIBC_INLINE ErrorOr getpriority(int which, id_t who) { + return syscall_checked(SYS_getpriority, which, who); +} + +} // namespace linux_syscalls +} // namespace LIBC_NAMESPACE_DECL + +#endif // LLVM_LIBC_SRC___SUPPORT_OSUTIL_LINUX_SYSCALL_WRAPPERS_GETPRIORITY_H diff --git a/libc/src/__support/OSUtil/linux/syscall_wrappers/setpriority.h b/libc/src/__support/OSUtil/linux/syscall_wrappers/setpriority.h new file mode 100644 index 0000000000000..0d3b7ede81f8a --- /dev/null +++ b/libc/src/__support/OSUtil/linux/syscall_wrappers/setpriority.h @@ -0,0 +1,34 @@ +//===----------------------------------------------------------------------===// +// +// 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 +// +//===----------------------------------------------------------------------===// +/// +/// \file +/// Syscall wrapper for setpriority +/// +//===----------------------------------------------------------------------===// + +#ifndef LLVM_LIBC_SRC___SUPPORT_OSUTIL_LINUX_SYSCALL_WRAPPERS_SETPRIORITY_H +#define LLVM_LIBC_SRC___SUPPORT_OSUTIL_LINUX_SYSCALL_WRAPPERS_SETPRIORITY_H + +#include "hdr/types/id_t.h" +#include "src/__support/OSUtil/linux/syscall.h" // For syscall_checked +#include "src/__support/common.h" +#include "src/__support/error_or.h" +#include "src/__support/macros/config.h" +#include // For syscall numbers + +namespace LIBC_NAMESPACE_DECL { +namespace linux_syscalls { + +LIBC_INLINE ErrorOr setpriority(int which, id_t who, int niceval) { + return syscall_checked(SYS_setpriority, which, who, niceval); +} + +} // namespace linux_syscalls +} // namespace LIBC_NAMESPACE_DECL + +#endif // LLVM_LIBC_SRC___SUPPORT_OSUTIL_LINUX_SYSCALL_WRAPPERS_SETPRIORITY_H diff --git a/libc/src/sys/resource/CMakeLists.txt b/libc/src/sys/resource/CMakeLists.txt index ac5f676588994..7105eb98e67ac 100644 --- a/libc/src/sys/resource/CMakeLists.txt +++ b/libc/src/sys/resource/CMakeLists.txt @@ -2,6 +2,13 @@ if(EXISTS ${CMAKE_CURRENT_SOURCE_DIR}/${LIBC_TARGET_OS}) add_subdirectory(${CMAKE_CURRENT_SOURCE_DIR}/${LIBC_TARGET_OS}) endif() +add_entrypoint_object( + getpriority + ALIAS + DEPENDS + .${LIBC_TARGET_OS}.getpriority +) + add_entrypoint_object( getrlimit ALIAS @@ -16,6 +23,13 @@ add_entrypoint_object( .${LIBC_TARGET_OS}.getrusage ) +add_entrypoint_object( + setpriority + ALIAS + DEPENDS + .${LIBC_TARGET_OS}.setpriority +) + add_entrypoint_object( setrlimit ALIAS diff --git a/libc/src/sys/resource/getpriority.h b/libc/src/sys/resource/getpriority.h new file mode 100644 index 0000000000000..ca89889f0a190 --- /dev/null +++ b/libc/src/sys/resource/getpriority.h @@ -0,0 +1,26 @@ +//===----------------------------------------------------------------------===// +// +// 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 +// +//===----------------------------------------------------------------------===// +/// +/// \file +/// Implementation header of getpriority +/// +//===----------------------------------------------------------------------===// + +#ifndef LLVM_LIBC_SRC_SYS_RESOURCE_GETPRIORITY_H +#define LLVM_LIBC_SRC_SYS_RESOURCE_GETPRIORITY_H + +#include "hdr/types/id_t.h" +#include "src/__support/macros/config.h" + +namespace LIBC_NAMESPACE_DECL { + +int getpriority(int which, id_t who); + +} // namespace LIBC_NAMESPACE_DECL + +#endif // LLVM_LIBC_SRC_SYS_RESOURCE_GETPRIORITY_H diff --git a/libc/src/sys/resource/linux/CMakeLists.txt b/libc/src/sys/resource/linux/CMakeLists.txt index 2a7d96c2eb365..293acb3337355 100644 --- a/libc/src/sys/resource/linux/CMakeLists.txt +++ b/libc/src/sys/resource/linux/CMakeLists.txt @@ -1,3 +1,17 @@ +add_entrypoint_object( + getpriority + SRCS + getpriority.cpp + HDRS + ../getpriority.h + DEPENDS + libc.hdr.types.id_t + libc.src.__support.OSUtil.linux.syscall_wrappers.getpriority + libc.src.__support.common + libc.src.__support.macros.config + libc.src.errno.errno +) + add_entrypoint_object( getrlimit SRCS @@ -24,6 +38,20 @@ add_entrypoint_object( libc.src.errno.errno ) +add_entrypoint_object( + setpriority + SRCS + setpriority.cpp + HDRS + ../setpriority.h + DEPENDS + libc.hdr.types.id_t + libc.src.__support.OSUtil.linux.syscall_wrappers.setpriority + libc.src.__support.common + libc.src.__support.macros.config + libc.src.errno.errno +) + add_entrypoint_object( setrlimit SRCS diff --git a/libc/src/sys/resource/linux/getpriority.cpp b/libc/src/sys/resource/linux/getpriority.cpp new file mode 100644 index 0000000000000..a8c1225120c48 --- /dev/null +++ b/libc/src/sys/resource/linux/getpriority.cpp @@ -0,0 +1,34 @@ +//===----------------------------------------------------------------------===// +// +// 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 +// +//===----------------------------------------------------------------------===// +/// +/// \file +/// Linux implementation of getpriority. +/// +//===----------------------------------------------------------------------===// + +#include "src/sys/resource/getpriority.h" + +#include "hdr/types/id_t.h" +#include "src/__support/OSUtil/linux/syscall_wrappers/getpriority.h" +#include "src/__support/common.h" +#include "src/__support/libc_errno.h" +#include "src/__support/macros/config.h" + +namespace LIBC_NAMESPACE_DECL { + +LLVM_LIBC_FUNCTION(int, getpriority, (int which, id_t who)) { + auto result = linux_syscalls::getpriority(which, who); + if (!result) { + libc_errno = result.error(); + return -1; + } + // The syscall returns (20 - nice), but we must return nice itself. + return 20 - result.value(); +} + +} // namespace LIBC_NAMESPACE_DECL diff --git a/libc/src/sys/resource/linux/setpriority.cpp b/libc/src/sys/resource/linux/setpriority.cpp new file mode 100644 index 0000000000000..c22802ad0184e --- /dev/null +++ b/libc/src/sys/resource/linux/setpriority.cpp @@ -0,0 +1,33 @@ +//===----------------------------------------------------------------------===// +// +// 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 +// +//===----------------------------------------------------------------------===// +/// +/// \file +/// Linux implementation of setpriority. +/// +//===----------------------------------------------------------------------===// + +#include "src/sys/resource/setpriority.h" + +#include "hdr/types/id_t.h" +#include "src/__support/OSUtil/linux/syscall_wrappers/setpriority.h" +#include "src/__support/common.h" +#include "src/__support/libc_errno.h" +#include "src/__support/macros/config.h" + +namespace LIBC_NAMESPACE_DECL { + +LLVM_LIBC_FUNCTION(int, setpriority, (int which, id_t who, int prio)) { + auto result = linux_syscalls::setpriority(which, who, prio); + if (!result) { + libc_errno = result.error(); + return -1; + } + return 0; +} + +} // namespace LIBC_NAMESPACE_DECL diff --git a/libc/src/sys/resource/setpriority.h b/libc/src/sys/resource/setpriority.h new file mode 100644 index 0000000000000..bcfd2a422882a --- /dev/null +++ b/libc/src/sys/resource/setpriority.h @@ -0,0 +1,26 @@ +//===----------------------------------------------------------------------===// +// +// 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 +// +//===----------------------------------------------------------------------===// +/// +/// \file +/// Implementation header of setpriority +/// +//===----------------------------------------------------------------------===// + +#ifndef LLVM_LIBC_SRC_SYS_RESOURCE_SETPRIORITY_H +#define LLVM_LIBC_SRC_SYS_RESOURCE_SETPRIORITY_H + +#include "hdr/types/id_t.h" +#include "src/__support/macros/config.h" + +namespace LIBC_NAMESPACE_DECL { + +int setpriority(int which, id_t who, int prio); + +} // namespace LIBC_NAMESPACE_DECL + +#endif // LLVM_LIBC_SRC_SYS_RESOURCE_SETPRIORITY_H diff --git a/libc/test/src/sys/resource/CMakeLists.txt b/libc/test/src/sys/resource/CMakeLists.txt index 5ff3ec8a62ea9..e67c456bfdbaf 100644 --- a/libc/test/src/sys/resource/CMakeLists.txt +++ b/libc/test/src/sys/resource/CMakeLists.txt @@ -1,5 +1,20 @@ add_custom_target(libc_sys_resource_unittests) +add_libc_test( + getpriority_setpriority_test + SUITE + libc_sys_resource_unittests + SRCS + getpriority_setpriority_test.cpp + DEPENDS + libc.hdr.sys_resource_macros + libc.hdr.types.id_t + libc.src.sys.resource.getpriority + libc.src.sys.resource.setpriority + libc.test.UnitTest.ErrnoCheckingTest + libc.test.UnitTest.ErrnoSetterMatcher +) + add_libc_test( getrlimit_setrlimit_test SUITE diff --git a/libc/test/src/sys/resource/getpriority_setpriority_test.cpp b/libc/test/src/sys/resource/getpriority_setpriority_test.cpp new file mode 100644 index 0000000000000..b4f7cfe05716b --- /dev/null +++ b/libc/test/src/sys/resource/getpriority_setpriority_test.cpp @@ -0,0 +1,57 @@ +//===----------------------------------------------------------------------===// +// +// 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 +// +//===----------------------------------------------------------------------===// +/// +/// \file +/// Unittests for getpriority and setpriority. +/// +//===----------------------------------------------------------------------===// + +#include "hdr/sys_resource_macros.h" +#include "hdr/types/id_t.h" +#include "src/sys/resource/getpriority.h" +#include "src/sys/resource/setpriority.h" +#include "test/UnitTest/ErrnoCheckingTest.h" +#include "test/UnitTest/ErrnoSetterMatcher.h" +#include "test/UnitTest/Test.h" + +using namespace LIBC_NAMESPACE::testing::ErrnoSetterMatcher; +using LlvmLibcGetprioritySetpriorityTest = + LIBC_NAMESPACE::testing::ErrnoCheckingTest; + +TEST_F(LlvmLibcGetprioritySetpriorityTest, BesicTest) { + int current_nice = LIBC_NAMESPACE::getpriority(PRIO_PROCESS, 0); + ASSERT_ERRNO_SUCCESS(); + ASSERT_GE(current_nice, -20); + ASSERT_LE(current_nice, 19); + + // 19 is the highest possible nice on Linux (i.e. minimal priority), which + // doesn't require special privileges. Current nice is likely less than or at + // worst equal to 19. This allows us to round-trip this value and confirm + // that we get back the correct nice. + int nice = 19; + + ASSERT_THAT(LIBC_NAMESPACE::setpriority(PRIO_PROCESS, 0, nice), Succeeds()); + ASSERT_THAT(LIBC_NAMESPACE::getpriority(PRIO_PROCESS, 0), Succeeds(nice)); +} + +TEST_F(LlvmLibcGetprioritySetpriorityTest, TestBadPidGetpriority) { + ASSERT_THAT(LIBC_NAMESPACE::getpriority(PRIO_PROCESS, -1), Fails(ESRCH, -1)); +} + +TEST_F(LlvmLibcGetprioritySetpriorityTest, TestBadWhichGetpriority) { + ASSERT_THAT(LIBC_NAMESPACE::getpriority(99, 0), Fails(EINVAL, -1)); +} + +TEST_F(LlvmLibcGetprioritySetpriorityTest, TestBadPidSetpriority) { + ASSERT_THAT(LIBC_NAMESPACE::setpriority(PRIO_PROCESS, -1, 19), + Fails(ESRCH, -1)); +} + +TEST_F(LlvmLibcGetprioritySetpriorityTest, TestBadWhichSetpriority) { + ASSERT_THAT(LIBC_NAMESPACE::setpriority(99, 0, 19), Fails(EINVAL, -1)); +}