1f08c3bdfSopenharmony_ci// SPDX-License-Identifier: GPL-2.0-or-later
2f08c3bdfSopenharmony_ci/*
3f08c3bdfSopenharmony_ci * Copyright (c) International Business Machines  Corp., 2001
4f08c3bdfSopenharmony_ci *  07/2001 Ported by Wayne Boyer
5f08c3bdfSopenharmony_ci */
6f08c3bdfSopenharmony_ci
7f08c3bdfSopenharmony_ci/*\
8f08c3bdfSopenharmony_ci * [Description]
9f08c3bdfSopenharmony_ci *
10f08c3bdfSopenharmony_ci * Verify that chmod(2) succeeds when used to change the mode permissions
11f08c3bdfSopenharmony_ci * of a file or directory.
12f08c3bdfSopenharmony_ci */
13f08c3bdfSopenharmony_ci
14f08c3bdfSopenharmony_ci#include "tst_test.h"
15f08c3bdfSopenharmony_ci
16f08c3bdfSopenharmony_ci#define MODE	S_IRUSR | S_IWUSR | S_IRGRP | S_IROTH
17f08c3bdfSopenharmony_ci#define TESTFILE	"testfile"
18f08c3bdfSopenharmony_ci#define TESTDIR		"testdir_1"
19f08c3bdfSopenharmony_ci
20f08c3bdfSopenharmony_cistatic int modes[] = {0, 07, 070, 0700, 0777, 02777, 04777, 06777};
21f08c3bdfSopenharmony_ci
22f08c3bdfSopenharmony_cistatic char *test_dir;
23f08c3bdfSopenharmony_cistatic char *test_file;
24f08c3bdfSopenharmony_ci
25f08c3bdfSopenharmony_cistatic struct variant {
26f08c3bdfSopenharmony_ci	char **name;
27f08c3bdfSopenharmony_ci	unsigned int mode_mask;
28f08c3bdfSopenharmony_ci	char *desc;
29f08c3bdfSopenharmony_ci} variants[] = {
30f08c3bdfSopenharmony_ci	{&test_file, S_IFREG, "verify permissions of file"},
31f08c3bdfSopenharmony_ci	{&test_dir, S_IFDIR, "verify permissions of directory"},
32f08c3bdfSopenharmony_ci};
33f08c3bdfSopenharmony_ci
34f08c3bdfSopenharmony_cistatic void verify_chmod(unsigned int n)
35f08c3bdfSopenharmony_ci{
36f08c3bdfSopenharmony_ci	struct stat stat_buf;
37f08c3bdfSopenharmony_ci	int mode = modes[n];
38f08c3bdfSopenharmony_ci	struct variant *tc = &variants[tst_variant];
39f08c3bdfSopenharmony_ci
40f08c3bdfSopenharmony_ci	TST_EXP_PASS(chmod(*tc->name, mode), "chmod(%s, %04o)",
41f08c3bdfSopenharmony_ci	             *tc->name, mode);
42f08c3bdfSopenharmony_ci
43f08c3bdfSopenharmony_ci	if (!TST_PASS)
44f08c3bdfSopenharmony_ci		return;
45f08c3bdfSopenharmony_ci
46f08c3bdfSopenharmony_ci	SAFE_STAT(*tc->name, &stat_buf);
47f08c3bdfSopenharmony_ci	stat_buf.st_mode &= ~tc->mode_mask;
48f08c3bdfSopenharmony_ci
49f08c3bdfSopenharmony_ci	if (stat_buf.st_mode == (unsigned int)mode) {
50f08c3bdfSopenharmony_ci		tst_res(TPASS, "stat(%s) mode=%04o",
51f08c3bdfSopenharmony_ci				*tc->name, stat_buf.st_mode);
52f08c3bdfSopenharmony_ci	} else {
53f08c3bdfSopenharmony_ci		tst_res(TFAIL, "stat(%s) mode=%04o",
54f08c3bdfSopenharmony_ci				*tc->name, stat_buf.st_mode);
55f08c3bdfSopenharmony_ci	}
56f08c3bdfSopenharmony_ci}
57f08c3bdfSopenharmony_ci
58f08c3bdfSopenharmony_cistatic void setup(void)
59f08c3bdfSopenharmony_ci{
60f08c3bdfSopenharmony_ci	tst_res(TINFO, "Testing variant: %s", variants[tst_variant].desc);
61f08c3bdfSopenharmony_ci
62f08c3bdfSopenharmony_ci	if (tst_variant)
63f08c3bdfSopenharmony_ci		SAFE_MKDIR(*variants[tst_variant].name, MODE);
64f08c3bdfSopenharmony_ci	else
65f08c3bdfSopenharmony_ci		SAFE_TOUCH(*variants[tst_variant].name, MODE, NULL);
66f08c3bdfSopenharmony_ci}
67f08c3bdfSopenharmony_ci
68f08c3bdfSopenharmony_cistatic struct tst_test test = {
69f08c3bdfSopenharmony_ci	.setup = setup,
70f08c3bdfSopenharmony_ci	.test_variants = ARRAY_SIZE(variants),
71f08c3bdfSopenharmony_ci	.tcnt = ARRAY_SIZE(modes),
72f08c3bdfSopenharmony_ci	.test = verify_chmod,
73f08c3bdfSopenharmony_ci	.needs_tmpdir = 1,
74f08c3bdfSopenharmony_ci	.bufs = (struct tst_buffers []) {
75f08c3bdfSopenharmony_ci		{&test_file, .str = TESTFILE},
76f08c3bdfSopenharmony_ci		{&test_dir, .str = TESTDIR},
77f08c3bdfSopenharmony_ci		{}
78f08c3bdfSopenharmony_ci	}
79f08c3bdfSopenharmony_ci};
80