xref: /aosp_15_r20/external/ltp/testcases/kernel/syscalls/tee/tee01.c (revision 49cdfc7efb34551c7342be41a7384b9c40d7cab7)
1 // SPDX-License-Identifier: GPL-2.0-or-later
2 /*
3  * Copyright (c) International Business Machines Corp., 2006
4  * Copyright (c) 2014 Cyril Hrubis <[email protected]>
5  * Author: Yi Yang <[email protected]>
6  */
7 
8 #define _GNU_SOURCE
9 
10 #include <errno.h>
11 #include <string.h>
12 #include <signal.h>
13 #include <sys/types.h>
14 
15 #include "tst_test.h"
16 #include "lapi/fcntl.h"
17 #include "lapi/tee.h"
18 #include "lapi/splice.h"
19 
20 #define TEST_BLOCK_SIZE 1024
21 
22 #define TESTFILE1 "tee_test_file_1"
23 #define TESTFILE2 "tee_test_file_2"
24 
25 static int fd_in, fd_out;
26 static char buffer[TEST_BLOCK_SIZE];
27 
check_file(void)28 static void check_file(void)
29 {
30 	int i;
31 	char teebuffer[TEST_BLOCK_SIZE];
32 
33 	fd_out = SAFE_OPEN(TESTFILE2, O_RDONLY);
34 	SAFE_READ(1, fd_out, teebuffer, TEST_BLOCK_SIZE);
35 
36 	for (i = 0; i < TEST_BLOCK_SIZE; i++) {
37 		if (buffer[i] != teebuffer[i])
38 			break;
39 	}
40 
41 	if (i < TEST_BLOCK_SIZE)
42 		tst_res(TFAIL, "Wrong data read from the buffer at %i", i);
43 	else
44 		tst_res(TPASS, "Written data has been read back correctly");
45 
46 	SAFE_CLOSE(fd_out);
47 }
48 
tee_test(void)49 static void tee_test(void)
50 {
51 	int pipe1[2];
52 	int pipe2[2];
53 	int ret = 0;
54 
55 	fd_in = SAFE_OPEN(TESTFILE1, O_RDONLY);
56 	fd_out = SAFE_OPEN(TESTFILE2, O_WRONLY | O_CREAT | O_TRUNC, 0777);
57 
58 	SAFE_PIPE(pipe1);
59 	SAFE_PIPE(pipe2);
60 
61 	ret = splice(fd_in, NULL, pipe1[1], NULL, TEST_BLOCK_SIZE, 0);
62 	if (ret < 0)
63 		tst_brk(TBROK | TERRNO, "splice(fd_in, pipe1) failed");
64 
65 	ret = tee(pipe1[0], pipe2[1], TEST_BLOCK_SIZE, SPLICE_F_NONBLOCK);
66 	if (ret < 0)
67 		tst_brk(TBROK | TERRNO, "tee() failed");
68 
69 	ret = splice(pipe2[0], NULL, fd_out, NULL, TEST_BLOCK_SIZE, 0);
70 	if (ret < 0)
71 		tst_brk(TBROK | TERRNO, "splice(pipe2, fd_out) failed");
72 
73 	SAFE_CLOSE(pipe2[0]);
74 	SAFE_CLOSE(pipe2[1]);
75 	SAFE_CLOSE(pipe1[0]);
76 	SAFE_CLOSE(pipe1[1]);
77 	SAFE_CLOSE(fd_out);
78 	SAFE_CLOSE(fd_in);
79 
80 	check_file();
81 }
82 
setup(void)83 static void setup(void)
84 {
85 	int i;
86 
87 	for (i = 0; i < TEST_BLOCK_SIZE; i++)
88 		buffer[i] = i & 0xff;
89 
90 	fd_in = SAFE_OPEN(TESTFILE1, O_WRONLY | O_CREAT | O_TRUNC, 0777);
91 	SAFE_WRITE(SAFE_WRITE_ALL, fd_in, buffer, TEST_BLOCK_SIZE);
92 	SAFE_CLOSE(fd_in);
93 }
94 
cleanup(void)95 static void cleanup(void)
96 {
97 	if (fd_in > 0)
98 		SAFE_CLOSE(fd_in);
99 
100 	if (fd_out > 0)
101 		SAFE_CLOSE(fd_out);
102 }
103 
104 static struct tst_test test = {
105 	.setup = setup,
106 	.cleanup = cleanup,
107 	.test_all = tee_test,
108 	.needs_tmpdir = 1,
109 };
110