xref: /aosp_15_r20/external/ltp/testcases/kernel/syscalls/name_to_handle_at/name_to_handle_at01.c (revision 49cdfc7efb34551c7342be41a7384b9c40d7cab7)
1 // SPDX-License-Identifier: GPL-2.0-or-later
2 /*
3  * Copyright (c) 2020 Viresh Kumar <[email protected]>
4  */
5 
6 /*\
7  * [Description]
8  *
9  * Basic name_to_handle_at() tests.
10  *
11  * [Algorithm]
12  *  - Check that EOVERFLOW is returned as expected by name_to_handle_at().
13  *  - Check that we were able to access a file's stat with name_to_handle_at()
14  *    and open_by_handle_at().
15  */
16 
17 #define _GNU_SOURCE
18 #include <sys/stat.h>
19 #include "lapi/name_to_handle_at.h"
20 
21 #define TEST_FILE "test_file"
22 #define TEST_DIR "test_dir"
23 
24 static int dir_fd, fd_atcwd = AT_FDCWD, file_fd;
25 static struct file_handle *fhp;
26 
27 static struct tcase {
28 	int *dfd;
29 	const char *pathname;
30 	int name_flags;
31 	int flags;
32 } tcases[] = {
33 	{&dir_fd, TEST_FILE, 0, O_RDWR},
34 	{&dir_fd, TEST_FILE, 0, O_RDONLY},
35 	{&dir_fd, TEST_FILE, 0, O_WRONLY},
36 	{&dir_fd, TEST_FILE, AT_EMPTY_PATH, O_RDWR},
37 	{&dir_fd, TEST_FILE, AT_EMPTY_PATH, O_RDONLY},
38 	{&dir_fd, TEST_FILE, AT_EMPTY_PATH, O_WRONLY},
39 	{&dir_fd, TEST_FILE, AT_SYMLINK_FOLLOW, O_RDWR},
40 	{&dir_fd, TEST_FILE, AT_SYMLINK_FOLLOW, O_RDONLY},
41 	{&dir_fd, TEST_FILE, AT_SYMLINK_FOLLOW, O_WRONLY},
42 	{&dir_fd, TEST_FILE, AT_EMPTY_PATH | AT_SYMLINK_FOLLOW, O_RDWR},
43 	{&dir_fd, TEST_FILE, AT_EMPTY_PATH | AT_SYMLINK_FOLLOW, O_RDONLY},
44 	{&dir_fd, TEST_FILE, AT_EMPTY_PATH | AT_SYMLINK_FOLLOW, O_WRONLY},
45 	{&dir_fd, "", AT_EMPTY_PATH, O_RDONLY},
46 	{&file_fd, "", AT_EMPTY_PATH, O_RDONLY},
47 
48 	{&fd_atcwd, TEST_FILE, 0, O_RDWR},
49 	{&fd_atcwd, TEST_FILE, 0, O_RDONLY},
50 	{&fd_atcwd, TEST_FILE, 0, O_WRONLY},
51 	{&fd_atcwd, TEST_FILE, AT_EMPTY_PATH, O_RDWR},
52 	{&fd_atcwd, TEST_FILE, AT_EMPTY_PATH, O_RDONLY},
53 	{&fd_atcwd, TEST_FILE, AT_EMPTY_PATH, O_WRONLY},
54 	{&fd_atcwd, TEST_FILE, AT_SYMLINK_FOLLOW, O_RDWR},
55 	{&fd_atcwd, TEST_FILE, AT_SYMLINK_FOLLOW, O_RDONLY},
56 	{&fd_atcwd, TEST_FILE, AT_SYMLINK_FOLLOW, O_WRONLY},
57 	{&fd_atcwd, TEST_FILE, AT_EMPTY_PATH | AT_SYMLINK_FOLLOW, O_RDWR},
58 	{&fd_atcwd, TEST_FILE, AT_EMPTY_PATH | AT_SYMLINK_FOLLOW, O_RDONLY},
59 	{&fd_atcwd, TEST_FILE, AT_EMPTY_PATH | AT_SYMLINK_FOLLOW, O_WRONLY},
60 	{&fd_atcwd, "", AT_EMPTY_PATH, O_RDONLY},
61 };
62 
cleanup(void)63 static void cleanup(void)
64 {
65 	SAFE_CLOSE(dir_fd);
66 	SAFE_CLOSE(file_fd);
67 }
68 
setup(void)69 static void setup(void)
70 {
71 	SAFE_MKDIR(TEST_DIR, 0700);
72 	dir_fd = SAFE_OPEN(TEST_DIR, O_DIRECTORY);
73 	SAFE_CHDIR(TEST_DIR);
74 	SAFE_TOUCH(TEST_FILE, 0600, NULL);
75 	file_fd = SAFE_OPEN("foo_file", O_RDWR | O_CREAT, 0600);
76 	fhp = allocate_file_handle(AT_FDCWD, TEST_FILE);
77 }
78 
run(unsigned int n)79 static void run(unsigned int n)
80 {
81 	struct tcase *tc = &tcases[n];
82 	struct stat file_stat;
83 	int fd, mount_id;
84 
85 	TEST(name_to_handle_at(*tc->dfd, tc->pathname, fhp, &mount_id,
86 			       tc->name_flags));
87 	if (TST_RET) {
88 		tst_res(TFAIL | TTERRNO, "name_to_handle_at() failed (%d)", n);
89 		return;
90 	}
91 
92 	TEST(fd = open_by_handle_at(*tc->dfd, fhp, tc->flags));
93 	if (fd < 0) {
94 		tst_res(TFAIL | TTERRNO, "open_by_handle_at() failed (%d)", n);
95 		return;
96 	}
97 
98 	SAFE_FSTAT(fd, &file_stat);
99 
100 	/* Don't check stats when pathname is empty */
101 	if (file_stat.st_size == 0 || !tc->pathname[0])
102 		tst_res(TPASS, "name_to_handle_at() passed (%d)", n);
103 	else
104 		tst_res(TFAIL, "fstat() didn't work as expected (%d)", n);
105 
106 	SAFE_CLOSE(fd);
107 }
108 
109 static struct tst_test test = {
110 	.tcnt = ARRAY_SIZE(tcases),
111 	.test = run,
112 	.setup = setup,
113 	.cleanup = cleanup,
114 	.needs_tmpdir = 1,
115 	.needs_root = 1,
116 };
117