blob: 31162f7fdd8251cc7affbaf2ea7732f8f1d2e860 [file]
// Copyright 2026 The Fuchsia Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
#include <sys/syscall.h>
#include <sys/time.h>
#include <unistd.h>
#include <cerrno>
#include <csignal>
#include <cstdlib>
#include <ctime>
#include <gtest/gtest.h>
#include "src/starnix/tests/syscalls/cpp/syscall_matchers.h"
int main(int argc, char** argv) {
if (argc != 2) {
return EXIT_FAILURE;
}
int kernel_timer_id = std::atoi(argv[1]);
// POSIX timers created via timer_create(2) are not preserved across execve(2).
struct itimerspec its = {};
EXPECT_THAT(syscall(SYS_timer_gettime, kernel_timer_id, &its), SyscallFailsWithErrno(EINVAL));
EXPECT_THAT(syscall(SYS_timer_delete, kernel_timer_id), SyscallFailsWithErrno(EINVAL));
// Interval timers (setitimer(2)) are preserved across execve(2).
struct itimerval itv = {};
EXPECT_THAT(getitimer(ITIMER_REAL, &itv), SyscallSucceeds());
EXPECT_GT(itv.it_value.tv_sec, 0);
struct itimerval zero_itv = {};
EXPECT_THAT(setitimer(ITIMER_REAL, &zero_itv, nullptr), SyscallSucceeds());
// Verify that new POSIX timers can be created after execve(2). Linux is observed to not reset
// the per-process timer ID counter across execve(2), so the new timer receives the next
// sequential ID after the pre-exec timer.
int new_timer_id = -1;
struct sigevent sev = {};
sev.sigev_notify = SIGEV_NONE;
EXPECT_THAT(syscall(SYS_timer_create, CLOCK_MONOTONIC, &sev, &new_timer_id), SyscallSucceeds());
EXPECT_EQ(new_timer_id, kernel_timer_id + 1);
EXPECT_THAT(syscall(SYS_timer_delete, new_timer_id), SyscallSucceeds());
return ::testing::Test::HasFailure() ? EXIT_FAILURE : EXIT_SUCCESS;
}