Skip to content

[libc] Implement getitimer and setitimer, add proxy headers for itimerval #134773

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 8 commits into from
Apr 14, 2025
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 4 additions & 0 deletions libc/config/linux/aarch64/entrypoints.txt
Original file line number Diff line number Diff line change
Expand Up @@ -363,6 +363,10 @@ set(TARGET_LIBC_ENTRYPOINTS
# sys/uio.h entrypoints
libc.src.sys.uio.writev
libc.src.sys.uio.readv

# sys/time.h entrypoints
libc.src.sys.time.setitimer
libc.src.sys.time.getitimer
)

if(LLVM_LIBC_INCLUDE_SCUDO)
Expand Down
3 changes: 3 additions & 0 deletions libc/config/linux/arm/entrypoints.txt
Original file line number Diff line number Diff line change
Expand Up @@ -185,6 +185,9 @@ set(TARGET_LIBC_ENTRYPOINTS
# libc.src.sys.epoll.epoll_pwait
# libc.src.sys.epoll.epoll_pwait2

# sys/time.h entrypoints
libc.src.sys.time.setitimer
libc.src.sys.time.getitimer
)

if(LLVM_LIBC_FULL_BUILD)
Expand Down
4 changes: 4 additions & 0 deletions libc/config/linux/x86_64/entrypoints.txt
Original file line number Diff line number Diff line change
Expand Up @@ -368,6 +368,10 @@ set(TARGET_LIBC_ENTRYPOINTS
# sys/uio.h entrypoints
libc.src.sys.uio.writev
libc.src.sys.uio.readv

# sys/time.h entrypoints
libc.src.sys.time.setitimer
libc.src.sys.time.getitimer
)

if(LLVM_LIBC_INCLUDE_SCUDO)
Expand Down
9 changes: 9 additions & 0 deletions libc/hdr/types/CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -190,6 +190,15 @@ add_proxy_header_library(
libc.include.sys_time
)

add_proxy_header_library(
struct_itimerval
HDRS
struct_itimerval.h
FULL_BUILD_DEPENDS
libc.include.llvm-libc-types.struct_itimerval
libc.include.sys_time
)

