blob: 2c4f429b16f6f5da94b0aaad4a11dc80b7a8127a [file] [log] [blame]
vapierc033f492006-08-21 07:44:43 +00001/*
Cyril Hrubis3cbe5412014-06-03 14:00:39 +02002 * Copyright (c) International Business Machines Corp., 2006
3 * Author Yi Yang <yyangcdl@cn.ibm.com>
vapierc033f492006-08-21 07:44:43 +00004 *
Cyril Hrubis3cbe5412014-06-03 14:00:39 +02005 * This program is free software; you can redistribute it and/or modify
6 * it under the terms of the GNU General Public License as published by
7 * the Free Software Foundation; either version 2 of the License, or
8 * (at your option) any later version.
vapierc033f492006-08-21 07:44:43 +00009 *
Cyril Hrubis3cbe5412014-06-03 14:00:39 +020010 * This program is distributed in the hope that it will be useful,
11 * but WITHOUT ANY WARRANTY; without even the implied warranty of
12 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See
13 * the GNU General Public License for more details.
vapierc033f492006-08-21 07:44:43 +000014 *
Cyril Hrubis3cbe5412014-06-03 14:00:39 +020015 * You should have received a copy of the GNU General Public License
16 * along with this program; if not, write to the Free Software Foundation,
17 * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
18 */
19/*
vapierc033f492006-08-21 07:44:43 +000020 * DESCRIPTION
21 * This test case will verify basic function of splice
22 * added by kernel 2.6.17 or up.
23 *
vapierc033f492006-08-21 07:44:43 +000024 */
25
Xing Gucf900502014-05-30 16:05:25 +080026#define _GNU_SOURCE
27
vapierc033f492006-08-21 07:44:43 +000028#include <errno.h>
29#include <string.h>
30#include <signal.h>
31#include <sys/types.h>
32#include <fcntl.h>
33#include <sys/syscall.h>
Cyril Hrubis3cbe5412014-06-03 14:00:39 +020034
vapierc033f492006-08-21 07:44:43 +000035#include "test.h"
Cyril Hrubis3cbe5412014-06-03 14:00:39 +020036#include "safe_macros.h"
Cyril Hrubis0f0e3482014-02-27 16:08:04 +010037#include "tst_fs_type.h"
Cyril Hrubis6bd56e62014-06-03 11:09:35 +020038#include "lapi/splice.h"
vapierc033f492006-08-21 07:44:43 +000039
Cyril Hrubis3cbe5412014-06-03 14:00:39 +020040#define TEST_BLOCK_SIZE 1024
vapierc033f492006-08-21 07:44:43 +000041
Cyril Hrubis3cbe5412014-06-03 14:00:39 +020042#define TESTFILE1 "splice_testfile_1"
43#define TESTFILE2 "splice_testfile_2"
44
45static void splice_test(void);
46static void setup(void);
47static void cleanup(void);
48static char buffer[TEST_BLOCK_SIZE];
49static int fd_in, fd_out;
vapierc033f492006-08-21 07:44:43 +000050
Cyril Hrubisfdce7d52013-04-04 18:35:48 +020051char *TCID = "splice01";
52int TST_TOTAL = 1;
vapierc033f492006-08-21 07:44:43 +000053
vapierc033f492006-08-21 07:44:43 +000054int main(int ac, char **av)
55{
Cyril Hrubis89af32a2012-10-24 16:39:11 +020056 int lc;
Cyril Hrubis0b9589f2014-05-27 17:40:33 +020057 const char *msg;
mreed10380d3e62006-09-06 15:38:25 +000058
Garrett Cooper45e285d2010-11-22 12:19:25 -080059 if ((msg = parse_opts(ac, av, NULL, NULL)))
Garrett Cooper60fa8012010-11-22 13:50:58 -080060 tst_brkm(TBROK, NULL, "OPTION PARSING ERROR - %s", msg);
vapierc033f492006-08-21 07:44:43 +000061
vapierc033f492006-08-21 07:44:43 +000062 setup();
63
Cyril Hrubis3cbe5412014-06-03 14:00:39 +020064 for (lc = 0; TEST_LOOPING(lc); lc++)
65 splice_test();
subrata_modak5387ba02008-05-05 08:49:34 +000066
vapierc033f492006-08-21 07:44:43 +000067 cleanup();
Cyril Hrubis3cbe5412014-06-03 14:00:39 +020068 tst_exit();
Garrett Cooper2c282152010-12-16 00:55:50 -080069}
vapierc033f492006-08-21 07:44:43 +000070
Cyril Hrubis3cbe5412014-06-03 14:00:39 +020071static void check_file(void)
vapierc033f492006-08-21 07:44:43 +000072{
Cyril Hrubis3cbe5412014-06-03 14:00:39 +020073 int i;
74 char splicebuffer[TEST_BLOCK_SIZE];
75
76 fd_out = SAFE_OPEN(cleanup, TESTFILE2, O_RDONLY);
77 SAFE_READ(cleanup, 1, fd_out, splicebuffer, TEST_BLOCK_SIZE);
78
79 for (i = 0; i < TEST_BLOCK_SIZE; i++) {
80 if (buffer[i] != splicebuffer[i])
81 break;
82 }
83
84 if (i < TEST_BLOCK_SIZE)
85 tst_resm(TFAIL, "Wrong data read from the buffer at %i", i);
86 else
87 tst_resm(TPASS, "Written data has been read back correctly");
88
89 close(fd_out);
90 fd_out = 0;
91}
92
93static void splice_test(void)
94{
vapierc033f492006-08-21 07:44:43 +000095 int pipes[2];
96 int ret;
vapierc033f492006-08-21 07:44:43 +000097
Cyril Hrubis3cbe5412014-06-03 14:00:39 +020098 fd_in = SAFE_OPEN(cleanup, TESTFILE1, O_RDONLY);
99 SAFE_PIPE(cleanup, pipes);
100 fd_out = SAFE_OPEN(cleanup, TESTFILE2, O_WRONLY | O_CREAT | O_TRUNC, 0666);
subrata_modak6a8f17a2007-11-14 12:55:07 +0000101
Cyril Hrubis3cbe5412014-06-03 14:00:39 +0200102 ret = splice(fd_in, NULL, pipes[1], NULL, TEST_BLOCK_SIZE, 0);
103 if (ret < 0)
104 tst_brkm(TBROK | TERRNO, cleanup, "splice(fd_in, pipe) failed");
vapierc033f492006-08-21 07:44:43 +0000105
Cyril Hrubis3cbe5412014-06-03 14:00:39 +0200106 ret = splice(pipes[0], NULL, fd_out, NULL, TEST_BLOCK_SIZE, 0);
107 if (ret < 0)
108 tst_brkm(TBROK | TERRNO, cleanup, "splice(pipe, fd_out) failed");
vapierc033f492006-08-21 07:44:43 +0000109
110 close(fd_in);
111 close(fd_out);
112 close(pipes[0]);
113 close(pipes[1]);
114
Cyril Hrubis3cbe5412014-06-03 14:00:39 +0200115 fd_out = 0;
116 fd_in = 0;
117
118 check_file();
vapierc033f492006-08-21 07:44:43 +0000119}
120
Cyril Hrubis3cbe5412014-06-03 14:00:39 +0200121static void setup(void)
vapierc033f492006-08-21 07:44:43 +0000122{
Cyril Hrubis3cbe5412014-06-03 14:00:39 +0200123 int i;
124
125 if ((tst_kvercmp(2, 6, 17)) < 0) {
126 tst_brkm(TCONF, NULL,
127 "The splice is supported 2.6.17 and newer");
128 }
vapierc033f492006-08-21 07:44:43 +0000129
vapierc033f492006-08-21 07:44:43 +0000130 tst_sig(NOFORK, DEF_HANDLER, cleanup);
131
vapierc033f492006-08-21 07:44:43 +0000132 TEST_PAUSE;
Cyril Hrubis3cbe5412014-06-03 14:00:39 +0200133
134 tst_tmpdir();
135
136 if (tst_fs_type(cleanup, ".") == TST_NFS_MAGIC) {
Xiong Zhoud623e2c2014-09-25 03:24:19 -0400137 if (tst_kvercmp(2, 6, 32) < 0)
138 tst_brkm(TCONF, cleanup, "Cannot do splice on a file"
139 " on NFS filesystem before 2.6.32");
Cyril Hrubis3cbe5412014-06-03 14:00:39 +0200140 }
141
142 for (i = 0; i < TEST_BLOCK_SIZE; i++)
143 buffer[i] = i & 0xff;
144
145 fd_in = SAFE_OPEN(cleanup, TESTFILE1, O_WRONLY | O_CREAT | O_TRUNC, 0777);
146 SAFE_WRITE(cleanup, 1, fd_in, buffer, TEST_BLOCK_SIZE);
147 SAFE_CLOSE(cleanup, fd_in);
148 fd_in = 0;
Garrett Cooper2c282152010-12-16 00:55:50 -0800149}
vapierc033f492006-08-21 07:44:43 +0000150
Cyril Hrubis3cbe5412014-06-03 14:00:39 +0200151static void cleanup(void)
vapierc033f492006-08-21 07:44:43 +0000152{
Cyril Hrubis3cbe5412014-06-03 14:00:39 +0200153 if (fd_in > 0 && close(fd_in))
154 tst_resm(TWARN, "Failed to close fd_in");
subrata_modak6a8f17a2007-11-14 12:55:07 +0000155
Cyril Hrubis3cbe5412014-06-03 14:00:39 +0200156 if (fd_out > 0 && close(fd_out))
157 tst_resm(TWARN, "Failed to close fd_out");
158
159 tst_rmdir();
Chris Dearmanec6edca2012-10-17 19:54:01 -0700160}