1f08c3bdfSopenharmony_ci// SPDX-License-Identifier: GPL-2.0-or-later
2f08c3bdfSopenharmony_ci/*
3f08c3bdfSopenharmony_ci * Copyright (c) International Business Machines Corp., 2001
4f08c3bdfSopenharmony_ci * Ported to LTP: Wayne Boyer
5f08c3bdfSopenharmony_ci * Copyright (c) 2016 Cyril Hrubis <chrubis@suse.cz>
6f08c3bdfSopenharmony_ci * Copyright (c) Linux Test Project, 2003-2022
7f08c3bdfSopenharmony_ci */
8f08c3bdfSopenharmony_ci
9f08c3bdfSopenharmony_ci/*\
10f08c3bdfSopenharmony_ci * [Description]
11f08c3bdfSopenharmony_ci *
12f08c3bdfSopenharmony_ci * Verify that root can provide a negative value to nice() system call and hence
13f08c3bdfSopenharmony_ci * root can decrease the nice value of the process using nice().
14f08c3bdfSopenharmony_ci */
15f08c3bdfSopenharmony_ci
16f08c3bdfSopenharmony_ci#include <unistd.h>
17f08c3bdfSopenharmony_ci#include <errno.h>
18f08c3bdfSopenharmony_ci#include <sys/resource.h>
19f08c3bdfSopenharmony_ci#include "tst_test.h"
20f08c3bdfSopenharmony_ci
21f08c3bdfSopenharmony_ci#define MIN_PRIO        -20
22f08c3bdfSopenharmony_ci
23f08c3bdfSopenharmony_cistatic int nice_inc[] = {-1, -12, -50};
24f08c3bdfSopenharmony_ci
25f08c3bdfSopenharmony_cistatic void verify_nice(unsigned int i)
26f08c3bdfSopenharmony_ci{
27f08c3bdfSopenharmony_ci	int new_nice;
28f08c3bdfSopenharmony_ci	int orig_nice;
29f08c3bdfSopenharmony_ci	int exp_nice;
30f08c3bdfSopenharmony_ci	int inc = nice_inc[i];
31f08c3bdfSopenharmony_ci	int delta;
32f08c3bdfSopenharmony_ci
33f08c3bdfSopenharmony_ci	orig_nice = SAFE_GETPRIORITY(PRIO_PROCESS, 0);
34f08c3bdfSopenharmony_ci
35f08c3bdfSopenharmony_ci	TEST(nice(inc));
36f08c3bdfSopenharmony_ci
37f08c3bdfSopenharmony_ci	exp_nice = MAX(MIN_PRIO, (orig_nice + inc));
38f08c3bdfSopenharmony_ci
39f08c3bdfSopenharmony_ci	if (TST_RET != exp_nice) {
40f08c3bdfSopenharmony_ci		tst_res(TFAIL | TTERRNO, "nice(%d) returned %li, expected %i",
41f08c3bdfSopenharmony_ci				inc, TST_RET, exp_nice);
42f08c3bdfSopenharmony_ci		return;
43f08c3bdfSopenharmony_ci	}
44f08c3bdfSopenharmony_ci
45f08c3bdfSopenharmony_ci	if (TST_ERR) {
46f08c3bdfSopenharmony_ci		tst_res(TFAIL | TTERRNO, "nice(%d) failed", inc);
47f08c3bdfSopenharmony_ci		return;
48f08c3bdfSopenharmony_ci	}
49f08c3bdfSopenharmony_ci
50f08c3bdfSopenharmony_ci	new_nice = SAFE_GETPRIORITY(PRIO_PROCESS, 0);
51f08c3bdfSopenharmony_ci
52f08c3bdfSopenharmony_ci	if (new_nice != exp_nice) {
53f08c3bdfSopenharmony_ci		tst_res(TFAIL, "Process priority %i, expected %i",
54f08c3bdfSopenharmony_ci				new_nice, exp_nice);
55f08c3bdfSopenharmony_ci		return;
56f08c3bdfSopenharmony_ci	}
57f08c3bdfSopenharmony_ci
58f08c3bdfSopenharmony_ci	tst_res(TPASS, "nice(%d) passed", inc);
59f08c3bdfSopenharmony_ci
60f08c3bdfSopenharmony_ci	delta = orig_nice - exp_nice;
61f08c3bdfSopenharmony_ci	TEST(nice(delta));
62f08c3bdfSopenharmony_ci	if (TST_ERR)
63f08c3bdfSopenharmony_ci		tst_brk(TBROK | TTERRNO, "nice(%d) failed", delta);
64f08c3bdfSopenharmony_ci}
65f08c3bdfSopenharmony_ci
66f08c3bdfSopenharmony_cistatic struct tst_test test = {
67f08c3bdfSopenharmony_ci	.needs_root = 1,
68f08c3bdfSopenharmony_ci	.test = verify_nice,
69f08c3bdfSopenharmony_ci	.tcnt = ARRAY_SIZE(nice_inc),
70f08c3bdfSopenharmony_ci};
71