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