1f08c3bdfSopenharmony_ci// SPDX-License-Identifier: GPL-2.0-or-later
2f08c3bdfSopenharmony_ci/*
3f08c3bdfSopenharmony_ci * Copyright (c) International Business Machines  Corp., 2006
4f08c3bdfSopenharmony_ci *
5f08c3bdfSopenharmony_ci * 08/28/2006 AUTHOR: Yi Yang <yyangcdl@cn.ibm.com>
6f08c3bdfSopenharmony_ci */
7f08c3bdfSopenharmony_ci
8f08c3bdfSopenharmony_ci/*\
9f08c3bdfSopenharmony_ci * [Description]
10f08c3bdfSopenharmony_ci *
11f08c3bdfSopenharmony_ci * This test case will verify basic function of fchmodat.
12f08c3bdfSopenharmony_ci */
13f08c3bdfSopenharmony_ci
14f08c3bdfSopenharmony_ci#define _GNU_SOURCE
15f08c3bdfSopenharmony_ci
16f08c3bdfSopenharmony_ci#include <unistd.h>
17f08c3bdfSopenharmony_ci#include <string.h>
18f08c3bdfSopenharmony_ci#include <stdlib.h>
19f08c3bdfSopenharmony_ci#include <stdio.h>
20f08c3bdfSopenharmony_ci#include "tst_test.h"
21f08c3bdfSopenharmony_ci#include "lapi/syscalls.h"
22f08c3bdfSopenharmony_ci
23f08c3bdfSopenharmony_ci#ifndef AT_FDCWD
24f08c3bdfSopenharmony_ci#define AT_FDCWD -100
25f08c3bdfSopenharmony_ci#endif
26f08c3bdfSopenharmony_ci
27f08c3bdfSopenharmony_cistatic char pathname[256];
28f08c3bdfSopenharmony_cistatic char testfile[256];
29f08c3bdfSopenharmony_cistatic char testfile2[256];
30f08c3bdfSopenharmony_cistatic char testfile3[256];
31f08c3bdfSopenharmony_ci
32f08c3bdfSopenharmony_cistatic struct tcase {
33f08c3bdfSopenharmony_ci	int exp_errno;
34f08c3bdfSopenharmony_ci	char *exp_errval;
35f08c3bdfSopenharmony_ci} tcases[] = {
36f08c3bdfSopenharmony_ci	{ 0, NULL},
37f08c3bdfSopenharmony_ci	{ 0, NULL},
38f08c3bdfSopenharmony_ci	{ ENOTDIR, "ENOTDIR"},
39f08c3bdfSopenharmony_ci	{ EBADF, "EBADF"},
40f08c3bdfSopenharmony_ci	{ 0, NULL},
41f08c3bdfSopenharmony_ci	{ 0, NULL},
42f08c3bdfSopenharmony_ci};
43f08c3bdfSopenharmony_cistatic int fds[ARRAY_SIZE(tcases)];
44f08c3bdfSopenharmony_cistatic char *filenames[ARRAY_SIZE(tcases)];
45f08c3bdfSopenharmony_ci
46f08c3bdfSopenharmony_cistatic void verify_fchmodat(unsigned int i)
47f08c3bdfSopenharmony_ci{
48f08c3bdfSopenharmony_ci	struct tcase *tc = &tcases[i];
49f08c3bdfSopenharmony_ci
50f08c3bdfSopenharmony_ci	if (tc->exp_errno == 0)
51f08c3bdfSopenharmony_ci		TST_EXP_PASS(tst_syscall(__NR_fchmodat, fds[i], filenames[i], 0600),
52f08c3bdfSopenharmony_ci			     "fchmodat() returned the expected errno %d: %s",
53f08c3bdfSopenharmony_ci			     TST_ERR, strerror(TST_ERR));
54f08c3bdfSopenharmony_ci	else
55f08c3bdfSopenharmony_ci		TST_EXP_FAIL(tst_syscall(__NR_fchmodat, fds[i], filenames[i], 0600),
56f08c3bdfSopenharmony_ci			     tc->exp_errno,
57f08c3bdfSopenharmony_ci			     "fchmodat() returned the expected errno %d: %s",
58f08c3bdfSopenharmony_ci			     TST_ERR, strerror(TST_ERR));
59f08c3bdfSopenharmony_ci}
60f08c3bdfSopenharmony_ci
61f08c3bdfSopenharmony_cistatic void setup(void)
62f08c3bdfSopenharmony_ci{
63f08c3bdfSopenharmony_ci	/* Initialize test dir and file names */
64f08c3bdfSopenharmony_ci	char *abs_path = tst_get_tmpdir();
65f08c3bdfSopenharmony_ci	int p = getpid();
66f08c3bdfSopenharmony_ci
67f08c3bdfSopenharmony_ci	sprintf(pathname, "fchmodattestdir%d", p);
68f08c3bdfSopenharmony_ci	sprintf(testfile, "fchmodattest%d.txt", p);
69f08c3bdfSopenharmony_ci	sprintf(testfile2, "%s/fchmodattest%d.txt", abs_path, p);
70f08c3bdfSopenharmony_ci	sprintf(testfile3, "fchmodattestdir%d/fchmodattest%d.txt", p, p);
71f08c3bdfSopenharmony_ci
72f08c3bdfSopenharmony_ci	free(abs_path);
73f08c3bdfSopenharmony_ci
74f08c3bdfSopenharmony_ci	SAFE_MKDIR(pathname, 0700);
75f08c3bdfSopenharmony_ci
76f08c3bdfSopenharmony_ci	fds[0] = SAFE_OPEN(pathname, O_DIRECTORY);
77f08c3bdfSopenharmony_ci	fds[1] = fds[4] = fds[0];
78f08c3bdfSopenharmony_ci
79f08c3bdfSopenharmony_ci	SAFE_FILE_PRINTF(testfile, "%s", testfile);
80f08c3bdfSopenharmony_ci	SAFE_FILE_PRINTF(testfile2, "%s", testfile2);
81f08c3bdfSopenharmony_ci
82f08c3bdfSopenharmony_ci	fds[2] = SAFE_OPEN(testfile3, O_CREAT | O_RDWR, 0600);
83f08c3bdfSopenharmony_ci	fds[3] = 100;
84f08c3bdfSopenharmony_ci	fds[5] = AT_FDCWD;
85f08c3bdfSopenharmony_ci
86f08c3bdfSopenharmony_ci	filenames[0] = filenames[2] = filenames[3] = filenames[4] = testfile;
87f08c3bdfSopenharmony_ci	filenames[1] = testfile2;
88f08c3bdfSopenharmony_ci	filenames[5] = testfile3;
89f08c3bdfSopenharmony_ci}
90f08c3bdfSopenharmony_ci
91f08c3bdfSopenharmony_cistatic void cleanup(void)
92f08c3bdfSopenharmony_ci{
93f08c3bdfSopenharmony_ci	if (fds[0] > 0)
94f08c3bdfSopenharmony_ci		close(fds[0]);
95f08c3bdfSopenharmony_ci	if (fds[2] > 0)
96f08c3bdfSopenharmony_ci		close(fds[2]);
97f08c3bdfSopenharmony_ci}
98f08c3bdfSopenharmony_ci
99f08c3bdfSopenharmony_cistatic struct tst_test test = {
100f08c3bdfSopenharmony_ci	.tcnt = ARRAY_SIZE(tcases),
101f08c3bdfSopenharmony_ci	.test = verify_fchmodat,
102f08c3bdfSopenharmony_ci	.setup = setup,
103f08c3bdfSopenharmony_ci	.cleanup = cleanup,
104f08c3bdfSopenharmony_ci	.needs_tmpdir = 1,
105f08c3bdfSopenharmony_ci};
106