1f08c3bdfSopenharmony_ci// SPDX-License-Identifier: GPL-2.0-or-later
2f08c3bdfSopenharmony_ci/*
3f08c3bdfSopenharmony_ci * Copyright (c) International Business Machines Corp., 2006
4f08c3bdfSopenharmony_ci *  Author Yi Yang <yyangcdl@cn.ibm.com>
5f08c3bdfSopenharmony_ci */
6f08c3bdfSopenharmony_ci/*
7f08c3bdfSopenharmony_ci * DESCRIPTION
8f08c3bdfSopenharmony_ci *	This test case will verify basic function of splice
9f08c3bdfSopenharmony_ci *	added by kernel 2.6.17 or up.
10f08c3bdfSopenharmony_ci *
11f08c3bdfSopenharmony_ci */
12f08c3bdfSopenharmony_ci
13f08c3bdfSopenharmony_ci#define _GNU_SOURCE
14f08c3bdfSopenharmony_ci
15f08c3bdfSopenharmony_ci#include <errno.h>
16f08c3bdfSopenharmony_ci#include <string.h>
17f08c3bdfSopenharmony_ci#include <signal.h>
18f08c3bdfSopenharmony_ci#include <sys/types.h>
19f08c3bdfSopenharmony_ci#include <fcntl.h>
20f08c3bdfSopenharmony_ci
21f08c3bdfSopenharmony_ci#include "tst_test.h"
22f08c3bdfSopenharmony_ci#include "lapi/splice.h"
23f08c3bdfSopenharmony_ci
24f08c3bdfSopenharmony_ci#define TEST_BLOCK_SIZE 1024
25f08c3bdfSopenharmony_ci
26f08c3bdfSopenharmony_ci#define TESTFILE1 "splice_testfile_1"
27f08c3bdfSopenharmony_ci#define TESTFILE2 "splice_testfile_2"
28f08c3bdfSopenharmony_ci
29f08c3bdfSopenharmony_cistatic char buffer[TEST_BLOCK_SIZE];
30f08c3bdfSopenharmony_cistatic int fd_in, fd_out;
31f08c3bdfSopenharmony_ci
32f08c3bdfSopenharmony_cistatic void check_file(void)
33f08c3bdfSopenharmony_ci{
34f08c3bdfSopenharmony_ci	int i;
35f08c3bdfSopenharmony_ci	char splicebuffer[TEST_BLOCK_SIZE];
36f08c3bdfSopenharmony_ci
37f08c3bdfSopenharmony_ci	fd_out = SAFE_OPEN(TESTFILE2, O_RDONLY);
38f08c3bdfSopenharmony_ci	SAFE_READ(1, fd_out, splicebuffer, TEST_BLOCK_SIZE);
39f08c3bdfSopenharmony_ci
40f08c3bdfSopenharmony_ci	for (i = 0; i < TEST_BLOCK_SIZE; i++) {
41f08c3bdfSopenharmony_ci		if (buffer[i] != splicebuffer[i])
42f08c3bdfSopenharmony_ci			break;
43f08c3bdfSopenharmony_ci	}
44f08c3bdfSopenharmony_ci
45f08c3bdfSopenharmony_ci	if (i < TEST_BLOCK_SIZE)
46f08c3bdfSopenharmony_ci		tst_res(TFAIL, "Wrong data read from the buffer at %i", i);
47f08c3bdfSopenharmony_ci	else
48f08c3bdfSopenharmony_ci		tst_res(TPASS, "Written data has been read back correctly");
49f08c3bdfSopenharmony_ci
50f08c3bdfSopenharmony_ci	SAFE_CLOSE(fd_out);
51f08c3bdfSopenharmony_ci}
52f08c3bdfSopenharmony_ci
53f08c3bdfSopenharmony_cistatic void splice_test(void)
54f08c3bdfSopenharmony_ci{
55f08c3bdfSopenharmony_ci	int pipes[2];
56f08c3bdfSopenharmony_ci	int ret;
57f08c3bdfSopenharmony_ci
58f08c3bdfSopenharmony_ci	fd_in = SAFE_OPEN(TESTFILE1, O_RDONLY);
59f08c3bdfSopenharmony_ci	fd_out = SAFE_OPEN(TESTFILE2, O_WRONLY | O_CREAT | O_TRUNC, 0666);
60f08c3bdfSopenharmony_ci	SAFE_PIPE(pipes);
61f08c3bdfSopenharmony_ci
62f08c3bdfSopenharmony_ci	ret = splice(fd_in, NULL, pipes[1], NULL, TEST_BLOCK_SIZE, 0);
63f08c3bdfSopenharmony_ci	if (ret < 0)
64f08c3bdfSopenharmony_ci		tst_brk(TBROK | TERRNO, "splice(fd_in, pipe) failed");
65f08c3bdfSopenharmony_ci
66f08c3bdfSopenharmony_ci	ret = splice(pipes[0], NULL, fd_out, NULL, TEST_BLOCK_SIZE, 0);
67f08c3bdfSopenharmony_ci	if (ret < 0)
68f08c3bdfSopenharmony_ci		tst_brk(TBROK | TERRNO, "splice(pipe, fd_out) failed");
69f08c3bdfSopenharmony_ci
70f08c3bdfSopenharmony_ci	SAFE_CLOSE(fd_in);
71f08c3bdfSopenharmony_ci	SAFE_CLOSE(fd_out);
72f08c3bdfSopenharmony_ci	SAFE_CLOSE(pipes[0]);
73f08c3bdfSopenharmony_ci	SAFE_CLOSE(pipes[1]);
74f08c3bdfSopenharmony_ci
75f08c3bdfSopenharmony_ci	check_file();
76f08c3bdfSopenharmony_ci}
77f08c3bdfSopenharmony_ci
78f08c3bdfSopenharmony_cistatic void setup(void)
79f08c3bdfSopenharmony_ci{
80f08c3bdfSopenharmony_ci	int i;
81f08c3bdfSopenharmony_ci
82f08c3bdfSopenharmony_ci	for (i = 0; i < TEST_BLOCK_SIZE; i++)
83f08c3bdfSopenharmony_ci		buffer[i] = i & 0xff;
84f08c3bdfSopenharmony_ci
85f08c3bdfSopenharmony_ci	fd_in = SAFE_OPEN(TESTFILE1, O_WRONLY | O_CREAT | O_TRUNC, 0777);
86f08c3bdfSopenharmony_ci	SAFE_WRITE(SAFE_WRITE_ALL, fd_in, buffer, TEST_BLOCK_SIZE);
87f08c3bdfSopenharmony_ci	SAFE_CLOSE(fd_in);
88f08c3bdfSopenharmony_ci}
89f08c3bdfSopenharmony_ci
90f08c3bdfSopenharmony_cistatic void cleanup(void)
91f08c3bdfSopenharmony_ci{
92f08c3bdfSopenharmony_ci	if (fd_in > 0)
93f08c3bdfSopenharmony_ci		SAFE_CLOSE(fd_in);
94f08c3bdfSopenharmony_ci
95f08c3bdfSopenharmony_ci	if (fd_out > 0)
96f08c3bdfSopenharmony_ci		SAFE_CLOSE(fd_out);
97f08c3bdfSopenharmony_ci}
98f08c3bdfSopenharmony_ci
99f08c3bdfSopenharmony_cistatic struct tst_test test = {
100f08c3bdfSopenharmony_ci	.setup = setup,
101f08c3bdfSopenharmony_ci	.cleanup = cleanup,
102f08c3bdfSopenharmony_ci	.test_all = splice_test,
103f08c3bdfSopenharmony_ci	.needs_tmpdir = 1,
104f08c3bdfSopenharmony_ci};
105