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 <[email protected]>
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 char *tmpdir_path = tst_get_tmpdir();
64
65 abs_path = tst_aprintf("%s/%s", tmpdir_path, FILEPATH);
66 free(tmpdir_path);
67
68 SAFE_MKDIR(TESTDIR, 0700);
69 dir_fd = SAFE_OPEN(TESTDIR, O_DIRECTORY);
70 file_fd = SAFE_OPEN(FILEPATH, O_CREAT | O_RDWR, 0600);
71 }
72
cleanup(void)73 static void cleanup(void)
74 {
75 if (dir_fd > -1)
76 SAFE_CLOSE(dir_fd);
77
78 if (file_fd > -1)
79 SAFE_CLOSE(file_fd);
80 }
81
82 static struct tst_test test = {
83 .tcnt = ARRAY_SIZE(tcases),
84 .test = verify_fchmodat,
85 .setup = setup,
86 .cleanup = cleanup,
87 .bufs = (struct tst_buffers []) {
88 {&test_file, .str = TESTFILE},
89 {&file_path, .str = FILEPATH},
90 {},
91 },
92 .needs_tmpdir = 1,
93 };
94