xref: /aosp_15_r20/external/ltp/testcases/kernel/syscalls/open_by_handle_at/open_by_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 open_by_handle_at() tests.
10  *
11  * [Algorithm]
12  *
13  * Check that we were able to access a file's stat which is opened with
14  * 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 *f_fhp, *d_fhp, *at_fhp;
26 static struct file_handle *f_fhp, *d_fhp, *at_fhp;
27 
28 static struct tcase {
29 	int *dfd;
30 	struct file_handle **fhp;
31 	int flags;
32 } tcases[] = {
33 	{&dir_fd, &d_fhp, O_RDWR},
34 	{&dir_fd, &d_fhp, O_RDONLY},
35 	{&dir_fd, &d_fhp, O_WRONLY},
36 	{&file_fd, &f_fhp, O_RDWR},
37 	{&file_fd, &f_fhp, O_RDONLY},
38 	{&file_fd, &f_fhp, O_WRONLY},
39 	{&fd_atcwd, &at_fhp, O_RDWR},
40 	{&fd_atcwd, &at_fhp, O_RDONLY},
41 	{&fd_atcwd, &at_fhp, O_WRONLY},
42 };
43 
cleanup(void)44 static void cleanup(void)
45 {
46 	SAFE_CLOSE(dir_fd);
47 	SAFE_CLOSE(file_fd);
48 }
49 
setup(void)50 static void setup(void)
51 {
52 	int mount_id;
53 
54 	SAFE_MKDIR(TEST_DIR, 0700);
55 	dir_fd = SAFE_OPEN(TEST_DIR, O_DIRECTORY);
56 	SAFE_CHDIR(TEST_DIR);
57 	SAFE_TOUCH(TEST_FILE, 0600, NULL);
58 	file_fd = SAFE_OPEN("foo_file", O_RDWR | O_CREAT, 0600);
59 
60 	f_fhp = allocate_file_handle(AT_FDCWD, TEST_FILE);
61 	d_fhp = allocate_file_handle(AT_FDCWD, TEST_FILE);
62 	at_fhp = allocate_file_handle(AT_FDCWD, TEST_FILE);
63 
64 	TEST(name_to_handle_at(file_fd, "", f_fhp, &mount_id, AT_EMPTY_PATH));
65 	if (TST_RET) {
66 		tst_res(TFAIL | TTERRNO, "name_to_handle_at() failed");
67 		return;
68 	}
69 
70 	TEST(name_to_handle_at(dir_fd, TEST_FILE, d_fhp, &mount_id,
71 			       AT_EMPTY_PATH | AT_SYMLINK_FOLLOW));
72 	if (TST_RET) {
73 		tst_res(TFAIL | TTERRNO, "name_to_handle_at() failed");
74 		return;
75 	}
76 
77 	TEST(name_to_handle_at(AT_FDCWD, TEST_FILE, at_fhp, &mount_id,
78 			       AT_EMPTY_PATH | AT_SYMLINK_FOLLOW));
79 	if (TST_RET) {
80 		tst_res(TFAIL | TTERRNO, "name_to_handle_at() failed");
81 		return;
82 	}
83 }
84 
run(unsigned int n)85 static void run(unsigned int n)
86 {
87 	struct tcase *tc = &tcases[n];
88 	struct stat file_stat;
89 	int fd;
90 
91 	TEST(fd = open_by_handle_at(*tc->dfd, *tc->fhp, tc->flags));
92 	if (fd < 0) {
93 		tst_res(TFAIL | TTERRNO, "open_by_handle_at() failed (%d)", n);
94 		return;
95 	}
96 
97 	SAFE_FSTAT(fd, &file_stat);
98 
99 	/* Don't check stats when pathname is empty */
100 	if (file_stat.st_size == 0 || (tc->fhp == &f_fhp))
101 		tst_res(TPASS, "open_by_handle_at() passed (%d)", n);
102 	else
103 		tst_res(TFAIL, "fstat() didn't work as expected (%d)", n);
104 
105 	SAFE_CLOSE(fd);
106 }
107 
108 static struct tst_test test = {
109 	.tcnt = ARRAY_SIZE(tcases),
110 	.test = run,
111 	.setup = setup,
112 	.cleanup = cleanup,
113 	.needs_tmpdir = 1,
114 	.needs_root = 1,
115 };
116