1f08c3bdfSopenharmony_ci// SPDX-License-Identifier: GPL-2.0-or-later
2f08c3bdfSopenharmony_ci/*
3f08c3bdfSopenharmony_ci * Copyright (c) 2020 Petr Vorel <pvorel@suse.cz>
4f08c3bdfSopenharmony_ci */
5f08c3bdfSopenharmony_ci
6f08c3bdfSopenharmony_ci#include "tst_safe_timerfd.h"
7f08c3bdfSopenharmony_ci#include "lapi/timerfd.h"
8f08c3bdfSopenharmony_ci#include "tst_clocks.h"
9f08c3bdfSopenharmony_ci#define TST_NO_DEFAULT_MAIN
10f08c3bdfSopenharmony_ci#include "tst_test.h"
11f08c3bdfSopenharmony_ci
12f08c3bdfSopenharmony_ci#define TTYPE (errno == ENOTSUP ? TCONF : TBROK)
13f08c3bdfSopenharmony_ci
14f08c3bdfSopenharmony_ciint safe_timerfd_create(const char *file, const int lineno,
15f08c3bdfSopenharmony_ci				      int clockid, int flags)
16f08c3bdfSopenharmony_ci{
17f08c3bdfSopenharmony_ci	int fd;
18f08c3bdfSopenharmony_ci
19f08c3bdfSopenharmony_ci	fd = timerfd_create(clockid, flags);
20f08c3bdfSopenharmony_ci
21f08c3bdfSopenharmony_ci	if (fd == -1) {
22f08c3bdfSopenharmony_ci		tst_brk_(file, lineno, TTYPE | TERRNO,
23f08c3bdfSopenharmony_ci			"timerfd_create(%s) failed", tst_clock_name(clockid));
24f08c3bdfSopenharmony_ci	} else if (fd < 0) {
25f08c3bdfSopenharmony_ci		tst_brk_(file, lineno, TBROK | TERRNO,
26f08c3bdfSopenharmony_ci			"Invalid timerfd_create(%s) return value %d",
27f08c3bdfSopenharmony_ci			tst_clock_name(clockid), fd);
28f08c3bdfSopenharmony_ci	}
29f08c3bdfSopenharmony_ci
30f08c3bdfSopenharmony_ci	return fd;
31f08c3bdfSopenharmony_ci}
32f08c3bdfSopenharmony_ci
33f08c3bdfSopenharmony_ciint safe_timerfd_gettime(const char *file, const int lineno,
34f08c3bdfSopenharmony_ci				int fd, struct itimerspec *curr_value)
35f08c3bdfSopenharmony_ci{
36f08c3bdfSopenharmony_ci	int rval;
37f08c3bdfSopenharmony_ci
38f08c3bdfSopenharmony_ci	rval = timerfd_gettime(fd, curr_value);
39f08c3bdfSopenharmony_ci
40f08c3bdfSopenharmony_ci	if (rval == -1) {
41f08c3bdfSopenharmony_ci		tst_brk_(file, lineno, TTYPE | TERRNO,
42f08c3bdfSopenharmony_ci			"timerfd_gettime() failed");
43f08c3bdfSopenharmony_ci	} else if (rval) {
44f08c3bdfSopenharmony_ci		tst_brk_(file, lineno, TBROK | TERRNO,
45f08c3bdfSopenharmony_ci			"Invalid timerfd_gettime() return value %d", rval);
46f08c3bdfSopenharmony_ci	}
47f08c3bdfSopenharmony_ci
48f08c3bdfSopenharmony_ci	return rval;
49f08c3bdfSopenharmony_ci}
50f08c3bdfSopenharmony_ci
51f08c3bdfSopenharmony_ciint safe_timerfd_settime(const char *file, const int lineno,
52f08c3bdfSopenharmony_ci				int fd, int flags,
53f08c3bdfSopenharmony_ci				const struct itimerspec *new_value,
54f08c3bdfSopenharmony_ci				struct itimerspec *old_value)
55f08c3bdfSopenharmony_ci{
56f08c3bdfSopenharmony_ci	int rval;
57f08c3bdfSopenharmony_ci
58f08c3bdfSopenharmony_ci	rval = timerfd_settime(fd, flags, new_value, old_value);
59f08c3bdfSopenharmony_ci
60f08c3bdfSopenharmony_ci	if (rval == -1) {
61f08c3bdfSopenharmony_ci		tst_brk_(file, lineno, TTYPE | TERRNO,
62f08c3bdfSopenharmony_ci			"timerfd_settime() failed");
63f08c3bdfSopenharmony_ci	} else if (rval) {
64f08c3bdfSopenharmony_ci		tst_brk_(file, lineno, TBROK | TERRNO,
65f08c3bdfSopenharmony_ci			"Invalid timerfd_settime() return value %d", rval);
66f08c3bdfSopenharmony_ci	}
67f08c3bdfSopenharmony_ci
68f08c3bdfSopenharmony_ci	return rval;
69f08c3bdfSopenharmony_ci}
70