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 * Author: Yi Yang <[email protected]>
6 */
7
8 /*\
9 * [Description]
10 *
11 * Check the basic functionality of the faccessat() system call.
12 *
13 * - faccessat() 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 *
16 * - faccessat() passes if dir_fd is a bad file descriptor and pathname is
17 * absolute path of the file.
18 *
19 * - faccessat() passes if dir_fd is AT_FDCWD and pathname is interpreted
20 * relative to the current working directory of the calling process.
21 */
22
23 #include <stdlib.h>
24 #include <stdio.h>
25 #include "tst_test.h"
26
27 #define TESTDIR "faccessatdir"
28 #define TESTFILE "faccessatfile"
29 #define FILEPATH "faccessatdir/faccessatfile"
30
31 static int dir_fd, file_fd;
32 static int atcwd_fd = AT_FDCWD;
33 static char *abs_path;
34 static char *test_file;
35 static char *file_path;
36
37 static struct tcase {
38 int *fd;
39 char **filename;
40 int exp_errno;
41 } tcases[] = {
42 {&dir_fd, &test_file, 0},
43 {&dir_fd, &abs_path, 0},
44 {&atcwd_fd, &file_path, 0},
45 };
46
verify_faccessat(unsigned int i)47 static void verify_faccessat(unsigned int i)
48 {
49 struct tcase *tc = &tcases[i];
50
51 TST_EXP_PASS(faccessat(*tc->fd, *tc->filename, R_OK, 0),
52 "faccessat(%d, %s, R_OK, 0)",
53 *tc->fd, *tc->filename);
54 }
55
setup(void)56 static void setup(void)
57 {
58 char *tmpdir_path = tst_get_tmpdir();
59
60 abs_path = tst_aprintf("%s/%s", tmpdir_path, FILEPATH);
61 free(tmpdir_path);
62
63 SAFE_MKDIR(TESTDIR, 0700);
64 dir_fd = SAFE_OPEN(TESTDIR, O_DIRECTORY);
65 file_fd = SAFE_OPEN(FILEPATH, O_CREAT | O_RDWR, 0600);
66 }
67
cleanup(void)68 static void cleanup(void)
69 {
70 if (dir_fd > -1)
71 SAFE_CLOSE(dir_fd);
72
73 if (file_fd > -1)
74 SAFE_CLOSE(file_fd);
75 }
76
77 static struct tst_test test = {
78 .test = verify_faccessat,
79 .tcnt = ARRAY_SIZE(tcases),
80 .setup = setup,
81 .cleanup = cleanup,
82 .bufs = (struct tst_buffers []) {
83 {&test_file, .str = TESTFILE},
84 {&file_path, .str = FILEPATH},
85 {},
86 },
87 .needs_tmpdir = 1,
88 };
89