• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 // SPDX-License-Identifier: GPL-2.0-or-later
2 /*
3  * Copyright (c) 2020 Viresh Kumar <viresh.kumar@linaro.org>
4  *
5  * Basic openat2() test.
6  */
7 #include "tst_test.h"
8 #include "lapi/openat2.h"
9 
10 #define TEST_FILE "test_file"
11 #define TEST_DIR "test_dir"
12 
13 static struct open_how *how;
14 static struct open_how_pad *phow;
15 
16 static int dir_fd = -1, fd_atcwd = AT_FDCWD;
17 
18 static struct tcase {
19 	int *dfd;
20 	const char *pathname;
21 	uint64_t flags;
22 	uint64_t mode;
23 	uint64_t resolve;
24 	struct open_how **how;
25 	size_t size;
26 } tcases[] = {
27 	{&dir_fd, TEST_FILE, O_RDWR, S_IRWXU, 0, &how, sizeof(*how)},
28 	{&dir_fd, TEST_FILE, O_RDONLY, S_IRUSR, 0, &how, sizeof(*how)},
29 	{&dir_fd, TEST_FILE, O_WRONLY, S_IWUSR, 0, &how, sizeof(*how)},
30 	{&dir_fd, TEST_FILE, O_RDWR, S_IRWXU, RESOLVE_NO_XDEV, &how, sizeof(*how)},
31 	{&dir_fd, TEST_FILE, O_RDWR, S_IRWXU, RESOLVE_NO_MAGICLINKS, &how, sizeof(*how)},
32 	{&dir_fd, TEST_FILE, O_RDWR, S_IRWXU, RESOLVE_NO_SYMLINKS, &how, sizeof(*how)},
33 	{&dir_fd, TEST_FILE, O_RDWR, S_IRWXU, RESOLVE_BENEATH, &how, sizeof(*how)},
34 	{&dir_fd, TEST_FILE, O_RDWR, S_IRWXU, RESOLVE_IN_ROOT, &how, sizeof(*how)},
35 	{&fd_atcwd, TEST_FILE, O_RDWR, S_IRWXU, 0, &how, sizeof(*how)},
36 	{&fd_atcwd, TEST_FILE, O_RDONLY, S_IRUSR, 0, &how, sizeof(*how)},
37 	{&fd_atcwd, TEST_FILE, O_WRONLY, S_IWUSR, 0, &how, sizeof(*how)},
38 	{&fd_atcwd, TEST_FILE, O_RDWR, S_IRWXU, RESOLVE_NO_XDEV, &how, sizeof(*how)},
39 	{&fd_atcwd, TEST_FILE, O_RDWR, S_IRWXU, RESOLVE_NO_MAGICLINKS, &how, sizeof(*how)},
40 	{&fd_atcwd, TEST_FILE, O_RDWR, S_IRWXU, RESOLVE_NO_SYMLINKS, &how, sizeof(*how)},
41 	{&fd_atcwd, TEST_FILE, O_RDWR, S_IRWXU, RESOLVE_BENEATH, &how, sizeof(*how)},
42 	{&fd_atcwd, TEST_FILE, O_RDWR, S_IRWXU, RESOLVE_IN_ROOT, (struct open_how **)&phow, sizeof(*how) + 8},
43 };
44 
cleanup(void)45 static void cleanup(void)
46 {
47 	if (dir_fd != -1)
48 		SAFE_CLOSE(dir_fd);
49 }
50 
setup(void)51 static void setup(void)
52 {
53 	openat2_supported_by_kernel();
54 
55 	phow->pad = 0x00;
56 	SAFE_MKDIR(TEST_DIR, 0700);
57 	dir_fd = SAFE_OPEN(TEST_DIR, O_DIRECTORY);
58 }
59 
run(unsigned int n)60 static void run(unsigned int n)
61 {
62 	int fd;
63 	struct stat file_stat;
64 	struct tcase *tc = &tcases[n];
65 	struct open_how *myhow = *tc->how;
66 
67 	myhow->flags = tc->flags | O_CREAT;
68 	myhow->mode = tc->mode;
69 	myhow->resolve = tc->resolve;
70 
71 	TEST(fd = openat2(*tc->dfd, tc->pathname, myhow, tc->size));
72 	if (fd < 0) {
73 		tst_res(TFAIL | TTERRNO, "openat2() failed (%d)", n);
74 		return;
75 	}
76 
77 	SAFE_FSTAT(fd, &file_stat);
78 
79 	if (file_stat.st_size == 0)
80 		tst_res(TPASS, "openat2() passed (%d)", n);
81 	else
82 		tst_res(TFAIL, "fstat() didn't work as expected (%d)", n);
83 
84 	SAFE_CLOSE(fd);
85 }
86 
87 static struct tst_test test = {
88 	.tcnt = ARRAY_SIZE(tcases),
89 	.test = run,
90 	.setup = setup,
91 	.cleanup = cleanup,
92 	.needs_tmpdir = 1,
93 	.bufs = (struct tst_buffers []) {
94 		{&how, .size = sizeof(*how)},
95 		{&phow, .size = sizeof(*phow)},
96 		{},
97 	},
98 };
99