1*49cdfc7eSAndroid Build Coastguard Worker /*
2*49cdfc7eSAndroid Build Coastguard Worker * Copyright (c) 2015-2016 Oracle and/or its affiliates. All Rights Reserved.
3*49cdfc7eSAndroid Build Coastguard Worker *
4*49cdfc7eSAndroid Build Coastguard Worker * This program is free software; you can redistribute it and/or
5*49cdfc7eSAndroid Build Coastguard Worker * modify it under the terms of the GNU General Public License as
6*49cdfc7eSAndroid Build Coastguard Worker * published by the Free Software Foundation; either version 2 of
7*49cdfc7eSAndroid Build Coastguard Worker * the License, or (at your option) any later version.
8*49cdfc7eSAndroid Build Coastguard Worker *
9*49cdfc7eSAndroid Build Coastguard Worker * This program is distributed in the hope that it would be useful,
10*49cdfc7eSAndroid Build Coastguard Worker * but WITHOUT ANY WARRANTY; without even the implied warranty of
11*49cdfc7eSAndroid Build Coastguard Worker * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12*49cdfc7eSAndroid Build Coastguard Worker * GNU General Public License for more details.
13*49cdfc7eSAndroid Build Coastguard Worker *
14*49cdfc7eSAndroid Build Coastguard Worker * You should have received a copy of the GNU General Public License
15*49cdfc7eSAndroid Build Coastguard Worker * along with this program. If not, see <http://www.gnu.org/licenses/>.
16*49cdfc7eSAndroid Build Coastguard Worker *
17*49cdfc7eSAndroid Build Coastguard Worker * Author: Alexey Kodanev <[email protected]>
18*49cdfc7eSAndroid Build Coastguard Worker *
19*49cdfc7eSAndroid Build Coastguard Worker */
20*49cdfc7eSAndroid Build Coastguard Worker
21*49cdfc7eSAndroid Build Coastguard Worker #define _GNU_SOURCE
22*49cdfc7eSAndroid Build Coastguard Worker #include <sys/types.h>
23*49cdfc7eSAndroid Build Coastguard Worker #include <sys/stat.h>
24*49cdfc7eSAndroid Build Coastguard Worker #include <unistd.h>
25*49cdfc7eSAndroid Build Coastguard Worker #include <errno.h>
26*49cdfc7eSAndroid Build Coastguard Worker
27*49cdfc7eSAndroid Build Coastguard Worker #include "test.h"
28*49cdfc7eSAndroid Build Coastguard Worker #include "safe_macros.h"
29*49cdfc7eSAndroid Build Coastguard Worker #include "lapi/fcntl.h"
30*49cdfc7eSAndroid Build Coastguard Worker #include "openat.h"
31*49cdfc7eSAndroid Build Coastguard Worker
32*49cdfc7eSAndroid Build Coastguard Worker char *TCID = "openat03";
33*49cdfc7eSAndroid Build Coastguard Worker int TST_TOTAL = 3;
34*49cdfc7eSAndroid Build Coastguard Worker static ssize_t size;
35*49cdfc7eSAndroid Build Coastguard Worker static char buf[1024];
36*49cdfc7eSAndroid Build Coastguard Worker static const ssize_t blocks_num = 4;
37*49cdfc7eSAndroid Build Coastguard Worker static struct stat st;
38*49cdfc7eSAndroid Build Coastguard Worker
cleanup(void)39*49cdfc7eSAndroid Build Coastguard Worker static void cleanup(void)
40*49cdfc7eSAndroid Build Coastguard Worker {
41*49cdfc7eSAndroid Build Coastguard Worker tst_rmdir();
42*49cdfc7eSAndroid Build Coastguard Worker }
43*49cdfc7eSAndroid Build Coastguard Worker
setup(void)44*49cdfc7eSAndroid Build Coastguard Worker static void setup(void)
45*49cdfc7eSAndroid Build Coastguard Worker {
46*49cdfc7eSAndroid Build Coastguard Worker tst_tmpdir();
47*49cdfc7eSAndroid Build Coastguard Worker
48*49cdfc7eSAndroid Build Coastguard Worker size = sizeof(buf);
49*49cdfc7eSAndroid Build Coastguard Worker
50*49cdfc7eSAndroid Build Coastguard Worker memset(buf, 1, size);
51*49cdfc7eSAndroid Build Coastguard Worker
52*49cdfc7eSAndroid Build Coastguard Worker int fd = openat(AT_FDCWD, ".", O_TMPFILE | O_RDWR, 0600);
53*49cdfc7eSAndroid Build Coastguard Worker
54*49cdfc7eSAndroid Build Coastguard Worker if (fd == -1) {
55*49cdfc7eSAndroid Build Coastguard Worker if (errno == EISDIR || errno == ENOTSUP)
56*49cdfc7eSAndroid Build Coastguard Worker tst_brkm(TCONF, cleanup, "O_TMPFILE not supported");
57*49cdfc7eSAndroid Build Coastguard Worker
58*49cdfc7eSAndroid Build Coastguard Worker tst_brkm(TBROK | TERRNO, cleanup, "openat() failed");
59*49cdfc7eSAndroid Build Coastguard Worker }
60*49cdfc7eSAndroid Build Coastguard Worker
61*49cdfc7eSAndroid Build Coastguard Worker SAFE_CLOSE(cleanup, fd);
62*49cdfc7eSAndroid Build Coastguard Worker }
63*49cdfc7eSAndroid Build Coastguard Worker
openat_tmp(int mode)64*49cdfc7eSAndroid Build Coastguard Worker static int openat_tmp(int mode)
65*49cdfc7eSAndroid Build Coastguard Worker {
66*49cdfc7eSAndroid Build Coastguard Worker int fd = openat(AT_FDCWD, ".", O_TMPFILE | O_RDWR, mode);
67*49cdfc7eSAndroid Build Coastguard Worker
68*49cdfc7eSAndroid Build Coastguard Worker if (fd >= 0)
69*49cdfc7eSAndroid Build Coastguard Worker return fd;
70*49cdfc7eSAndroid Build Coastguard Worker
71*49cdfc7eSAndroid Build Coastguard Worker tst_brkm(TBROK | TERRNO, cleanup, "openat() failed");
72*49cdfc7eSAndroid Build Coastguard Worker }
73*49cdfc7eSAndroid Build Coastguard Worker
write_file(int fd)74*49cdfc7eSAndroid Build Coastguard Worker static void write_file(int fd)
75*49cdfc7eSAndroid Build Coastguard Worker {
76*49cdfc7eSAndroid Build Coastguard Worker int i;
77*49cdfc7eSAndroid Build Coastguard Worker
78*49cdfc7eSAndroid Build Coastguard Worker for (i = 0; i < blocks_num; ++i)
79*49cdfc7eSAndroid Build Coastguard Worker SAFE_WRITE(cleanup, SAFE_WRITE_ALL, fd, buf, size);
80*49cdfc7eSAndroid Build Coastguard Worker }
81*49cdfc7eSAndroid Build Coastguard Worker
test01(void)82*49cdfc7eSAndroid Build Coastguard Worker void test01(void)
83*49cdfc7eSAndroid Build Coastguard Worker {
84*49cdfc7eSAndroid Build Coastguard Worker int fd;
85*49cdfc7eSAndroid Build Coastguard Worker char path[PATH_MAX], tmp[PATH_MAX];
86*49cdfc7eSAndroid Build Coastguard Worker
87*49cdfc7eSAndroid Build Coastguard Worker tst_resm(TINFO, "creating a file with O_TMPFILE flag");
88*49cdfc7eSAndroid Build Coastguard Worker fd = openat_tmp(0600);
89*49cdfc7eSAndroid Build Coastguard Worker
90*49cdfc7eSAndroid Build Coastguard Worker tst_resm(TINFO, "writing data to the file");
91*49cdfc7eSAndroid Build Coastguard Worker write_file(fd);
92*49cdfc7eSAndroid Build Coastguard Worker
93*49cdfc7eSAndroid Build Coastguard Worker SAFE_FSTAT(cleanup, fd, &st);
94*49cdfc7eSAndroid Build Coastguard Worker tst_resm(TINFO, "file size is '%li'", (long)st.st_size);
95*49cdfc7eSAndroid Build Coastguard Worker
96*49cdfc7eSAndroid Build Coastguard Worker if (st.st_size != blocks_num * size) {
97*49cdfc7eSAndroid Build Coastguard Worker tst_resm(TFAIL, "not expected size: '%li' != '%zu'",
98*49cdfc7eSAndroid Build Coastguard Worker (long)st.st_size, blocks_num * size);
99*49cdfc7eSAndroid Build Coastguard Worker SAFE_CLOSE(cleanup, fd);
100*49cdfc7eSAndroid Build Coastguard Worker return;
101*49cdfc7eSAndroid Build Coastguard Worker }
102*49cdfc7eSAndroid Build Coastguard Worker
103*49cdfc7eSAndroid Build Coastguard Worker tst_resm(TINFO, "looking for the file in '.'");
104*49cdfc7eSAndroid Build Coastguard Worker if (!tst_dir_is_empty(cleanup, ".", 1))
105*49cdfc7eSAndroid Build Coastguard Worker tst_brkm(TFAIL, cleanup, "found a file, this is not expected");
106*49cdfc7eSAndroid Build Coastguard Worker tst_resm(TINFO, "file not found, OK");
107*49cdfc7eSAndroid Build Coastguard Worker
108*49cdfc7eSAndroid Build Coastguard Worker snprintf(path, PATH_MAX, "/proc/self/fd/%d", fd);
109*49cdfc7eSAndroid Build Coastguard Worker SAFE_READLINK(cleanup, path, tmp, PATH_MAX);
110*49cdfc7eSAndroid Build Coastguard Worker
111*49cdfc7eSAndroid Build Coastguard Worker tst_resm(TINFO, "renaming '%s' -> 'tmpfile'", tmp);
112*49cdfc7eSAndroid Build Coastguard Worker SAFE_LINKAT(cleanup, AT_FDCWD, path, AT_FDCWD, "tmpfile",
113*49cdfc7eSAndroid Build Coastguard Worker AT_SYMLINK_FOLLOW);
114*49cdfc7eSAndroid Build Coastguard Worker
115*49cdfc7eSAndroid Build Coastguard Worker if (tst_dir_is_empty(cleanup, ".", 1))
116*49cdfc7eSAndroid Build Coastguard Worker tst_brkm(TFAIL, cleanup, "file not found");
117*49cdfc7eSAndroid Build Coastguard Worker
118*49cdfc7eSAndroid Build Coastguard Worker SAFE_UNLINK(cleanup, "tmpfile");
119*49cdfc7eSAndroid Build Coastguard Worker SAFE_CLOSE(cleanup, fd);
120*49cdfc7eSAndroid Build Coastguard Worker
121*49cdfc7eSAndroid Build Coastguard Worker tst_resm(TPASS, "single file tests passed");
122*49cdfc7eSAndroid Build Coastguard Worker }
123*49cdfc7eSAndroid Build Coastguard Worker
read_file(int fd)124*49cdfc7eSAndroid Build Coastguard Worker static void read_file(int fd)
125*49cdfc7eSAndroid Build Coastguard Worker {
126*49cdfc7eSAndroid Build Coastguard Worker int i;
127*49cdfc7eSAndroid Build Coastguard Worker char tmp[size];
128*49cdfc7eSAndroid Build Coastguard Worker
129*49cdfc7eSAndroid Build Coastguard Worker SAFE_LSEEK(cleanup, fd, 0, SEEK_SET);
130*49cdfc7eSAndroid Build Coastguard Worker
131*49cdfc7eSAndroid Build Coastguard Worker for (i = 0; i < blocks_num; ++i) {
132*49cdfc7eSAndroid Build Coastguard Worker SAFE_READ(cleanup, 0, fd, tmp, size);
133*49cdfc7eSAndroid Build Coastguard Worker if (memcmp(buf, tmp, size))
134*49cdfc7eSAndroid Build Coastguard Worker tst_brkm(TFAIL, cleanup, "got unexepected data");
135*49cdfc7eSAndroid Build Coastguard Worker }
136*49cdfc7eSAndroid Build Coastguard Worker }
137*49cdfc7eSAndroid Build Coastguard Worker
test02(void)138*49cdfc7eSAndroid Build Coastguard Worker static void test02(void)
139*49cdfc7eSAndroid Build Coastguard Worker {
140*49cdfc7eSAndroid Build Coastguard Worker const int files_num = 100;
141*49cdfc7eSAndroid Build Coastguard Worker int i, fd[files_num];
142*49cdfc7eSAndroid Build Coastguard Worker char path[PATH_MAX];
143*49cdfc7eSAndroid Build Coastguard Worker
144*49cdfc7eSAndroid Build Coastguard Worker tst_resm(TINFO, "create files in multiple directories");
145*49cdfc7eSAndroid Build Coastguard Worker for (i = 0; i < files_num; ++i) {
146*49cdfc7eSAndroid Build Coastguard Worker snprintf(path, PATH_MAX, "tst02_%d", i);
147*49cdfc7eSAndroid Build Coastguard Worker SAFE_MKDIR(cleanup, path, 0700);
148*49cdfc7eSAndroid Build Coastguard Worker SAFE_CHDIR(cleanup, path);
149*49cdfc7eSAndroid Build Coastguard Worker
150*49cdfc7eSAndroid Build Coastguard Worker fd[i] = openat_tmp(0600);
151*49cdfc7eSAndroid Build Coastguard Worker }
152*49cdfc7eSAndroid Build Coastguard Worker
153*49cdfc7eSAndroid Build Coastguard Worker tst_resm(TINFO, "removing test directories");
154*49cdfc7eSAndroid Build Coastguard Worker for (i = files_num - 1; i >= 0; --i) {
155*49cdfc7eSAndroid Build Coastguard Worker SAFE_CHDIR(cleanup, "..");
156*49cdfc7eSAndroid Build Coastguard Worker snprintf(path, PATH_MAX, "tst02_%d", i);
157*49cdfc7eSAndroid Build Coastguard Worker SAFE_RMDIR(cleanup, path);
158*49cdfc7eSAndroid Build Coastguard Worker }
159*49cdfc7eSAndroid Build Coastguard Worker
160*49cdfc7eSAndroid Build Coastguard Worker tst_resm(TINFO, "writing/reading temporary files");
161*49cdfc7eSAndroid Build Coastguard Worker for (i = 0; i < files_num; ++i) {
162*49cdfc7eSAndroid Build Coastguard Worker write_file(fd[i]);
163*49cdfc7eSAndroid Build Coastguard Worker read_file(fd[i]);
164*49cdfc7eSAndroid Build Coastguard Worker }
165*49cdfc7eSAndroid Build Coastguard Worker
166*49cdfc7eSAndroid Build Coastguard Worker tst_resm(TINFO, "closing temporary files");
167*49cdfc7eSAndroid Build Coastguard Worker for (i = 0; i < files_num; ++i)
168*49cdfc7eSAndroid Build Coastguard Worker SAFE_CLOSE(cleanup, fd[i]);
169*49cdfc7eSAndroid Build Coastguard Worker
170*49cdfc7eSAndroid Build Coastguard Worker tst_resm(TPASS, "multiple files tests passed");
171*49cdfc7eSAndroid Build Coastguard Worker }
172*49cdfc7eSAndroid Build Coastguard Worker
link_tmp_file(int fd)173*49cdfc7eSAndroid Build Coastguard Worker static void link_tmp_file(int fd)
174*49cdfc7eSAndroid Build Coastguard Worker {
175*49cdfc7eSAndroid Build Coastguard Worker char path1[PATH_MAX], path2[PATH_MAX];
176*49cdfc7eSAndroid Build Coastguard Worker
177*49cdfc7eSAndroid Build Coastguard Worker snprintf(path1, PATH_MAX, "/proc/self/fd/%d", fd);
178*49cdfc7eSAndroid Build Coastguard Worker snprintf(path2, PATH_MAX, "tmpfile_%d", fd);
179*49cdfc7eSAndroid Build Coastguard Worker
180*49cdfc7eSAndroid Build Coastguard Worker SAFE_LINKAT(cleanup, AT_FDCWD, path1, AT_FDCWD, path2,
181*49cdfc7eSAndroid Build Coastguard Worker AT_SYMLINK_FOLLOW);
182*49cdfc7eSAndroid Build Coastguard Worker }
183*49cdfc7eSAndroid Build Coastguard Worker
test03(void)184*49cdfc7eSAndroid Build Coastguard Worker static void test03(void)
185*49cdfc7eSAndroid Build Coastguard Worker {
186*49cdfc7eSAndroid Build Coastguard Worker const int files_num = 100;
187*49cdfc7eSAndroid Build Coastguard Worker const mode_t test_perms[] = { 0, 07777, 001, 0755, 0644, 0440 };
188*49cdfc7eSAndroid Build Coastguard Worker
189*49cdfc7eSAndroid Build Coastguard Worker int i, fd[files_num];
190*49cdfc7eSAndroid Build Coastguard Worker char path[PATH_MAX];
191*49cdfc7eSAndroid Build Coastguard Worker struct stat st;
192*49cdfc7eSAndroid Build Coastguard Worker mode_t mask = umask(0), perm;
193*49cdfc7eSAndroid Build Coastguard Worker
194*49cdfc7eSAndroid Build Coastguard Worker umask(mask);
195*49cdfc7eSAndroid Build Coastguard Worker
196*49cdfc7eSAndroid Build Coastguard Worker tst_resm(TINFO, "create multiple directories, link files into them");
197*49cdfc7eSAndroid Build Coastguard Worker tst_resm(TINFO, "and check file permissions");
198*49cdfc7eSAndroid Build Coastguard Worker for (i = 0; i < files_num; ++i) {
199*49cdfc7eSAndroid Build Coastguard Worker
200*49cdfc7eSAndroid Build Coastguard Worker snprintf(path, PATH_MAX, "tst03_%d", i);
201*49cdfc7eSAndroid Build Coastguard Worker SAFE_MKDIR(cleanup, path, 0700);
202*49cdfc7eSAndroid Build Coastguard Worker SAFE_CHDIR(cleanup, path);
203*49cdfc7eSAndroid Build Coastguard Worker
204*49cdfc7eSAndroid Build Coastguard Worker perm = test_perms[i % ARRAY_SIZE(test_perms)];
205*49cdfc7eSAndroid Build Coastguard Worker
206*49cdfc7eSAndroid Build Coastguard Worker fd[i] = openat_tmp(perm);
207*49cdfc7eSAndroid Build Coastguard Worker
208*49cdfc7eSAndroid Build Coastguard Worker write_file(fd[i]);
209*49cdfc7eSAndroid Build Coastguard Worker read_file(fd[i]);
210*49cdfc7eSAndroid Build Coastguard Worker
211*49cdfc7eSAndroid Build Coastguard Worker link_tmp_file(fd[i]);
212*49cdfc7eSAndroid Build Coastguard Worker
213*49cdfc7eSAndroid Build Coastguard Worker snprintf(path, PATH_MAX, "tmpfile_%d", fd[i]);
214*49cdfc7eSAndroid Build Coastguard Worker
215*49cdfc7eSAndroid Build Coastguard Worker SAFE_LSTAT(cleanup, path, &st);
216*49cdfc7eSAndroid Build Coastguard Worker
217*49cdfc7eSAndroid Build Coastguard Worker mode_t exp_mode = perm & ~mask;
218*49cdfc7eSAndroid Build Coastguard Worker
219*49cdfc7eSAndroid Build Coastguard Worker if ((st.st_mode & ~S_IFMT) != exp_mode) {
220*49cdfc7eSAndroid Build Coastguard Worker tst_brkm(TFAIL, cleanup,
221*49cdfc7eSAndroid Build Coastguard Worker "file mode read %o, but expected %o",
222*49cdfc7eSAndroid Build Coastguard Worker st.st_mode & ~S_IFMT, exp_mode);
223*49cdfc7eSAndroid Build Coastguard Worker }
224*49cdfc7eSAndroid Build Coastguard Worker }
225*49cdfc7eSAndroid Build Coastguard Worker
226*49cdfc7eSAndroid Build Coastguard Worker tst_resm(TINFO, "remove files, directories");
227*49cdfc7eSAndroid Build Coastguard Worker for (i = files_num - 1; i >= 0; --i) {
228*49cdfc7eSAndroid Build Coastguard Worker snprintf(path, PATH_MAX, "tmpfile_%d", fd[i]);
229*49cdfc7eSAndroid Build Coastguard Worker SAFE_UNLINK(cleanup, path);
230*49cdfc7eSAndroid Build Coastguard Worker SAFE_CLOSE(cleanup, fd[i]);
231*49cdfc7eSAndroid Build Coastguard Worker
232*49cdfc7eSAndroid Build Coastguard Worker SAFE_CHDIR(cleanup, "..");
233*49cdfc7eSAndroid Build Coastguard Worker
234*49cdfc7eSAndroid Build Coastguard Worker snprintf(path, PATH_MAX, "tst03_%d", i);
235*49cdfc7eSAndroid Build Coastguard Worker SAFE_RMDIR(cleanup, path);
236*49cdfc7eSAndroid Build Coastguard Worker }
237*49cdfc7eSAndroid Build Coastguard Worker
238*49cdfc7eSAndroid Build Coastguard Worker tst_resm(TPASS, "file permission tests passed");
239*49cdfc7eSAndroid Build Coastguard Worker }
240*49cdfc7eSAndroid Build Coastguard Worker
main(int ac,char * av[])241*49cdfc7eSAndroid Build Coastguard Worker int main(int ac, char *av[])
242*49cdfc7eSAndroid Build Coastguard Worker {
243*49cdfc7eSAndroid Build Coastguard Worker int lc;
244*49cdfc7eSAndroid Build Coastguard Worker
245*49cdfc7eSAndroid Build Coastguard Worker tst_parse_opts(ac, av, NULL, NULL);
246*49cdfc7eSAndroid Build Coastguard Worker
247*49cdfc7eSAndroid Build Coastguard Worker setup();
248*49cdfc7eSAndroid Build Coastguard Worker
249*49cdfc7eSAndroid Build Coastguard Worker for (lc = 0; TEST_LOOPING(lc); ++lc) {
250*49cdfc7eSAndroid Build Coastguard Worker tst_count = 0;
251*49cdfc7eSAndroid Build Coastguard Worker test01();
252*49cdfc7eSAndroid Build Coastguard Worker test02();
253*49cdfc7eSAndroid Build Coastguard Worker test03();
254*49cdfc7eSAndroid Build Coastguard Worker }
255*49cdfc7eSAndroid Build Coastguard Worker
256*49cdfc7eSAndroid Build Coastguard Worker cleanup();
257*49cdfc7eSAndroid Build Coastguard Worker tst_exit();
258*49cdfc7eSAndroid Build Coastguard Worker }
259