add_proxy_header_library(
pid_t
HDRS
Expand Down
21 changes: 21 additions & 0 deletions libc/hdr/types/struct_itimerval.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,21 @@
//===-- Proxy for struct itimerval ----------------------------------------===//
//
// 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_HDR_TYPES_STRUCT_ITIMERVAL_H
#define LLVM_LIBC_HDR_TYPES_STRUCT_ITIMERVAL_H

#ifdef LIBC_FULL_BUILD

#include "include/llvm-libc-types/struct_itimerval.h"

#else

#include <sys/time.h>

#endif // LIBC_FULL_BUILD

#endif // LLVM_LIBC_HDR_TYPES_STRUCT_ITIMERVAL_H
1 change: 1 addition & 0 deletions libc/include/llvm-libc-types/CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -77,6 +77,7 @@ add_header(struct_pollfd HDR struct_pollfd.h)
add_header(struct_rlimit HDR struct_rlimit.h DEPENDS .rlim_t)
add_header(struct_sched_param HDR struct_sched_param.h)
add_header(struct_timeval HDR struct_timeval.h DEPENDS .suseconds_t .time_t)
add_header(struct_itimerval HDR struct_itimerval.h DEPENDS .struct_timeval)
add_header(struct_rusage HDR struct_rusage.h DEPENDS .struct_timeval)
add_header(union_sigval HDR union_sigval.h)
add_header(siginfo_t HDR siginfo_t.h DEPENDS .union_sigval .pid_t .uid_t .clock_t)
Expand Down
19 changes: 19 additions & 0 deletions libc/include/llvm-libc-types/struct_itimerval.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,19 @@
//===-- Definition of struct itimerval ------------------------------------===//
//
// 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_STRUCT_ITIMERVAL_H
#define LLVM_LIBC_TYPES_STRUCT_ITIMERVAL_H

#include "struct_timeval.h"

struct itimerval {
struct timeval it_interval; /* Interval for periodic timer */
struct timeval it_value; /* Time until next expiration */
};

#endif // LLVM_LIBC_TYPES_STRUCT_ITIMERVAL_H
18 changes: 18 additions & 0 deletions libc/include/sys/time.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@ standards: Linux
macros: []
types:
- type_name: struct_timeval
- type_name: struct_itimerval
enums: []
objects: []
functions:
Expand All @@ -12,3 +13,20 @@ functions:
arguments:
- type: const char*
- type: const struct timeval*

- name: setitimer
standards:
- POSIX
return_type: int
arguments:
- type: int
- type: const struct itimerval *__restrict
- type: struct itimerval *__restrict

- name: getitimer
standards:
- POSIX
return_type: int
arguments:
- type: int
- type: struct itimerval *
14 changes: 14 additions & 0 deletions libc/src/sys/time/CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -8,3 +8,17 @@ add_entrypoint_object(
DEPENDS
.${LIBC_TARGET_OS}.utimes
)

add_entrypoint_object(
setitimer
ALIAS
DEPENDS
.${LIBC_TARGET_OS}.setitimer
)

add_entrypoint_object(
getitimer
ALIAS
DEPENDS
.${LIBC_TARGET_OS}.getitimer
)
19 changes: 19 additions & 0 deletions libc/src/sys/time/getitimer.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,19 @@
//===-- Implementation header for getitimer -------------------------------===//
//
// 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_TIME_GETITIMER_H
#define LLVM_LIBC_SRC_SYS_TIME_GETITIMER_H

#include "hdr/types/struct_itimerval.h"
#include "src/__support/macros/config.h"

namespace LIBC_NAMESPACE_DECL {
int getitimer(int which, struct itimerval *curr_value);
} // namespace LIBC_NAMESPACE_DECL

#endif // LLVM_LIBC_SRC_SYS_TIME_GETITIMER_H
28 changes: 28 additions & 0 deletions libc/src/sys/time/linux/CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -14,3 +14,31 @@ add_entrypoint_object(
libc.src.__support.OSUtil.osutil
libc.src.errno.errno
)

add_entrypoint_object(
setitimer
SRCS
setitimer.cpp
HDRS
../setitimer.h
DEPENDS
libc.hdr.types.struct_itimerval
libc.include.sys_syscall
libc.src.__support.OSUtil.osutil
libc.src.__support.common
libc.src.errno.errno
)

add_entrypoint_object(
getitimer
SRCS
getitimer.cpp
HDRS
../getitimer.h
DEPENDS
libc.hdr.types.struct_itimerval
libc.include.sys_syscall
libc.src.__support.OSUtil.osutil
libc.src.__support.common
libc.src.errno.errno
)
29 changes: 29 additions & 0 deletions libc/src/sys/time/linux/getitimer.cpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,29 @@
//===-- Implementation file for getitimer ---------------------------------===//
//
// 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/time/getitimer.h"
#include "hdr/types/struct_itimerval.h"
#include "src/__support/OSUtil/syscall.h"
#include "src/__support/common.h"
#include "src/errno/libc_errno.h"
#include <sys/syscall.h>

namespace LIBC_NAMESPACE_DECL {

LLVM_LIBC_FUNCTION(int, getitimer, (int which, struct itimerval *curr_value)) {
long ret =
LIBC_NAMESPACE::syscall_impl<long>(SYS_getitimer, which, curr_value);
// On failure, return -1 and set errno.
if (ret < 0) {
libc_errno = static_cast<int>(-ret);
return -1;
}
return 0;
}

} // namespace LIBC_NAMESPACE_DECL
30 changes: 30 additions & 0 deletions libc/src/sys/time/linux/setitimer.cpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,30 @@
//===-- Implementation file for setitimer ---------------------------------===//
//
// 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/time/setitimer.h"
#include "hdr/types/struct_itimerval.h"
#include "src/__support/OSUtil/syscall.h"
#include "src/__support/common.h"
#include "src/errno/libc_errno.h"
#include <sys/syscall.h>

namespace LIBC_NAMESPACE_DECL {

LLVM_LIBC_FUNCTION(int, setitimer,
(int which, const struct itimerval *new_value,
struct itimerval *old_value)) {
long ret = LIBC_NAMESPACE::syscall_impl<long>(SYS_setitimer, which, new_value,
old_value);
// On failure, return -1 and set errno.
if (ret < 0) {
libc_errno = static_cast<int>(-ret);
return -1;
}
return 0;
}

} // namespace LIBC_NAMESPACE_DECL
20 changes: 20 additions & 0 deletions libc/src/sys/time/setitimer.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,20 @@
//===-- Implementation header for setitimer -------------------------------===//
//
// 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_TIME_SETITIMER_H
#define LLVM_LIBC_SRC_SYS_TIME_SETITIMER_H

#include "hdr/types/struct_itimerval.h"
#include "src/__support/macros/config.h"

namespace LIBC_NAMESPACE_DECL {
int setitimer(int which, const struct itimerval *new_value,
struct itimerval *old_value);
} // namespace LIBC_NAMESPACE_DECL

#endif // LLVM_LIBC_SRC_SYS_TIME_SETITIMER_H
31 changes: 31 additions & 0 deletions libc/test/src/sys/time/CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -19,3 +19,34 @@ add_libc_unittest(
libc.src.sys.stat.stat
libc.test.UnitTest.ErrnoCheckingTest
)

add_libc_unittest(
setitimer_test
SUITE
libc_sys_time_unittests
SRCS
setitimer_test.cpp
DEPENDS
libc.include.signal
libc.src.sys.time.setitimer
libc.src.signal.sigaction
libc.src.signal.sigemptyset
libc.src.__support.common
libc.src.errno.errno
libc.test.UnitTest.ErrnoCheckingTest
libc.test.UnitTest.ErrnoSetterMatcher
)

add_libc_unittest(
getitimer_test
SUITE
libc_sys_time_unittests
SRCS
getitimer_test.cpp
DEPENDS
libc.src.sys.time.getitimer
libc.src.__support.common
libc.src.errno.errno
libc.test.UnitTest.ErrnoCheckingTest
libc.test.UnitTest.ErrnoSetterMatcher
)
41 changes: 41 additions & 0 deletions libc/test/src/sys/time/getitimer_test.cpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,41 @@
//===-- Unittests for getitimer -------------------------------------------===//
//
// 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 "hdr/types/struct_itimerval.h"
#include "src/sys/time/getitimer.h"
#include "test/UnitTest/ErrnoCheckingTest.h"
#include "test/UnitTest/ErrnoSetterMatcher.h"
#include "test/UnitTest/Test.h"

using namespace LIBC_NAMESPACE::testing::ErrnoSetterMatcher;
using LlvmLibcSysTimeGetitimerTest = LIBC_NAMESPACE::testing::ErrnoCheckingTest;

TEST_F(LlvmLibcSysTimeGetitimerTest, SmokeTest) {
struct itimerval timer;
timer.it_value.tv_sec = -1;
timer.it_value.tv_usec = -1;
timer.it_interval.tv_sec = -1;
timer.it_interval.tv_usec = -1;

ASSERT_THAT(LIBC_NAMESPACE::getitimer(0, &timer),
returns(EQ(0)).with_errno(EQ(0)));
Comment on lines +26 to +27
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

ideally there would be a test where the function succeeds and one where it fails. Could you add a test where the function gives an error?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Added


ASSERT_TRUE(timer.it_value.tv_sec == 0);
ASSERT_TRUE(timer.it_value.tv_usec == 0);
ASSERT_TRUE(timer.it_interval.tv_sec == 0);
ASSERT_TRUE(timer.it_interval.tv_usec == 0);
}

TEST_F(LlvmLibcSysTimeGetitimerTest, InvalidRetTest) {
struct itimerval timer;

// out of range timer type (which)
ASSERT_THAT(LIBC_NAMESPACE::getitimer(99, &timer),
returns(NE(0)).with_errno(NE(0)));
}
Loading
Loading