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 #include <limits.h> 37 38 #include "tst_test.h" 39 #include "lapi/syscalls.h" 40 #include "lapi/fcntl.h" 41 #include "lapi/vmsplice.h" 42 43 #define TESTFILE "testfile" 44 45 #define TEST_BLOCK_SIZE 128 46 47 static char buffer[TEST_BLOCK_SIZE]; 48 static int notvalidfd = -1; 49 static int filefd; 50 static int pipes[2]; 51 static struct iovec ivc; 52 53 static struct tcase { 54 int *fd; 55 const struct iovec *iov; 56 unsigned long nr_segs; 57 int exp_errno; 58 } tcases[] = { 59 { ¬validfd, &ivc, 1, EBADF }, 60 { &filefd, &ivc, 1, EBADF }, 61 { &pipes[1], &ivc, IOV_MAX + 1, EINVAL }, 62 }; 63 64 static void setup(void) 65 { 66 if (tst_fs_type(".") == TST_NFS_MAGIC) { 67 tst_brk(TCONF, "Cannot do splice() " 68 "on a file located on an NFS filesystem"); 69 } 70 71 filefd = SAFE_OPEN(TESTFILE, O_WRONLY | O_CREAT, 0644); 72 73 SAFE_PIPE(pipes); 74 75 ivc.iov_base = buffer; 76 ivc.iov_len = TEST_BLOCK_SIZE; 77 } 78 79 static void vmsplice_verify(unsigned int n) 80 { 81 struct tcase *tc = &tcases[n]; 82 83 TEST(vmsplice(*(tc->fd), tc->iov, tc->nr_segs, 0)); 84 85 if (TST_RET != -1) { 86 tst_res(TFAIL, "vmsplice() returned %ld, " 87 "expected -1, errno:%d", TST_RET, 88 tc->exp_errno); 89 return; 90 } 91 92 if (TST_ERR != tc->exp_errno) { 93 tst_res(TFAIL | TTERRNO, 94 "vmsplice() failed unexpectedly; expected: %d - %s", 95 tc->exp_errno, tst_strerrno(tc->exp_errno)); 96 return; 97 } 98 99 tst_res(TPASS | TTERRNO, "vmsplice() failed as expected"); 100 } 101 102 static void cleanup(void) 103 { 104 if (filefd > 0) 105 SAFE_CLOSE(filefd); 106 107 if (pipes[0] > 0) 108 SAFE_CLOSE(pipes[0]); 109 110 if (pipes[1] > 0) 111 SAFE_CLOSE(pipes[1]); 112 } 113 114 static struct tst_test test = { 115 .setup = setup, 116 .cleanup = cleanup, 117 .test = vmsplice_verify, 118 .tcnt = ARRAY_SIZE(tcases), 119 .needs_tmpdir = 1, 120 .min_kver = "2.6.17", 121 }; 122