1 // SPDX-License-Identifier: GPL-2.0-or-later
2 /*
3 * Copyright (c) International Business Machines Corp., 2006
4 * Copyright (c) Linux Test Project, 2003-2023
5 * 08/28/2006 AUTHOR: Yi Yang <yyangcdl@cn.ibm.com>
6 */
7
8 /*\
9 * [Description]
10 *
11 * Check the basic functionality of the fchmodat() system call.
12 *
13 * - fchmodat() passes if dir_fd is file descriptor to the directory
14 * where the file is located and pathname is relative path of the file.
15 * - fchmodat() passes if pathname is absolute, then dirfd is ignored.
16 * - fchmodat() passes if dir_fd is AT_FDCWD and pathname is interpreted
17 * relative to the current working directory of the calling process.
18 */
19
20 #include <stdlib.h>
21 #include <stdio.h>
22 #include "tst_test.h"
23
24 #define TESTDIR "fchmodatdir"
25 #define TESTFILE "fchmodatfile"
26 #define FILEPATH "fchmodatdir/fchmodatfile"
27
28 static int dir_fd, file_fd;
29 static int atcwd_fd = AT_FDCWD;
30 static char *abs_path;
31 static char *test_file;
32 static char *file_path;
33
34 static struct tcase {
35 int *fd;
36 char **filenames;
37 char **full_path;
38 } tcases[] = {
39 {&dir_fd, &test_file, &file_path},
40 {&file_fd, &abs_path, &abs_path},
41 {&atcwd_fd, &file_path, &file_path},
42 };
43
verify_fchmodat(unsigned int i)44 static void verify_fchmodat(unsigned int i)
45 {
46 struct tcase *tc = &tcases[i];
47 struct stat st;
48
49 TST_EXP_PASS(fchmodat(*tc->fd, *tc->filenames, 0600, 0),
50 "fchmodat(%d, %s, 0600, 0)",
51 *tc->fd, *tc->filenames);
52
53 SAFE_LSTAT(*tc->full_path, &st);
54
55 if ((st.st_mode & ~S_IFREG) == 0600)
56 tst_res(TPASS, "File permission changed correctly");
57 else
58 tst_res(TFAIL, "File permission not changed correctly");
59 }
60
setup(void)61 static void setup(void)
62 {
63 abs_path = tst_tmpdir_genpath(FILEPATH);
64
65 SAFE_MKDIR(TESTDIR, 0700);
66 dir_fd = SAFE_OPEN(TESTDIR, O_DIRECTORY);
67 file_fd = SAFE_OPEN(FILEPATH, O_CREAT | O_RDWR, 0600);
68 }
69
cleanup(void)70 static void cleanup(void)
71 {
72 if (dir_fd > -1)
73 SAFE_CLOSE(dir_fd);
74
75 if (file_fd > -1)
76 SAFE_CLOSE(file_fd);
77 }
78
79 static struct tst_test test = {
80 .tcnt = ARRAY_SIZE(tcases),
81 .test = verify_fchmodat,
82 .setup = setup,
83 .cleanup = cleanup,
84 .bufs = (struct tst_buffers []) {
85 {&test_file, .str = TESTFILE},
86 {&file_path, .str = FILEPATH},
87 {},
88 },
89 .needs_tmpdir = 1,
90 };
91