1f08c3bdfSopenharmony_ci// SPDX-License-Identifier: GPL-2.0-or-later
2f08c3bdfSopenharmony_ci/*
3f08c3bdfSopenharmony_ci * Copyright (c) Wipro Technologies Ltd, 2002.  All Rights Reserved.
4f08c3bdfSopenharmony_ci * AUTHOR : Saji Kumar.V.R <saji.kumar@wipro.com>
5f08c3bdfSopenharmony_ci */
6f08c3bdfSopenharmony_ci
7f08c3bdfSopenharmony_ci/*\
8f08c3bdfSopenharmony_ci * [Description]
9f08c3bdfSopenharmony_ci *
10f08c3bdfSopenharmony_ci * Verify that getrusage() fails with:
11f08c3bdfSopenharmony_ci *
12f08c3bdfSopenharmony_ci * - EINVAL with invalid who
13f08c3bdfSopenharmony_ci * - EFAULT with invalid usage pointer
14f08c3bdfSopenharmony_ci */
15f08c3bdfSopenharmony_ci
16f08c3bdfSopenharmony_ci#include <errno.h>
17f08c3bdfSopenharmony_ci#include <sched.h>
18f08c3bdfSopenharmony_ci#include <sys/resource.h>
19f08c3bdfSopenharmony_ci#include "tst_test.h"
20f08c3bdfSopenharmony_ci#include "lapi/syscalls.h"
21f08c3bdfSopenharmony_ci
22f08c3bdfSopenharmony_cistatic struct rusage usage;
23f08c3bdfSopenharmony_ci
24f08c3bdfSopenharmony_cistatic int libc_getrusage(int who, void *usage)
25f08c3bdfSopenharmony_ci{
26f08c3bdfSopenharmony_ci	return getrusage(who, usage);
27f08c3bdfSopenharmony_ci}
28f08c3bdfSopenharmony_ci
29f08c3bdfSopenharmony_cistatic int sys_getrusage(int who, void *usage)
30f08c3bdfSopenharmony_ci{
31f08c3bdfSopenharmony_ci	return tst_syscall(__NR_getrusage, who, usage);
32f08c3bdfSopenharmony_ci}
33f08c3bdfSopenharmony_ci
34f08c3bdfSopenharmony_cistruct tc_t {
35f08c3bdfSopenharmony_ci	int who;
36f08c3bdfSopenharmony_ci	struct rusage *usage;
37f08c3bdfSopenharmony_ci	int exp_errno;
38f08c3bdfSopenharmony_ci} tc[] = {
39f08c3bdfSopenharmony_ci	{-2, &usage, EINVAL},
40f08c3bdfSopenharmony_ci	{RUSAGE_SELF, (struct rusage *)-1, EFAULT}
41f08c3bdfSopenharmony_ci};
42f08c3bdfSopenharmony_ci
43f08c3bdfSopenharmony_cistatic struct test_variants
44f08c3bdfSopenharmony_ci{
45f08c3bdfSopenharmony_ci	int (*getrusage)(int who, void *usage);
46f08c3bdfSopenharmony_ci	char *desc;
47f08c3bdfSopenharmony_ci} variants[] = {
48f08c3bdfSopenharmony_ci	{ .getrusage = libc_getrusage, .desc = "libc getrusage()"},
49f08c3bdfSopenharmony_ci#if (__NR_getrusage != __LTP__NR_INVALID_SYSCALL)
50f08c3bdfSopenharmony_ci	{ .getrusage = sys_getrusage,  .desc = "__NR_getrusage syscall"},
51f08c3bdfSopenharmony_ci#endif
52f08c3bdfSopenharmony_ci};
53f08c3bdfSopenharmony_ci
54f08c3bdfSopenharmony_cistatic void verify_getrusage(unsigned int i)
55f08c3bdfSopenharmony_ci{
56f08c3bdfSopenharmony_ci	struct test_variants *tv = &variants[tst_variant];
57f08c3bdfSopenharmony_ci
58f08c3bdfSopenharmony_ci	if (tc[i].exp_errno == EFAULT &&
59f08c3bdfSopenharmony_ci	    tv->getrusage == libc_getrusage) {
60f08c3bdfSopenharmony_ci		tst_res(TCONF, "EFAULT is skipped for libc variant");
61f08c3bdfSopenharmony_ci		return;
62f08c3bdfSopenharmony_ci	}
63f08c3bdfSopenharmony_ci
64f08c3bdfSopenharmony_ci	TST_EXP_FAIL(tv->getrusage(tc[i].who, tc[i].usage), tc[i].exp_errno,
65f08c3bdfSopenharmony_ci	             "getrusage(%i, %p)", tc[i].who, tc[i].usage);
66f08c3bdfSopenharmony_ci}
67f08c3bdfSopenharmony_ci
68f08c3bdfSopenharmony_cistatic void setup(void)
69f08c3bdfSopenharmony_ci{
70f08c3bdfSopenharmony_ci	struct test_variants *tv = &variants[tst_variant];
71f08c3bdfSopenharmony_ci
72f08c3bdfSopenharmony_ci	tst_res(TINFO, "Testing variant: %s", tv->desc);
73f08c3bdfSopenharmony_ci}
74f08c3bdfSopenharmony_ci
75f08c3bdfSopenharmony_cistatic struct tst_test test = {
76f08c3bdfSopenharmony_ci	.test = verify_getrusage,
77f08c3bdfSopenharmony_ci	.setup = setup,
78f08c3bdfSopenharmony_ci	.tcnt = ARRAY_SIZE(tc),
79f08c3bdfSopenharmony_ci	.test_variants = ARRAY_SIZE(variants),
80f08c3bdfSopenharmony_ci};
81