Home | History | Annotate | Download | only in vmsplice
      1 /*
      2  * Copyright (c) 2014 Fujitsu Ltd.
      3  * Author: Xing Gu <gux.fnst (at) cn.fujitsu.com>
      4  *
      5  * This program is free software; you can redistribute it and/or modify it
      6  * under the terms of version 2 of the GNU General Public License as
      7  * published by the Free Software Foundation.
      8  *
      9  * This program is distributed in the hope that it would be useful, but
     10  * WITHOUT ANY WARRANTY; without even the implied warranty of
     11  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
     12  *
     13  * You should have received a copy of the GNU General Public License along
     14  * with this program; if not, write the Free Software Foundation, Inc.,
     15  * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
     16  */
     17 /*
     18  * Description:
     19  *   Verify that,
     20  *   1) vmsplice() returns -1 and sets errno to EBADF if fd
     21  *      is not valid.
     22  *   2) vmsplice() returns -1 and sets errno to EBADF if fd
     23  *      doesn't refer to a pipe.
     24  *   3) vmsplice() returns -1 and sets errno to EINVAL if
     25  *      nr_segs is greater than IOV_MAX.
     26  */
     27 
     28 #define _GNU_SOURCE
     29 
     30 #include <sys/types.h>
     31 #include <sys/stat.h>
     32 #include <fcntl.h>
     33 #include <unistd.h>
     34 #include <fcntl.h>
     35 #include <sys/uio.h>
     36 
     37 #include "test.h"
     38 #include "safe_macros.h"
     39 #include "linux_syscall_numbers.h"
     40 #include "lapi/fcntl.h"
     41 #include "lapi/vmsplice.h"
     42 
     43 #include "limits_ltp.h"
     44 
     45 #define TESTFILE "testfile"
     46 
     47 #define TEST_BLOCK_SIZE 128
     48 
     49 static char buffer[TEST_BLOCK_SIZE];
     50 static int notvalidfd = -1;
     51 static int filefd;
     52 static int pipes[2];
     53 static struct iovec ivc;
     54 
     55 static struct test_case_t {
     56 	int *fd;
     57 	const struct iovec *iov;
     58 	unsigned long nr_segs;
     59 	int exp_errno;
     60 } test_cases[] = {
     61 	{ &notvalidfd, &ivc, 1, EBADF },
     62 	{ &filefd, &ivc, 1, EBADF },
     63 	{ &pipes[1], &ivc, IOV_MAX + 1, EINVAL },
     64 };
     65 
     66 static void setup(void);
     67 static void cleanup(void);
     68 static void vmsplice_verify(const struct test_case_t *);
     69 
     70 char *TCID = "vmsplice02";
     71 int TST_TOTAL = ARRAY_SIZE(test_cases);
     72 
     73 int main(int ac, char **av)
     74 {
     75 	int i, lc;
     76 
     77 	tst_parse_opts(ac, av, NULL, NULL);
     78 
     79 	setup();
     80 
     81 	for (lc = 0; TEST_LOOPING(lc); lc++) {
     82 		tst_count = 0;
     83 
     84 		for (i = 0; i < TST_TOTAL; i++)
     85 			vmsplice_verify(&test_cases[i]);
     86 	}
     87 
     88 	cleanup();
     89 	tst_exit();
     90 }
     91 
     92 static void setup(void)
     93 {
     94 	if ((tst_kvercmp(2, 6, 17)) < 0) {
     95 		tst_brkm(TCONF, cleanup, "This test can only run on "
     96 			"kernels that are 2.6.17 or higher");
     97 	}
     98 
     99 	tst_sig(NOFORK, DEF_HANDLER, cleanup);
    100 
    101 	TEST_PAUSE;
    102 
    103 	tst_tmpdir();
    104 
    105 	if (tst_fs_type(cleanup, ".") == TST_NFS_MAGIC) {
    106 		tst_brkm(TCONF, cleanup, "Cannot do splice() "
    107 			"on a file located on an NFS filesystem");
    108 	}
    109 
    110 	filefd = SAFE_OPEN(cleanup, TESTFILE,
    111 				O_WRONLY | O_CREAT, 0644);
    112 
    113 	SAFE_PIPE(cleanup, pipes);
    114 
    115 	ivc.iov_base = buffer;
    116 	ivc.iov_len = TEST_BLOCK_SIZE;
    117 }
    118 
    119 static void vmsplice_verify(const struct test_case_t *tc)
    120 {
    121 	TEST(vmsplice(*(tc->fd), tc->iov, tc->nr_segs, 0));
    122 
    123 	if (TEST_RETURN != -1) {
    124 		tst_resm(TFAIL, "vmsplice() returned %ld, "
    125 			"expected -1, errno:%d", TEST_RETURN,
    126 			tc->exp_errno);
    127 		return;
    128 	}
    129 
    130 	if (TEST_ERRNO == tc->exp_errno) {
    131 		tst_resm(TPASS | TTERRNO, "vmsplice() failed as expected");
    132 	} else {
    133 		tst_resm(TFAIL | TTERRNO,
    134 			"vmsplice() failed unexpectedly; expected: %d - %s",
    135 			tc->exp_errno, strerror(tc->exp_errno));
    136 	}
    137 }
    138 
    139 static void cleanup(void)
    140 {
    141 	if (filefd && close(filefd) < 0)
    142 		tst_resm(TWARN | TERRNO, "close filefd failed");
    143 
    144 	if (pipes[0] && close(pipes[0]) < 0)
    145 		tst_resm(TWARN | TERRNO, "close pipes[0] failed");
    146 
    147 	if (pipes[1] && close(pipes[1]) < 0)
    148 		tst_resm(TWARN | TERRNO, "close pipes[1] failed");
    149 
    150 	tst_rmdir();
    151 }
    152